dsh-composer-plus 1.17.0 → 1.18.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.de.md +18 -2
- package/README.es.md +18 -2
- package/README.fr.md +18 -2
- package/README.hi.md +18 -2
- package/README.id.md +18 -2
- package/README.ja.md +18 -2
- package/README.ko.md +18 -2
- package/README.md +18 -2
- package/README.pt-BR.md +18 -2
- package/README.ru.md +18 -2
- package/README.tr.md +18 -2
- package/README.vi.md +18 -2
- package/README.zh.md +18 -2
- package/assets/features/blockedCommands.webp +0 -0
- package/assets/features/plannedSteps.webp +0 -0
- package/assets/features/taskBoard.webp +0 -0
- package/client.js +879 -41
- package/index.js +1036 -1
- package/package.json +2 -2
- package/tether/gateway/server.mjs +1 -0
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.
|
|
32
|
+
> dsh의 pnpm은 게시된 지 24시간이 지나지 않은 버전을 건너뜁니다. 릴리스 직후에는 버전을 붙여서 설치하세요: `dsh-composer-plus@1.18.0`.
|
|
33
33
|
|
|
34
34
|
## 기능
|
|
35
35
|
|
|
@@ -68,7 +68,10 @@ dsh plugin --profile web add dsh-composer-plus
|
|
|
68
68
|
| **목표 확인** | <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> |
|
|
69
69
|
| **새 채팅에서 계속** | <a id="feature-handoffchat"></a>사이드바에서 채팅을 마우스 오른쪽 버튼으로 클릭(또는 채팅의 **…** 메뉴 열기) → **새 채팅에서 계속…**. 채팅 자체의 모델을 한 번 호출해, 채팅에 보이는 내용으로 인계 메모를 씁니다. 항목은 작업, 산출물, 완료한 일, 결정 사항, 미해결 문제, 다음 작업입니다(도구 호출과 그 결과가 증거이며, 되돌린 단계는 빠집니다). 메모는 대화 상자에 열립니다. 읽고 편집하세요. **다시 쓰기**는 새 메모를 씁니다. **새 채팅 시작**(또는 `Cmd/Ctrl+Enter`)은 같은 프로젝트에서 새 채팅을 열고, 메모와 이전 채팅 링크를 첫 메시지로 보냅니다. 이전 채팅은 그대로 남습니다. 긴 채팅이 가득 차거나 느려졌을 때, 또는 다음 날 이어서 할 때 쓰세요. 프로젝트에는 아무것도 쓰지 않습니다. | <a href="assets/features/handoffChat.webp"><img src="assets/features/handoffChat.webp" width="160" alt="스크린샷: 새 채팅에서 계속"></a> |
|
|
70
70
|
| **컨텍스트 구성** | <a id="feature-contextbreakdown"></a>오른쪽 사이드바 → `+` → **컨텍스트**. 페이지는 열린 채팅의 모델 컨텍스트를 지금 무엇이 채우고 있는지, 그리고 컨텍스트 창을 얼마나 쓰는지 보여 줍니다. 시스템 프롬프트, 프로젝트 지침(AGENTS.md), 스킬, 내 메시지, 에이전트 답변과 도구 호출, 도구 결과(도구별), MCP 결과(서버별), 도구 정의, 압축 요약, 기타 컨텍스트 메모를 각각의 토큰 수와 비율과 함께 보여 줍니다. 항목을 클릭하면 그 도구나 서버를 볼 수 있습니다. 채팅 로그만 읽으며(`/compact`와 되돌리기 이후), 모델을 호출하지 않습니다. 각 턴이 끝난 뒤와 **새로 고침**을 누르면 다시 읽습니다. 채팅이 느리거나 가득 찬 이유를 볼 때 쓰세요. 예를 들어 큰 MCP 도구 결과나 많은 도구 정의가 원인일 수 있습니다. | <a href="assets/features/contextBreakdown.webp"><img src="assets/features/contextBreakdown.webp" width="160" alt="스크린샷: 컨텍스트 구성"></a> |
|
|
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> |
|
|
71
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
|
+
| **차단된 명령** | <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`를 누르세요. 카드를 다른 열이나 두 카드 사이로 끌어다 놓을 수 있습니다. 카드를 클릭하면 **상태**, **태그**, **수동**(에이전트가 건너뜀), 설명(Markdown), 댓글을 보고 바꿀 수 있습니다. `/`는 모든 프로젝트를 검색하고, `h`는 수동 작업만 보여 주며, 내보내기 버튼은 보드를 Markdown이나 JSON으로 저장합니다. 에이전트는 보드 도구를 받습니다. 채팅에서 "보드에서 다음 작업을 가져와"라고 하면 에이전트가 **할 일**의 맨 위 카드를 **진행 중**으로 옮기고, 한 일을 댓글로 남긴 뒤 **검토**로 옮깁니다. **완료**로 옮기는 것은 사용자입니다. 열린 작업이 있는 프로젝트에서는 각 채팅이 이 규칙을 자동으로 받습니다. 설정 → Composer Plus → **작업 보드**에 **백로그** 열 스위치가 있습니다. 이 열의 카드는 에이전트가 사용자에게 맡깁니다. | <a href="assets/features/taskBoard.webp"><img src="assets/features/taskBoard.webp" width="160" alt="스크린샷: 작업 보드"></a> |
|
|
72
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> |
|
|
73
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> |
|
|
74
77
|
| **프로젝트 상태** | <a id="feature-projectstatus"></a>사이드바의 프로젝트 행에 그 채팅과 같은 실행 중 / 대기 중 / 완료 표시가 나타납니다. 그래서 접힌 프로젝트도 안의 채팅이 작업 중인지, 사용자의 조치가 필요한지 알려 줍니다. 사용자의 조치를 기다리는 채팅이 먼저 표시되고, 그다음 아직 열지 않은 완료된 채팅(초록색 점, 다른 채팅이 아직 실행 중일 때도 표시), 마지막으로 실행 중 표시가 나타납니다. 포인터를 올리면 자세한 내용이 보입니다. **작업 공간 트리**에서는 상위 폴더의 행에도 그 안에 있는 각 프로젝트(예: `.worktrees/` 안의 각 브랜치 폴더)의 채팅 상태가 표시되며, 폴더가 접혀 있을 때도 마찬가지입니다. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="스크린샷: 프로젝트 상태"></a> |
|
|
@@ -166,7 +169,9 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
|
|
|
166
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개)에 보관됩니다.
|
|
167
170
|
- **새 채팅에서 계속:** 클릭하기 전에는 아무것도 실행되지 않습니다. 클릭하면 Host 쪽은 채팅(목표 확인이 읽는 방식과 같음: 추론과 되돌린 단계 제외)을 채팅 자체의 모델에 보내고 인계 메모를 보여 줍니다. 새 채팅을 만드는 것은 **새 채팅 시작**뿐입니다. 프로젝트에는 아무것도 쓰지 않습니다.
|
|
168
171
|
- **컨텍스트 구성:** Host에서 채팅 로그만 읽습니다. 모델 호출도 프로젝트 파일도 없습니다.
|
|
172
|
+
- **작업 보드:** 보드(작업의 제목, 설명, 태그, 댓글, 프로젝트 폴더 경로와 그 짧은 ID)는 `$DSH_HOME/storages/dsh-composer-plus/board.json`(소유자 전용 파일)에 있습니다. 스위치는 그 옆의 `board-switch.json`에 있습니다. 아무것도 컴퓨터 밖으로 나가지 않으며, 프로젝트 폴더에는 아무것도 쓰지 않습니다. 보드 도구는 사용자가 보드에 쓴 내용을 에이전트에게 주므로, 에이전트가 작업을 읽으면 그 텍스트가 채팅의 모델에 전달됩니다. 손상된 보드 파일은 `board.json.broken-<time>`으로 보관되고, 보드는 빈 상태로 시작합니다.
|
|
169
173
|
- **보호된 파일:** 목록과 스위치는 `$DSH_HOME/storages/dsh-composer-plus/protected-files.json`(소유자 전용 파일)에 있습니다. 확인은 각 파일 도구 호출의 경로(와 실제 경로)만 읽으며, 파일 자체는 읽지 않습니다.
|
|
174
|
+
- **차단된 명령:** 규칙과 스위치는 `$DSH_HOME/storages/dsh-composer-plus/blocked-commands.json`(소유자 전용 파일)에 있습니다. 확인은 각 `bash`와 `pwsh` 호출의 명령 텍스트만 읽으며, 아무것도 실행하거나 보내지 않습니다.
|
|
170
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도 같은 경로로 메모를 읽고 바꿉니다.
|
|
171
176
|
- **백업:** 아무것도 컴퓨터 밖으로 나가지 않습니다. 아카이브는 `~/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 프로세스를 나타냅니다(복구 콘솔은 이 파일들을 읽고 복원을 거부합니다).
|
|
172
177
|
- **복구 콘솔:** 터미널 메뉴이며, 네트워크 포트를 열지 않습니다. 복원은 dsh 홈 옆의 새 폴더에만 씁니다(파일은 `O_EXCL | O_NOFOLLOW`로 쓰고, 심볼릭 링크는 마지막에 만들며 따라가지 않음). 안전하지 않은 이름(`..`, 절대 경로), 장치나 FIFO, 둘 이상의 최상위 폴더, 링크 아래의 항목이 있는 아카이브는 거부합니다.
|
|
@@ -189,7 +194,7 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
|
|
|
189
194
|
- **채팅 행에 브랜치 배지가 없음:** 이 버전을 설치한 뒤 그 채팅에 턴이 없었거나, 폴더가 git 저장소가 아니거나, **채팅 행의 Git 브랜치**가 꺼져 있습니다. 업데이트한 뒤에는 dsh를 다시 시작하세요(브랜치는 Host 쪽이 기록합니다).
|
|
190
195
|
- **목표 확인에 테스트가 종료 코드 127 또는 "not found"로 끝났다고 표시됨:** Finder나 Dock에서 시작한 dsh는 터미널보다 PATH가 짧을 수 있어서 `npm`, `pnpm`, `cargo`를 찾지 못합니다. 터미널에서 dsh를 시작하거나, **목표 확인** → **편집**에서 전체 경로를 쓴 테스트 명령을 직접 정하세요. **지금 실행**을 누르면 결과가 바로 표시됩니다.
|
|
191
196
|
- **목표가 닫히지 않고 에이전트가 계속 작업함:** **목표 확인**이 실패한 테스트나 남은 작업을 찾았습니다. 목표 아래의 행에 이유가 표시됩니다(자세한 내용은 결과에 포인터를 올려 보세요). 원인이나 테스트 명령을 고치거나, `/goal` 또는 목표 바로 목표를 직접 완료하세요(이 완료는 확인하지 않습니다).
|
|
192
|
-
- **릴리스 직후 설치 실패:** 버전을 붙여서 설치하세요(`dsh-composer-plus@1.
|
|
197
|
+
- **릴리스 직후 설치 실패:** 버전을 붙여서 설치하세요(`dsh-composer-plus@1.18.0`). 위의 설치 안내를 참고하세요.
|
|
193
198
|
- **지금 백업에서 "다른 백업 작업이 실행 중입니다"라고 표시됨:** 다른 dsh 창이나 복구 콘솔에서 작업이 실행 중입니다(둘은 백업 폴더의 잠금 파일 `.composer-plus.lock`을 함께 씁니다). 작업이 끝날 때까지 기다리세요. 실행 중인 작업이 없으면, 다음에 클릭할 때 종료된 프로세스의 잠금을 넘겨받습니다.
|
|
194
199
|
- **복구 콘솔에 "dsh is running"이라고 표시됨:** 먼저 dsh를 종료하세요. dsh가 정말 닫혀 있다면, 메시지에 나온 파일은 비정상 종료로 남은 것입니다. 그 파일을 삭제하고 다시 시도하세요.
|
|
195
200
|
- **복원 후 dsh가 시작되지 않거나 플러그인이 없음:** 프로필의 플러그인 패키지를 다시 설치해야 합니다. 복구 콘솔이 복원 후에 이를 제안합니다. 또는 콘솔이 나열하는 `$DSH_HOME/profiles/` 아래의 각 폴더에서 `pnpm install`을 실행하세요. vault에 없던 비밀 값(다른 컴퓨터)은 다시 입력해야 합니다. 콘솔이 그 목록을 보여 줍니다.
|
|
@@ -239,8 +244,11 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
|
|
|
239
244
|
- **프롬프트 개선**은 짧은 프로젝트 요약, 변경된 경로, 이름이 입력한 단어와 일치하는 경로만 보며, 코드 자체는 보지 않습니다. 그래서 맞는 파일을 놓칠 수 있고, 전달받은 경로만 언급합니다. 보내기 전에 새 텍스트를 읽어 보세요. `/goal <목표>` 외의 슬래시 명령, `/goal` 제어어(`clear`, `pause`, `resume`), 파일 칩이나 기호 칩이 있는 메시지에서는 실행되지 않습니다(새 텍스트는 일반 텍스트라서 칩이 사라지기 때문입니다). `/goal` 목표에서는 초안과 컨텍스트만으로 조건을 씁니다. 너무 엄격한 조건은 목표 라운드를 더 쓰게 할 수 있으므로, 보내기 전에 읽어 보세요. 메시지는 최대 8,000자까지 가능합니다. 이미지는 그대로 첨부되어 있고, 텍스트만 바뀝니다. 클릭할 때마다 모델 호출이 한 번 일어나며, 성능이 높은 모델은 1분쯤 걸릴 수 있습니다(`Esc`로 취소).
|
|
240
245
|
- **목표 확인**은 에이전트가 자동 목표 라운드에서 한 완료만 확인합니다. 채팅에서 사용자가 요청한 완료, `/goal`, 목표 바는 확인하지 않습니다. 에이전트는 테스트나 테스트 명령의 파일을 스스로 바꿀 수 있습니다. 검증 모델은 채팅을 읽으므로 이를 알아챌 수 있지만, 양쪽 방향으로 틀릴 수 있습니다(잘못된 "완료되지 않음"은 라운드를 한 번 더 쓰고, 잘못된 "완료"는 목표를 닫습니다). 검증 모델은 채팅과 `git status`를 보며, 코드 자체는 보지 않습니다. 테스트 실행은 파일을 바꿀 수 있는 에이전트의 최신 단계가 같은 폴더에서 정확히 같은 명령을 성공적으로 실행한 에이전트 자신의 `bash` 실행일 때만 재사용합니다. 파이프(`| tail`)나 `&&`가 있는 명령은 재사용하지 않습니다. 예산은 턴이 끝날 때 측정하므로, 한 턴이 예산을 넘을 수 있습니다. 토큰 예산은 그 채팅의 하위 에이전트 채팅의 호출도 셉니다(턴이 끝날 때마다 저장된 로그에서 읽으므로, 하위 에이전트가 많은 채팅은 확인이 조금 더 오래 걸립니다). 근거 표는 검증 모델이 채팅을 직접 읽은 결과입니다. 검증됨이라고 한 부분도 중요하다면 직접 확인하세요. 확인이 실행되는 동안 `update_goal`은 기다립니다(테스트는 최대 15분, 검증은 최대 3분). 포크한 채팅은 새 채팅 ID를 받으므로, 부모 채팅 자체의 테스트 명령과 제한 없이 시작합니다. 검증까지 간 완료마다 모델 호출이 한 번 일어납니다.
|
|
241
246
|
- **보호된 파일**은 가드레일이며 샌드박스가 아닙니다. dsh 자체의 파일 도구(`read`, `read_image`, 파일에 대한 `grep`, `write`, `edit`, `str_replace_editor`)만 다룹니다. 셸 명령(`cat .env`), 에이전트가 쓴 스크립트, 하위 에이전트의 셸, MCP 도구, `glob` 목록, 폴더 전체에 대한 `grep`은 여전히 보호된 파일에 접근할 수 있습니다. 실제로 제한하려면 dsh의 샌드박스 모드를 쓰거나 비밀 값을 프로젝트 폴더 밖에 두세요. 패턴은 `*`, `**`, `?`를 알지만 `{a,b}`나 `[ab]`는 모르며, 대소문자를 구분하지 않습니다.
|
|
247
|
+
- **차단된 명령**은 가드레일이며 샌드박스가 아닙니다. dsh의 `bash`와 `pwsh` 도구의 명령 텍스트만 읽습니다. 명령을 가리키는 변수나 별칭(`CMD=npm; $CMD publish`), 셸 함수, 에이전트가 쓴 스크립트 파일, 다른 프로그램(`python -c`, `node -e`, `make`), MCP 도구, 사용자 자신의 터미널은 여전히 그 명령을 실행할 수 있습니다. 규칙은 원하는 것보다 더 많이 일치할 수 있습니다. 명령의 어느 단어든 명령 이름이 될 수 있고(`echo npm publish`는 `npm publish`와 일치), 규칙의 단어 사이에 다른 단어가 와도 됩니다(`git push --force`는 `git push origin main --force`와도 일치). 너무 많이 일치하면 규칙을 더 길게 만드세요. **먼저 묻기** 규칙에는 물어볼 수 있는 채팅이 필요합니다. 승인 정책이 never인 채팅(예: 위임된 하위 에이전트)에서는 dsh가 카드를 표시할 수 없으므로 호출이 이유와 함께 거부됩니다. 승인 카드는 이유를 영어로 표시합니다. **이 채팅에서 허용**으로는 **먼저 묻기** 카드에 답할 수 없습니다.
|
|
242
248
|
- **새 채팅에서 계속**은 채팅(메시지, 도구 호출, 각 도구 결과의 끝부분. 최대 약 60,000자, 가장 최근 부분)을 채팅 자체의 모델에 보냅니다. 인계 메모는 결정이나 파일을 빠뜨릴 수 있으므로, 시작하기 전에 읽어 보세요. 새 채팅은 메모와 링크된 채팅만 압니다(dsh는 이전 채팅을 읽기 전용 컨텍스트로 첨부합니다). 새 채팅의 모델 컨텍스트는 작게 시작하고, 이전 채팅은 그대로 남습니다. 채팅마다 한 번에 메모 작성이나 시작 하나만 실행됩니다.
|
|
243
249
|
- **컨텍스트 구성**은 dsh 자체의 규칙(토큰당 약 4자)으로 추정값을 보여 줍니다. dsh의 컨텍스트 링과 같은 규칙이며, 모델 자체의 계산과 다를 수 있습니다. 도구 정의는 가장 최근 요청의 것입니다. 채팅 로그에 있는 그대로의 컨텍스트를 보여 주며, 지금 실행 중인 턴은 다음 단계 뒤에 나타납니다.
|
|
250
|
+
- **계획된 단계**는 모델이 실제로 계획할 때만 토큰을 절약합니다. 켜져 있는 동안에는 모델이 계획하지 않는 채팅에서도 모든 요청에 `plan_next_steps` 도구와 짧은 지침(약 500토큰)이 포함됩니다. 조건은 적힌 내용만 증명합니다(예: 빌드 종료 코드가 0이었음). 작업이 올바르다는 것은 증명하지 않습니다. `ok`는 dsh 자체의 결과 표시(`[exit code: N]`, 시간 초과, 샌드박스 거부)를 읽습니다. 0이 아닌 종료 코드 없이 실패한 명령은 통과로 처리됩니다. 단계는 한 번에 하나씩 실행되며, 동시에 준비된 두 단계는 모델에게 돌아갑니다. 단계의 메시지는 채팅 모델의 어시스턴트 메시지로 저장됩니다(dsh에는 플러그인이 쓴 메시지를 나타내는 표시가 없습니다). 그래서 그 텍스트에 Composer Plus가 실행했다고 적혀 있습니다. Tether에는 없습니다.
|
|
251
|
+
- **작업 보드**는 dsh의 프로젝트만 압니다. 프로젝트 밖의 채팅에서는 **모든 프로젝트**가 표시되고, 채팅별 브랜치 폴더(`<project>/.worktrees/<name>`)는 해당 프로젝트로 취급됩니다. 프로젝트 ID(`acme#12`)는 폴더 이름에서 오며, dsh에서 프로젝트 이름을 바꿔도 그대로입니다. "보드를 최신 상태로 유지" 규칙은 그 프로젝트에 열린 작업이 있을 때만 채팅에 들어갑니다. 한 번 받은 채팅은 규칙을 유지합니다. 에이전트에게는 **완료**, **백로그**, 수동 작업을 사용자에게 맡기라고 알리지만, 도구가 이를 거부하지는 않습니다. 에이전트가 그런 카드를 옮길 수도 있습니다. 기능이 켜져 있는 동안 보드 도구는 모든 채팅의 도구 목록에 들어갑니다(요청마다 약 1,000 토큰). 보드를 쓰지 않으면 끄세요. 페이지가 보이는 동안 2초마다 보드를 읽으므로, 에이전트의 변경은 그 시간 안에 표시됩니다. 에이전트가 같은 필드를 바꾸는 동안 사용자가 편집한 텍스트는 저장되지 않습니다. 패널에 새 텍스트와 이유가 표시됩니다. 이미지, 컴퓨터 간 git 동기화, 네트워크 공유는 없습니다(Kanzo에는 있습니다). 아이디어와 디자인은 emanuele-em의 [Kanzo](https://github.com/emanuele-em/kanzo)(AGPL-3.0)에서 왔습니다. Composer Plus는 그 코드를 쓰지 않습니다.
|
|
244
252
|
- **중지 후 보낸 메시지 먼저 실행**은 채팅을 중지한 뒤에만 동작합니다(또는 실패한 턴 뒤, 아직 대기열이 있는 채팅을 열 때). 턴이 실행되는 중에 보낸 메시지는 여전히 대기열 끝에서 기다립니다. 내가 대기열에 넣은 메시지만 앞지릅니다. 대기열에 목표 라운드나 질문 답변이 기다리고 있으면 dsh 자체 순서가 유지됩니다. 공개 API가 아닌 dsh의 일부(중지된 턴이 아직 끝나는 중인지)를 읽습니다. dsh 업데이트로 그 이름이 바뀌면, 메시지는 그 턴이 끝난 뒤에만 앞으로 옮겨집니다. 서브에이전트 채팅은 dsh 자체 순서를 유지합니다.
|
|
245
253
|
- **프로젝트 메모리**는 채팅의 첫 폴더(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 자체의 메모리를 읽거나 쓰지 않습니다.
|
|
246
254
|
- **백업**은 고정된 폴더 하나, `~/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 아카이브를 자기 보관 개수에 포함하며 그 아카이브를 삭제할 수 있습니다.
|
|
@@ -277,6 +285,8 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
|
|
|
277
285
|
|
|
278
286
|
**DS Bot의 메모리처럼 에이전트가 채팅이 바뀌어도 내 선호를 기억할 수 있나요?** 네, **프로젝트 메모리**(기본적으로 꺼짐)로 가능합니다. **설정 → Composer Plus**에서 켜세요. 턴이 끝날 때마다 오래 유지되는 선호와 결정이 채팅 프로젝트의 짧은 메모로 저장되고, 그 프로젝트의 새 채팅마다 이를 읽습니다. 에이전트에게 무언가를 기억하라고 하면 바로 저장합니다. 메모를 보거나 바꾸려면 같은 줄의 **메모리 열기**를 누르고 바꿀 내용을 적으세요.
|
|
279
287
|
|
|
288
|
+
**Kanzo처럼 에이전트와 하나의 작업 보드를 함께 쓸 수 있나요?** 네, **작업 보드**(기본적으로 켜짐)로 가능합니다. 왼쪽 사이드바에서 열고 **새 작업**으로 작업을 추가하세요. 채팅에서 에이전트에게 "보드에서 다음 작업을 가져와"라고 하면, 에이전트가 카드를 **진행 중**으로 옮기고, 한 일을 댓글로 남긴 뒤 **검토**로 옮깁니다. 직접 할 작업은 **수동**으로 표시하세요.
|
|
289
|
+
|
|
280
290
|
**dsh-backup처럼 dsh에서 채팅과 설정을 백업할 수 있나요?** 네. **설정 → Composer Plus → 백업 → 지금 백업**을 사용하세요. 같은 아카이브 형식으로 같은 폴더(`~/Desktop/dsh-backups`)에 쓰므로, dsh-backup의 아카이브도 표시되고 복원할 수 있으며, dsh-backup은 삭제해도 됩니다. 정해진 일정으로 백업하려면 **자동 백업**을 켜세요.
|
|
281
291
|
|
|
282
292
|
**dsh가 더 이상 시작되지 않습니다. 백업을 어떻게 복원하나요?** 백업 폴더(`~/Desktop/dsh-backups`)를 열고 `Composer Plus Rescue.command`를 더블클릭하세요(Linux: `composer-plus-rescue.sh`, Windows: `Composer Plus Rescue.cmd`). `3) Restore a backup`을 선택하고, 백업 하나를 고른 뒤 `RESTORE`를 입력하세요. dsh 없이도 작동합니다.
|
|
@@ -301,6 +311,8 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
|
|
|
301
311
|
|
|
302
312
|
**한 채팅이 바꾼 파일만 보려면 어떻게 하나요?** 오른쪽 사이드바 → **변경 사항** → **이 채팅**. 공백만 바뀐 변경을 숨기려면 **␣**를 클릭하세요.
|
|
303
313
|
|
|
314
|
+
**에이전트가 `npm publish`나 `git push --force`를 실행하지 못하게 하려면 어떻게 하나요?** **설정 → Composer Plus → 차단된 명령**에서 `npm publish`를 입력하고 **차단** 또는 **먼저 묻기**를 고른 뒤 **추가**를 클릭하세요. **차단**은 명령을 거부하고 에이전트가 사용자에게 묻습니다. **먼저 묻기**는 매번 승인 카드를 표시합니다. 보호된 파일은 에이전트의 파일 도구를, 차단된 명령은 셸 명령을 다룹니다.
|
|
315
|
+
|
|
304
316
|
**한 채팅에서 자동 검토가 같은 도구를 계속 묻지 않게 하려면 어떻게 하나요?** 승인 카드에서 **이 채팅에서 허용**을 클릭하세요. 이 허용은 그 채팅의 그 도구에만 적용되며, 기본값은 1시간입니다. 헤더 칩에서 취소할 수 있습니다. 시간은 **설정 → Composer Plus → 이 채팅에서 허용**에서 바꿉니다.
|
|
305
317
|
|
|
306
318
|
**iPhone을 잃어버렸습니다. 그 iPhone이 Mac에 접속하지 못하게 하려면 어떻게 하나요?** 사이드바 왼쪽 아래의 **모바일 연결**을 클릭하고, 그 iPhone 옆의 **Remove**를 클릭하세요. 그 iPhone의 키는 즉시 작동을 멈춥니다. 다시 연결하려면 Mac에서 승인하는 새 페어링이 필요합니다.
|
|
@@ -329,6 +341,8 @@ dsh `0.2.0-rc.2`(데스크톱과 웹)와 `0.2.1-rc.2`(웹)에서 테스트했습
|
|
|
329
341
|
|
|
330
342
|
**iPhone에서 사진을 보낼 수 있나요?** 네. Tether 채팅에서 메시지 입력란 옆의 **+** → Camera, Photos(최대 4장) 또는 Paste image를 탭하세요. 사진은 메시지의 첨부 파일로 Mac의 채팅에 전달되므로 모델이 볼 수 있습니다.
|
|
331
343
|
|
|
344
|
+
**dsh가 모델에 다시 묻지 않고 다음 명령을 실행할 수 있나요?** 네, **계획된 단계**(기본적으로 꺼짐)를 사용하세요. 설정 → Composer Plus에서 켜세요. 그러면 모델이 조건과 함께 다음 명령을 계획할 수 있고(예: “빌드가 통과하면 테스트 실행”), 결과가 조건을 충족하면 Composer Plus가 새 모델 호출 없이 그 단계를 실행합니다. 승인과 샌드박스는 그대로입니다.
|
|
345
|
+
|
|
332
346
|
**데스크톱 앱에서도 작동하나요?** 네. 설정 → 플러그인 → **플러그인 추가** → `dsh-composer-plus`. dsh 0.2.0-rc.2(데스크톱과 웹)와 0.2.1-rc.2(웹)에서 테스트했습니다.
|
|
333
347
|
|
|
334
348
|
## 개발
|
|
@@ -393,6 +407,8 @@ PLAYWRIGHT=/path/to/playwright node test/browser-continue-queue.mjs /path/to/dsh
|
|
|
393
407
|
SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-stop-send.mjs /path/to/dsh/lib/bin.js
|
|
394
408
|
# Edit queued message in place with images and files (slow fake model) + its thumbnail
|
|
395
409
|
SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-edit.mjs /path/to/dsh/lib/bin.js
|
|
410
|
+
# Task board: the page, the agent tools (fake model), drag and drop, search, the switch
|
|
411
|
+
SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-task-board.mjs /path/to/dsh/lib/bin.js
|
|
396
412
|
```
|
|
397
413
|
|
|
398
414
|
```sh
|
package/README.md
CHANGED
|
@@ -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.
|
|
30
|
+
> dsh's pnpm skips versions younger than 24 hours. Right after a release, add the version: `dsh-composer-plus@1.18.0`.
|
|
31
31
|
|
|
32
32
|
## Features
|
|
33
33
|
|
|
@@ -66,7 +66,10 @@ Then restart dsh. (The CLI can't install into the desktop profile; the app manag
|
|
|
66
66
|
| **Goal check** | <a id="feature-goalcheck"></a>Start a goal with `/goal`. When the agent marks the goal complete in an automatic round, the goal closes only after two checks. First, the project's test command runs in the chat's folder, under the chat's sandbox mode. The command is your own one or the one found in `package.json`, `Makefile`, `Cargo.toml`, `go.mod` or pytest. When the agent's own newest step was a passing run of that test, it does not run again. Then one independent model call, with no tools, reads the goal, this chat, `git status` and the test result. The model answers with an evidence table: each part of the goal is verified, incorrect or unresolved, with the evidence and the fix; the goal closes only when every part is verified. If a check fails, the goal stays active and the agent reads each open part with its evidence and fix, then the next round goes on. A row under the goal bar (**Goal check**) shows the test, the last result and how many parts were verified (hover it for the table). **Edit** sets your own test command and a time or token limit; over the limit the goal becomes blocked. The token limit also counts the chat's subagents. **Run now** runs the check without closing the goal. It has its own **Model** menu in Settings (default: **Same as the chat's model**). When you complete the goal yourself, nothing is checked. | <a href="assets/features/goalCheck.webp"><img src="assets/features/goalCheck.webp" width="160" alt="Screenshot: Goal check"></a> |
|
|
67
67
|
| **Continue in a new chat** | <a id="feature-handoffchat"></a>Right-click a chat in the sidebar (or open its **…** menu) → **Continue in a new chat…**. One call to the chat's own model writes a handoff note from the chat: Task, Outputs, Completed, Decisions, Open issues and Next action, from what the chat shows (tool calls and results are the evidence; steps that you rolled back are left out). The note opens in a dialog: read it and edit it. **Write again** writes a new note. **Start new chat** (or `Cmd/Ctrl+Enter`) opens a new chat in the same project with the note and a link to the old chat as its first message; the old chat stays as it is. Use it when a long chat is full or slow, or to continue tomorrow. Nothing is written to the project. | <a href="assets/features/handoffChat.webp"><img src="assets/features/handoffChat.webp" width="160" alt="Screenshot: Continue in a new chat"></a> |
|
|
68
68
|
| **Context breakdown** | <a id="feature-contextbreakdown"></a>Right sidebar → `+` → **Context**. The page shows what fills the open chat's model context now and how much of the context window it uses: the system prompt, project instructions (AGENTS.md), skills, your messages, agent replies and tool calls, tool results (by tool), MCP results (by server), tool definitions, the compact summary and other context notes, each with its tokens and its share. Click a part to see its tools or servers. It reads the chat log only, after `/compact` and rollbacks, and calls no model; it reads again after each turn and with **Refresh**. Use it to see why a chat is slow or full, for example a big MCP tool result or many tool definitions. | <a href="assets/features/contextBreakdown.webp"><img src="assets/features/contextBreakdown.webp" width="160" alt="Screenshot: Context breakdown"></a> |
|
|
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> |
|
|
69
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
|
+
| **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 projects for you and the agents: **Todo**, **Doing**, **Review** and **Done** (and **Backlog**, see below). Pick a project or **All projects** on the left. **New task** (or `n`) opens a new card: type its title and press `Enter`. Drag a card to another column or between two cards. Click a card to see and change its **Status**, **Tags**, **Human** (agents skip it), description (Markdown) and comments. `/` searches every project, `h` shows only human tasks, the export button saves the board as Markdown or JSON. Agents get board tools: ask a chat to "take the next task from the board" and it moves the top **Todo** card to **Doing**, comments on what it did and moves it to **Review**; you move it to **Done**. In a project with open tasks, each chat gets this rule by itself. Settings → Composer Plus → **Task board** has the **Backlog** column switch: agents leave its cards to you. | <a href="assets/features/taskBoard.webp"><img src="assets/features/taskBoard.webp" width="160" alt="Screenshot: Task board"></a> |
|
|
70
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> |
|
|
71
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> |
|
|
72
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> |
|
|
@@ -164,7 +167,9 @@ Tested on dsh `0.2.0-rc.2` (desktop and web) and `0.2.1-rc.2` (web). CI runs the
|
|
|
164
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).
|
|
165
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.
|
|
166
169
|
- **Context breakdown:** reads only the chat log on the Host; no model call, no project file.
|
|
170
|
+
- **Task board:** the board (titles, descriptions, tags and comments of your tasks, the project folder paths and their short ids) is in `$DSH_HOME/storages/dsh-composer-plus/board.json` (owner-only file); the switch is in `board-switch.json` next to it. Nothing leaves your machine and nothing is written to a project folder. The board tools give the agents what you wrote on the board, so the text of a task reaches the chat's model when an agent reads it. A broken board file is kept as `board.json.broken-<time>` and the board starts empty.
|
|
167
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
|
+
- **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.
|
|
168
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.
|
|
169
174
|
- **Backup:** nothing leaves your machine. Archives go to `~/Desktop/dsh-backups` (owner-only files). Secrets are not in an archive: credential files (`.credentials.yaml`, `.env`), key files (`.pem`, `.key`, `.p12`, `.pfx`) and the values of token, secret, password and API key settings in the yml files are masked; their real copies stay in `composer-plus-vault/<archive>/` in the same folder (owner-only), on this computer only. **For another computer** copies no vault: enter those secrets again there. Your chat logs, settings and the rest of the dsh home are in the archive as they are: keep the folder private, as `$DSH_HOME` itself. The backup reads files with `O_NOFOLLOW | O_NONBLOCK`; a symbolic link is stored as a link (never followed) and a FIFO or device is skipped. The automatic backup switch and settings are in `$DSH_HOME/storages/dsh-composer-plus/auto-backup.json`, the rescue console switch in `rescue-console.json`, and while dsh runs, `running/host-<pid>.json` names each dsh process (the rescue console reads them to refuse a restore).
|
|
170
175
|
- **Rescue console:** a terminal menu; it opens no network port. A restore writes only into a new folder next to the dsh home (files with `O_EXCL | O_NOFOLLOW`, symbolic links last and never followed) and refuses an archive with an unsafe name (`..`, an absolute path), a device or FIFO, more than one top folder or an entry below a link.
|
|
@@ -187,7 +192,7 @@ Tested on dsh `0.2.0-rc.2` (desktop and web) and `0.2.1-rc.2` (web). CI runs the
|
|
|
187
192
|
- **No branch pill on a chat row:** 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).
|
|
188
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.
|
|
189
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).
|
|
190
|
-
- **Install fails right after a release:** add the version (`dsh-composer-plus@1.
|
|
195
|
+
- **Install fails right after a release:** add the version (`dsh-composer-plus@1.18.0`), see the install note above.
|
|
191
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.
|
|
192
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.
|
|
193
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.
|
|
@@ -237,8 +242,11 @@ Tested on dsh `0.2.0-rc.2` (desktop and web) and `0.2.1-rc.2` (web). CI runs the
|
|
|
237
242
|
- **Improve prompt** sees only a short project summary, the changed paths and the paths whose names match your words: not the code itself. So it can miss the right file, and it names only paths that it was given. Read the new text before you send it. It does not run for a slash command other than `/goal <objective>`, for a `/goal` control word (`clear`, `pause`, `resume`) or for a message with a file or symbol chip (the new text is plain text, so it would lose the chip), and a message can have at most 8,000 characters. For a `/goal` objective it writes conditions only from the draft and the context; a condition that is too strict can cost goal rounds, so read it before you send it. Images stay attached: only the text changes. Each click costs one model call; a strong model can take a minute (`Esc` cancels).
|
|
238
243
|
- **Goal check** checks only a completion that the agent makes in an automatic goal round: a completion that you ask for in the chat, `/goal` and the goal bar are not checked. The agent can change the tests or the test command's files itself; the verifier reads the chat and can see that, but it can be wrong in both directions (a wrong "not done" costs one more round; a wrong "done" closes the goal). The verifier sees the chat and `git status`, not the code itself. A test run is reused only when the agent's newest step that can change files was its own passing `bash` run of exactly the same command in the same folder; a command with a pipe (`| tail`) or `&&` is not reused. The budget is measured when a turn ends, so one turn can go past it. The token budget also counts the calls of the chat's subagent chats (read from their saved logs at each turn end, so a chat with many subagents takes a little longer to check). The evidence table comes from the verifier's own reading of the chat: a part that it calls verified still needs your own look when it matters. `update_goal` waits while the check runs (the test at most 15 minutes, the verifier at most 3 minutes). A fork gets a new chat id, so it starts without the parent's own test command and limits. Each completion that reaches the verifier costs one model call.
|
|
239
244
|
- **Protected files** is a guard rail, not a sandbox. It covers dsh's own file tools (`read`, `read_image`, `grep` on a file, `write`, `edit`, `str_replace_editor`). A shell command (`cat .env`), a script that the agent writes, a subagent's shell, an MCP tool, a `glob` listing and a `grep` over a whole folder can still reach a protected file. For a real limit, use dsh's sandbox modes or keep secrets out of the project folder. Patterns know `*`, `**` and `?`, not `{a,b}` or `[ab]`, and they ignore letter case.
|
|
245
|
+
- **Blocked commands** is a guard rail, not a sandbox. It reads the command text of dsh's `bash` and `pwsh` tools only. A variable or an alias that names the command (`CMD=npm; $CMD publish`), a shell function, a script file that the agent writes, another program (`python -c`, `node -e`, `make`), an MCP tool and your own terminal can still run it. A rule matches more than you may want: any word of a command can be the command name (`echo npm publish` matches `npm publish`), and other words can come between the rule's words (`git push --force` also matches `git push origin main --force`). Make a rule longer when it matches too much. **ask first** needs a chat that can ask: in a chat whose approval policy is never (for example a delegated subagent), dsh cannot show the card, so the call is refused with the reason. The approval card shows the reason in English. **Allow for this chat** does not answer an **ask first** card.
|
|
240
246
|
- **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.
|
|
241
247
|
- **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.
|
|
248
|
+
- **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.
|
|
249
|
+
- **Task board** knows only dsh's projects: a chat outside a project shows **All projects**, and a Branch per chat folder (`<project>/.worktrees/<name>`) counts as its project. The project ids (`acme#12`) come from the folder name and stay when you rename the project in dsh. The rule "keep the board current" goes into a chat only when its project has open tasks; a chat that got it keeps it. Agents are told to leave **Done**, **Backlog** and human tasks to you, but the tools do not refuse it: an agent can still move such a card. The board tools are in every chat's tool list while the feature is on (about 1,000 tokens per request); switch it off if you do not use the board. The page reads the board every 2 seconds while it shows; a change by an agent shows within that time. A text that you edit while an agent changes the same field is not saved: the panel shows the new text and the reason. No images, no git sync between computers and no sharing over the network (Kanzo has them). 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.
|
|
242
250
|
- **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.
|
|
243
251
|
- **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.
|
|
244
252
|
- **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.
|
|
@@ -275,6 +283,8 @@ Tested on dsh `0.2.0-rc.2` (desktop and web) and `0.2.1-rc.2` (web). CI runs the
|
|
|
275
283
|
|
|
276
284
|
**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.
|
|
277
285
|
|
|
286
|
+
**Can my agents and I share one task board, like Kanzo?** Yes, with **Task board** (on by default): open it in the left sidebar and add tasks with **New task**. In a chat, ask the agent to "take the next task from the board": it moves the card to **Doing**, comments on what it did and moves it to **Review**. Mark a task **Human** to keep it for yourself.
|
|
287
|
+
|
|
278
288
|
**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.
|
|
279
289
|
|
|
280
290
|
**dsh does not start any more. How do I restore a backup?** Open the backup folder (`~/Desktop/dsh-backups`) and double-click `Composer Plus Rescue.command` (Linux: `composer-plus-rescue.sh`, Windows: `Composer Plus Rescue.cmd`). Choose **3) Restore a backup**, pick one and type `RESTORE`. It works without dsh.
|
|
@@ -299,6 +309,8 @@ Tested on dsh `0.2.0-rc.2` (desktop and web) and `0.2.1-rc.2` (web). CI runs the
|
|
|
299
309
|
|
|
300
310
|
**How do I see only the files that one chat changed?** Right sidebar → **Changes** → **This chat**. Click **␣** to hide changes that are only whitespace.
|
|
301
311
|
|
|
312
|
+
**How do I stop the agent from running `npm publish` or `git push --force`?** **Settings → Composer Plus → Blocked commands**: type `npm publish`, choose **block** or **ask first**, then click **Add**. **block** refuses the command and the agent asks you; **ask first** shows the approval card each time. Protected files covers the agent's file tools; Blocked commands covers its shell commands.
|
|
313
|
+
|
|
302
314
|
**How do I stop Auto Review asking about the same tool in one chat?** Click **Allow for this chat** on the approval card. It covers that exact tool in that chat only, for 1 hour by default; revoke it from the header chip. Change the time in **Settings → Composer Plus → Allow for this chat**.
|
|
303
315
|
|
|
304
316
|
**I lost my iPhone. How do I stop it from reaching my Mac?** Click **Mobile connect** at the bottom left of the sidebar and click **Remove** next to that iPhone. Its key stops working at once; it can come back only with a new pairing that you approve on the Mac.
|
|
@@ -327,6 +339,8 @@ Tested on dsh `0.2.0-rc.2` (desktop and web) and `0.2.1-rc.2` (web). CI runs the
|
|
|
327
339
|
|
|
328
340
|
**Can I send a photo from my iPhone?** Yes. In a Tether chat, tap **+** next to the message field → Camera, Photos (up to 4) or Paste image. The photos go to the chat on the Mac as attachments of your message, so the model sees them.
|
|
329
341
|
|
|
342
|
+
**Can dsh run the next command without asking the model again?** Yes, with **Planned steps** (off by default): switch it on in Settings → Composer Plus. The model can then plan its next commands with a condition, for example "run the tests when the build passes", and Composer Plus runs a step without a new model call when the result meets the condition. Approvals and the sandbox stay as they are.
|
|
343
|
+
|
|
330
344
|
**Does it work with the desktop app?** Yes: Settings → Plugins → **Add plugin** → `dsh-composer-plus`. Tested on dsh 0.2.0-rc.2 (desktop and web) and 0.2.1-rc.2 (web).
|
|
331
345
|
|
|
332
346
|
## Development
|
|
@@ -391,6 +405,8 @@ PLAYWRIGHT=/path/to/playwright node test/browser-continue-queue.mjs /path/to/dsh
|
|
|
391
405
|
SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-stop-send.mjs /path/to/dsh/lib/bin.js
|
|
392
406
|
# Edit queued message in place with images and files (slow fake model) + its thumbnail
|
|
393
407
|
SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-edit.mjs /path/to/dsh/lib/bin.js
|
|
408
|
+
# Task board: the page, the agent tools (fake model), drag and drop, search, the switch
|
|
409
|
+
SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-task-board.mjs /path/to/dsh/lib/bin.js
|
|
394
410
|
```
|
|
395
411
|
|
|
396
412
|
```sh
|
package/README.pt-BR.md
CHANGED
|
@@ -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.
|
|
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.18.0`.
|
|
33
33
|
|
|
34
34
|
## Recursos
|
|
35
35
|
|
|
@@ -68,7 +68,10 @@ Depois, reinicie o dsh. (A CLI não consegue instalar no perfil desktop; quem ge
|
|
|
68
68
|
| **Verificação da meta** | <a id="feature-goalcheck"></a>Comece uma meta com `/goal`. Quando o agente marca a meta como concluída em uma rodada automática, a meta só é fechada depois de duas verificações. Primeiro, o comando de teste do projeto é executado na pasta do chat, no modo sandbox do chat. O comando é o seu próprio ou o encontrado em `package.json`, `Makefile`, `Cargo.toml`, `go.mod` ou pytest. Quando o passo mais recente do próprio agente foi uma execução bem-sucedida desse teste, ele não é executado de novo. Depois, uma chamada independente ao modelo, sem ferramentas, lê a meta, este chat, o `git status` e o resultado do teste. O modelo responde com uma tabela de evidências: cada parte da meta fica verificada, incorreta ou não resolvida, com a evidência e a correção; a meta só é fechada quando todas as partes estão verificadas. Se uma verificação falhar, a meta continua ativa e o agente lê cada parte em aberto com a evidência e a correção; depois, a próxima rodada continua. Uma linha abaixo da barra da meta (**Verificação da meta**) mostra o teste, o último resultado e quantas partes foram verificadas (passe o ponteiro sobre ela para ver a tabela). **Editar** define o seu próprio comando de teste e um limite de tempo ou de tokens; acima do limite, a meta fica bloqueada. O limite de tokens também conta os subagentes do chat. **Executar agora** executa a verificação sem fechar a meta. Tem o próprio menu **Modelo** nas Configurações (padrão: **Igual ao modelo do chat**). Quando você mesmo conclui a meta, nada é verificado. | <a href="assets/features/goalCheck.webp"><img src="assets/features/goalCheck.webp" width="160" alt="Captura de tela: Verificação da meta"></a> |
|
|
69
69
|
| **Continuar em um novo chat** | <a id="feature-handoffchat"></a>Clique com o botão direito em um chat na barra lateral (ou abra o menu **…** dele) → **Continuar em um novo chat…**. Uma chamada ao próprio modelo do chat escreve uma nota de passagem com o que o chat mostra: Tarefa, Entregas, Concluído, Decisões, Pendências e Próxima ação (as chamadas de ferramentas e os resultados delas são a evidência; os passos que você reverteu ficam de fora). A nota abre em uma caixa de diálogo: leia e edite. **Escrever de novo** escreve uma nova nota. **Iniciar novo chat** (ou `Cmd/Ctrl+Enter`) abre um novo chat no mesmo projeto com a nota e um link para o chat antigo como primeira mensagem; o chat antigo fica como está. Use quando um chat longo estiver cheio ou lento, ou para continuar amanhã. Nada é gravado no projeto. | <a href="assets/features/handoffChat.webp"><img src="assets/features/handoffChat.webp" width="160" alt="Captura de tela: Continuar em um novo chat"></a> |
|
|
70
70
|
| **Detalhamento do contexto** | <a id="feature-contextbreakdown"></a>Barra lateral direita → `+` → **Contexto**. A página mostra o que preenche agora o contexto do modelo do chat aberto e quanto da janela de contexto ele usa: o prompt do sistema, as instruções do projeto (AGENTS.md), as skills, suas mensagens, as respostas do agente e as chamadas de ferramentas, os resultados de ferramentas (por ferramenta), os resultados de MCP (por servidor), as definições de ferramentas, o resumo da compactação e outras notas de contexto, cada um com os tokens e a sua parte. Clique em uma parte para ver as ferramentas ou os servidores dela. Lê só o log do chat, depois do `/compact` e das reversões, e não chama nenhum modelo; lê de novo depois de cada turno e com **Atualizar**. Use para ver por que um chat está lento ou cheio, por exemplo um resultado grande de uma ferramenta MCP ou muitas definições de ferramentas. | <a href="assets/features/contextBreakdown.webp"><img src="assets/features/contextBreakdown.webp" width="160" alt="Captura de tela: Detalhamento do contexto"></a> |
|
|
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> |
|
|
71
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
|
+
| **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 projetos do dsh, para você e para os agentes: **A fazer**, **Fazendo**, **Em revisão** e **Concluído** (e **Em espera**, veja abaixo). Escolha um projeto ou **Todos os projetos** à esquerda. **Nova tarefa** (ou `n`) abre um cartão novo: digite o título e pressione `Enter`. Arraste um cartão para outra coluna ou entre dois cartões. Clique em um cartão para ver e mudar **Status**, **Etiquetas**, **Manual** (os agentes a ignoram), a descrição (Markdown) e os comentários. `/` busca em todos os projetos, `h` mostra só as tarefas manuais e o botão de exportar salva o quadro como Markdown ou JSON. Os agentes recebem ferramentas do quadro: peça a um chat para "pegar a próxima tarefa do quadro" e ele move o primeiro cartão de **A fazer** para **Fazendo**, comenta o que fez e o move para **Em revisão**; você o move para **Concluído**. Em um projeto com tarefas abertas, cada chat recebe essa regra sozinho. Configurações → Composer Plus → **Quadro de tarefas** tem a chave da coluna **Em espera**: os agentes deixam os cartões dela para você. | <a href="assets/features/taskBoard.webp"><img src="assets/features/taskBoard.webp" width="160" alt="Captura de tela: Quadro de tarefas"></a> |
|
|
72
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> |
|
|
73
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> |
|
|
74
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> |
|
|
@@ -166,7 +169,9 @@ Testado no dsh `0.2.0-rc.2` (desktop e web) e `0.2.1-rc.2` (web). A CI executa o
|
|
|
166
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).
|
|
167
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.
|
|
168
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 (títulos, descrições, etiquetas e comentários das suas tarefas, os caminhos das pastas dos projetos e os ids curtos delas) fica em `$DSH_HOME/storages/dsh-composer-plus/board.json` (arquivo só para o dono); a chave fica em `board-switch.json`, ao lado. Nada sai do seu computador e nada é gravado em uma pasta de projeto. As ferramentas do quadro dão aos agentes o que você escreveu no quadro, então o texto de uma tarefa chega ao modelo do chat quando um agente a lê. Um arquivo do quadro corrompido é guardado como `board.json.broken-<time>` e o quadro começa vazio.
|
|
169
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
|
+
- **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.
|
|
170
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.
|
|
171
176
|
- **Backup:** nada sai do seu computador. Os arquivos compactados vão para `~/Desktop/dsh-backups` (arquivos só para o dono). Os segredos não ficam no arquivo compactado: arquivos de credenciais (`.credentials.yaml`, `.env`), arquivos de chave (`.pem`, `.key`, `.p12`, `.pfx`) e os valores das configurações token, secret, password e API key nos arquivos yml são mascarados; as cópias reais ficam em `composer-plus-vault/<archive>/`, na mesma pasta (só para o dono), só neste computador. **Para outro computador** não copia nenhum vault: informe esses segredos de novo lá. Os seus logs de chat, as suas configurações e o resto do dsh home ficam no arquivo compactado como estão: mantenha a pasta privada, como o próprio `$DSH_HOME`. O backup lê os arquivos com `O_NOFOLLOW | O_NONBLOCK`; um symlink é guardado como link (nunca é seguido) e um FIFO ou dispositivo é ignorado. A chave e as opções do backup automático ficam em `$DSH_HOME/storages/dsh-composer-plus/auto-backup.json`, a chave do console de resgate em `rescue-console.json` e, enquanto o dsh está em execução, `running/host-<pid>.json` identifica cada processo do dsh (o console de resgate os lê para recusar uma restauração).
|
|
172
177
|
- **Console de resgate:** um menu de terminal; ele não abre nenhuma porta de rede. Uma restauração grava só em uma pasta nova ao lado do dsh home (arquivos com `O_EXCL | O_NOFOLLOW`, symlinks por último e nunca seguidos) e recusa um arquivo compactado com um nome inseguro (`..`, um caminho absoluto), um dispositivo ou FIFO, mais de uma pasta de nível superior ou uma entrada abaixo de um link.
|
|
@@ -189,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
|
|
|
189
194
|
- **Nenhuma etiqueta de branch em uma linha de chat:** 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).
|
|
190
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.
|
|
191
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).
|
|
192
|
-
- **A instalação falha logo depois de uma nova versão:** informe a versão (`dsh-composer-plus@1.
|
|
197
|
+
- **A instalação falha logo depois de uma nova versão:** informe a versão (`dsh-composer-plus@1.18.0`); veja a nota de instalação acima.
|
|
193
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.
|
|
194
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.
|
|
195
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.
|
|
@@ -239,8 +244,11 @@ Testado no dsh `0.2.0-rc.2` (desktop e web) e `0.2.1-rc.2` (web). A CI executa o
|
|
|
239
244
|
- **Melhorar prompt** vê só um resumo curto do projeto, os caminhos alterados e os caminhos cujos nomes combinam com as suas palavras: não o código em si. Por isso, pode não encontrar o arquivo certo, e só cita caminhos que recebeu. Leia o novo texto antes de enviá-lo. Ele não é executado em um comando de barra que não seja `/goal <meta>`, em uma palavra de controle do `/goal` (`clear`, `pause`, `resume`) nem em uma mensagem com um chip de arquivo ou de símbolo (o novo texto é texto simples, então o chip se perderia), e uma mensagem pode ter no máximo 8.000 caracteres. Para uma meta do `/goal`, ele escreve condições só a partir do rascunho e do contexto; uma condição rígida demais pode custar rodadas da meta, então leia-a antes de enviar. As imagens continuam anexadas: só o texto muda. Cada clique custa uma chamada ao modelo; um modelo forte pode levar um minuto (`Esc` cancela).
|
|
240
245
|
- **Verificação da meta** verifica só uma conclusão que o agente faz em uma rodada automática da meta: uma conclusão que você pede no chat, `/goal` e a barra da meta não são verificados. O agente pode alterar os testes ou os arquivos do comando de teste por conta própria; o verificador lê o chat e pode ver isso, mas pode errar nos dois sentidos (um "não concluída" errado custa mais uma rodada; um "concluída" errado fecha a meta). O verificador vê o chat e o `git status`, não o código em si. Uma execução de teste só é reaproveitada quando o passo mais recente do agente que pode alterar arquivos foi a sua própria execução bem-sucedida de `bash` com exatamente o mesmo comando na mesma pasta; um comando com pipe (`| tail`) ou `&&` não é reaproveitado. O orçamento é medido quando um turno termina, então um turno pode ultrapassá-lo. O orçamento de tokens também conta as chamadas dos chats de subagentes do chat (lidas dos logs salvos deles ao fim de cada turno, então um chat com muitos subagentes leva um pouco mais para ser verificado). A tabela de evidências vem da própria leitura do chat feita pelo verificador: uma parte que ele chama de verificada ainda precisa que você mesmo olhe quando isso importa. `update_goal` espera enquanto a verificação é executada (o teste no máximo 15 minutos, o verificador no máximo 3 minutos). Uma bifurcação recebe um novo id de chat, então começa sem o comando de teste e os limites próprios do chat original. Cada conclusão que chega ao verificador custa uma chamada ao modelo.
|
|
241
246
|
- **Arquivos protegidos** é uma barreira de proteção, não um sandbox. Cobre as ferramentas de arquivo do próprio dsh (`read`, `read_image`, `grep` em um arquivo, `write`, `edit`, `str_replace_editor`). Um comando de shell (`cat .env`), um script que o agente escreve, o shell de um subagente, uma ferramenta MCP, uma listagem de `glob` e um `grep` em uma pasta inteira ainda podem acessar um arquivo protegido. Para um limite real, use os modos sandbox do dsh ou mantenha segredos fora da pasta do projeto. Os padrões conhecem `*`, `**` e `?`, não `{a,b}` nem `[ab]`, e ignoram maiúsculas e minúsculas.
|
|
247
|
+
- **Comandos bloqueados** é uma barreira de proteção, não um sandbox. Lê só o texto do comando das ferramentas `bash` e `pwsh` do dsh. Uma variável ou um alias que nomeia o comando (`CMD=npm; $CMD publish`), uma função de shell, um arquivo de script que o agente escreve, outro programa (`python -c`, `node -e`, `make`), uma ferramenta MCP e o seu próprio terminal ainda podem executá-lo. Uma regra pode corresponder a mais do que você quer: qualquer palavra de um comando pode ser o nome do comando (`echo npm publish` corresponde a `npm publish`), e outras palavras podem vir entre as palavras da regra (`git push --force` também corresponde a `git push origin main --force`). Deixe a regra mais longa quando ela corresponder a coisas demais. **perguntar antes** precisa de um chat que possa perguntar: em um chat cuja política de aprovação é never (por exemplo, um subagente delegado), o dsh não consegue mostrar o cartão, então a chamada é recusada com o motivo. O cartão de aprovação mostra o motivo em inglês. **Permitir neste chat** não responde a um cartão de **perguntar antes**.
|
|
242
248
|
- **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.
|
|
243
249
|
- **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.
|
|
250
|
+
- **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.
|
|
251
|
+
- **Quadro de tarefas** conhece só os projetos do dsh: um chat fora de um projeto mostra **Todos os projetos**, e a pasta de um branch por chat (`<project>/.worktrees/<name>`) conta como o projeto dela. Os ids de projeto (`acme#12`) vêm do nome da pasta e não mudam quando você renomeia o projeto no dsh. A regra "mantenha o quadro em dia" entra em um chat só quando o projeto dele tem tarefas abertas; um chat que já a recebeu a mantém. Os agentes são orientados a deixar **Concluído**, **Em espera** e as tarefas manuais para você, mas as ferramentas não recusam: um agente ainda pode mover um desses cartões. As ferramentas do quadro ficam na lista de ferramentas de todo chat enquanto o recurso está ativado (cerca de 1.000 tokens por solicitação); desative-o se você não usa o quadro. A página lê o quadro a cada 2 segundos enquanto aparece; uma mudança de um agente aparece nesse tempo. Um texto que você edita enquanto um agente muda o mesmo campo não é salvo: o painel mostra o texto novo e o motivo. Não há imagens, nem sincronização por git entre computadores, nem compartilhamento pela rede (o Kanzo tem isso). 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.
|
|
244
252
|
- **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.
|
|
245
253
|
- **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.
|
|
246
254
|
- **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.
|
|
@@ -277,6 +285,8 @@ Testado no dsh `0.2.0-rc.2` (desktop e web) e `0.2.1-rc.2` (web). A CI executa o
|
|
|
277
285
|
|
|
278
286
|
**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.
|
|
279
287
|
|
|
288
|
+
**Meus agentes e eu podemos usar um só quadro de tarefas, como no Kanzo?** Sim, com **Quadro de tarefas** (ativado por padrão): abra-o na barra lateral esquerda e adicione tarefas com **Nova tarefa**. Em um chat, peça ao agente para "pegar a próxima tarefa do quadro": ele move o cartão para **Fazendo**, comenta o que fez e o move para **Em revisão**. Marque uma tarefa como **Manual** para ficar com ela.
|
|
289
|
+
|
|
280
290
|
**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.
|
|
281
291
|
|
|
282
292
|
**O dsh não inicia mais. Como restauro um backup?** Abra a pasta de backups (`~/Desktop/dsh-backups`) e clique duas vezes em `Composer Plus Rescue.command` (Linux: `composer-plus-rescue.sh`, Windows: `Composer Plus Rescue.cmd`). Escolha `3) Restore a backup`, selecione um e digite `RESTORE`. Funciona sem o dsh.
|
|
@@ -301,6 +311,8 @@ Testado no dsh `0.2.0-rc.2` (desktop e web) e `0.2.1-rc.2` (web). A CI executa o
|
|
|
301
311
|
|
|
302
312
|
**Como vejo só os arquivos que um chat alterou?** Barra lateral direita → **Alterações** → **Este chat**. Clique em **␣** para ocultar alterações que são só espaço em branco.
|
|
303
313
|
|
|
314
|
+
**Como impeço o agente de executar `npm publish` ou `git push --force`?** **Configurações → Composer Plus → Comandos bloqueados**: digite `npm publish`, escolha **bloquear** ou **perguntar antes** e depois clique em **Adicionar**. **bloquear** recusa o comando e o agente pergunta a você; **perguntar antes** mostra o cartão de aprovação toda vez. Arquivos protegidos cobre as ferramentas de arquivo do agente; Comandos bloqueados cobre os comandos de shell dele.
|
|
315
|
+
|
|
304
316
|
**Como faço a Revisão automática parar de perguntar sobre a mesma ferramenta em um chat?** Clique em **Permitir neste chat** no cartão de aprovação. Isso cobre só aquela ferramenta exata naquele chat, por 1 hora por padrão; revogue pelo chip no cabeçalho. Mude o tempo em **Configurações → Composer Plus → Permitir neste chat**.
|
|
305
317
|
|
|
306
318
|
**Perdi meu iPhone. Como impeço que ele acesse meu Mac?** Clique em **Conexão móvel** no canto inferior esquerdo da barra lateral e clique em **Remove** ao lado desse iPhone. A chave dele para de funcionar na hora; ele só volta com um novo pareamento que você aprove no Mac.
|
|
@@ -329,6 +341,8 @@ Testado no dsh `0.2.0-rc.2` (desktop e web) e `0.2.1-rc.2` (web). A CI executa o
|
|
|
329
341
|
|
|
330
342
|
**Posso enviar uma foto do meu iPhone?** Sim. Em um chat do Tether, toque em **+** ao lado do campo de mensagem → Camera, Photos (até 4) ou Paste image. As fotos vão para o chat no Mac como anexos da sua mensagem, então o modelo as vê.
|
|
331
343
|
|
|
344
|
+
**O dsh pode rodar o próximo comando sem perguntar de novo ao modelo?** Sim, com **Etapas planejadas** (desativado por padrão): ative em Configurações → Composer Plus. O modelo pode então planejar os próximos comandos com uma condição, por exemplo “rode os testes quando o build passar”, e o Composer Plus executa uma etapa sem nova chamada ao modelo quando o resultado atende à condição. Aprovações e sandbox continuam iguais.
|
|
345
|
+
|
|
332
346
|
**Funciona com o app desktop?** Sim: Configurações → Plugins → **Adicionar plugin** → `dsh-composer-plus`. Testado no dsh 0.2.0-rc.2 (desktop e web) e 0.2.1-rc.2 (web).
|
|
333
347
|
|
|
334
348
|
## Desenvolvimento
|
|
@@ -393,6 +407,8 @@ PLAYWRIGHT=/path/to/playwright node test/browser-continue-queue.mjs /path/to/dsh
|
|
|
393
407
|
SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-stop-send.mjs /path/to/dsh/lib/bin.js
|
|
394
408
|
# Edit queued message in place with images and files (slow fake model) + its thumbnail
|
|
395
409
|
SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-edit.mjs /path/to/dsh/lib/bin.js
|
|
410
|
+
# Task board: the page, the agent tools (fake model), drag and drop, search, the switch
|
|
411
|
+
SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-task-board.mjs /path/to/dsh/lib/bin.js
|
|
396
412
|
```
|
|
397
413
|
|
|
398
414
|
```sh
|