dsh-composer-plus 1.16.1 → 1.17.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.vi.md CHANGED
@@ -29,7 +29,7 @@ dsh plugin --profile web add dsh-composer-plus
29
29
 
30
30
  Sau đó khởi động lại dsh. (CLI không cài được vào profile desktop; ứng dụng tự quản lý profile này.)
31
31
 
32
- > pnpm của dsh bỏ qua các phiên bản ra mắt chưa đủ 24 giờ. Ngay sau một bản phát hành, hãy thêm số phiên bản: `dsh-composer-plus@1.16.1`.
32
+ > pnpm của dsh bỏ qua các phiên bản ra mắt chưa đủ 24 giờ. Ngay sau một bản phát hành, hãy thêm số phiên bản: `dsh-composer-plus@1.17.0`.
33
33
 
34
34
  ## Tính năng
35
35
 
@@ -47,6 +47,7 @@ Sau đó khởi động lại dsh. (CLI không cài được vào profile deskto
47
47
  | **Chế độ kế hoạch bằng Shift+Tab** | <a id="feature-plantoggle"></a>`Shift+Tab` thêm `/plan ` vào đầu bản nháp (nhấn lần nữa để xóa). Nếu cuộc trò chuyện đã ở chế độ kế hoạch, `Shift+Tab` thoát chế độ này. | <a href="assets/features/planToggle.webp"><img src="assets/features/planToggle.webp" width="160" alt="Ảnh chụp màn hình: Chế độ kế hoạch bằng Shift+Tab"></a> |
48
48
  | **Giữ con trỏ trong khung soạn thảo** | <a id="feature-keepfocus"></a>Sau khi bạn gửi một lệnh `/` hoặc một skill, con trỏ vẫn ở trong khung soạn thảo và bạn có thể gõ tiếp ngay. Việc này cũng áp dụng cho macro bàn phím gõ một lệnh rồi nhấn `Enter`. dsh đặt khung soạn thảo ở chế độ chỉ đọc trong lúc xử lý lệnh, và khi đó trình duyệt bỏ tiêu điểm khỏi khung. Tính năng này trả tiêu điểm lại, trừ khi một menu, một hộp thoại hoặc một ô khác đang giữ tiêu điểm. | <a href="assets/features/keepFocus.webp"><img src="assets/features/keepFocus.webp" width="160" alt="Ảnh chụp màn hình: Giữ con trỏ trong khung soạn thảo"></a> |
49
49
  | **Vừa thẻ câu hỏi với cửa sổ** | <a id="feature-questionfit"></a>Khi tác tử hỏi bạn, câu hỏi và các câu trả lời cuộn cùng nhau trong thẻ, còn **Bỏ qua** và **Gửi** luôn hiện ở dưới cùng. Thẻ dùng chiều cao của cửa sổ (trừ 200 px cho tiêu đề cuộc trò chuyện và một dải cuộc trò chuyện), nên thẻ lớn lên và nhỏ lại theo cửa sổ. Khi không có tính năng này, dsh giới hạn thẻ ở 60% cửa sổ (tối đa 520 px) và chỉ cuộn các câu trả lời: một câu hỏi dài có thể đẩy phần cuối của nó, các câu trả lời và các nút ra ngoài thẻ. | <a href="assets/features/questionFit.webp"><img src="assets/features/questionFit.webp" width="160" alt="Ảnh chụp màn hình: Vừa thẻ câu hỏi với cửa sổ"></a> |
50
+ | **Vừa tiêu đề cuộc trò chuyện với cửa sổ** | <a id="feature-headerfit"></a>Trong cửa sổ hẹp, các nút ở tiêu đề cuộc trò chuyện của dsh (chế độ, tác tử con, tác vụ nền, Mở bằng, nhãn nhánh và nhãn quyền) không còn che nhau. Tên cuộc trò chuyện giữ ít nhất 120 px; các nút không vừa sẽ xuống dòng thứ hai ở bên phải, và nút nào cũng bấm được. Khi mọi thứ vừa một dòng (cửa sổ rộng), tiêu đề giống hệt của dsh. Không có tính năng này, dsh chỉ thu nhỏ tên: khi có tác tử con và tác vụ nền, các nút trượt chồng lên nhau trong cột trò chuyện hẹp. Nhãn nhánh (**Branch riêng cho từng cuộc trò chuyện**) và nhãn quyền (**Cho phép trong cuộc trò chuyện này**) cũng vừa với tiêu đề khi tắt công tắc này. | <a href="assets/features/headerFit.webp"><img src="assets/features/headerFit.webp" width="160" alt="Ảnh chụp màn hình: Vừa tiêu đề cuộc trò chuyện với cửa sổ"></a> |
50
51
  | **Tiếp tục bằng một cú nhấp** | <a id="feature-continuebutton"></a>Sau một lượt đã dừng, thất bại hoặc bị cắt ngang, khung soạn thảo trống hiện **▶**. Một cú nhấp sẽ tiếp tục từ cuộc hội thoại hiện có, không cần gõ gì vào ô nhập và không thêm tin nhắn hiển thị vào cuộc trò chuyện. (Mô hình nhận một ghi chú ẩn ngắn “tiếp tục từ chỗ đã dừng”, vì một số nhà cung cấp như Claude từ chối yêu cầu kết thúc bằng câu trả lời của trợ lý.) Tin nhắn trong hàng đợi vẫn ở đó: ▶ chỉ tiếp tục tác vụ đã dừng, sau đó hàng đợi mới chạy. Lượt đã hoàn tất vẫn giữ nút Gửi thông thường. | <a href="assets/features/continueButton.webp"><img src="assets/features/continueButton.webp" width="160" alt="Ảnh chụp màn hình: Tiếp tục bằng một cú nhấp"></a> |
51
52
  | **Tiếp tục sau khi khởi động lại** | <a id="feature-resumeafterrestart"></a>Mặc định tắt: hãy bật trong **Cài đặt → Composer Plus**. Nếu bạn thoát dsh (hoặc dsh bị đóng) khi một cuộc trò chuyện đang làm việc, cuộc trò chuyện đó tự tiếp tục khi bạn mở lại dsh, với cùng ghi chú ẩn như Tiếp tục bằng một cú nhấp. Nếu một vòng mục tiêu (`/goal`) đang chạy, mục tiêu tiếp tục với vòng kế tiếp (mỗi lần khởi động, dsh tạm dừng các mục tiêu cho đến khi bạn tiếp tục chúng). Các cuộc trò chuyện bạn đã dừng, đã xong hoặc đã thất bại không tiếp tục. Bản thân dsh không có cài đặt cho việc này: dsh chỉ đánh dấu lượt như vậy là bị ngắt. | <a href="assets/features/resumeAfterRestart.webp"><img src="assets/features/resumeAfterRestart.webp" width="160" alt="Ảnh chụp màn hình: Tiếp tục sau khi khởi động lại"></a> |
52
53
  | **Kéo thả hàng đợi** | <a id="feature-queuereorder"></a>Tin nhắn trong hàng đợi có một tay nắm (⠿). Kéo để sắp xếp lại, hoặc đặt tiêu điểm vào tay nắm rồi nhấn `↑` / `↓`. `Esc` hủy thao tác. | <a href="assets/features/queueReorder.webp"><img src="assets/features/queueReorder.webp" width="160" alt="Ảnh chụp màn hình: Kéo thả hàng đợi"></a> |
@@ -63,19 +64,22 @@ Sau đó khởi động lại dsh. (CLI không cài được vào profile deskto
63
64
  | **Branch trong cây không gian làm việc** | <a id="feature-branchtree"></a>Cài đặt → Composer Plus → **Branch trong cây không gian làm việc** (tắt theo mặc định). Khi bật, mỗi branch có thư mục worktree trong `<project>/.worktrees/` hiển thị như một dự án bên trong dự án của nó; chọn **Tùy chọn hiển thị** → **Cây không gian làm việc** của dsh để xem dạng lồng nhau. Branch có thư mục bị xóa sẽ rời danh sách, và dsh hiển thị các cuộc trò chuyện của nó trong **Chưa nhóm**. Khi agent của một cuộc trò chuyện trong thư mục dự án tạo một branch và chuyển sang branch đó (`git switch -c`, `git checkout -b`) trong khi thư mục không có thay đổi chưa commit, thư mục dự án trở về branch trước đó, branch có thư mục riêng, và cuộc trò chuyện chuyển sang đó: một bản sao mở trong dự án của branch và tiếp tục công việc, cuộc trò chuyện cũ được lưu trữ. Danh sách được kiểm tra khi khởi động, mỗi 30 giây, sau mỗi lượt và khi bạn quay lại cửa sổ. | <a href="assets/features/branchTree.webp"><img src="assets/features/branchTree.webp" width="160" alt="Ảnh chụp màn hình: Branch trong cây không gian làm việc"></a> |
64
65
  | **Dự đoán tin nhắn tiếp theo** | <a id="feature-nextprediction"></a>Mặc định bật: bạn có thể tắt trong **Cài đặt → Composer Plus**. Khi tác tử hoàn tất một lượt (không phải lượt đã dừng hoặc thất bại), khung soạn thảo trống hiện dự đoán tin nhắn tiếp theo của bạn bằng chữ màu xám, kèm gợi ý **Tab để chấp nhận**. `Tab` đưa văn bản vào khung soạn thảo nhưng không gửi. `Esc` ẩn dự đoán trong lượt đó. Khi bạn bắt đầu gõ, dự đoán cũng ẩn đi, và một lượt mới sẽ thay thế nó. Menu **Mô hình** bên dưới công tắc liệt kê các mô hình của chính dsh (cùng danh sách với menu mô hình của dsh). **Mặc định của dsh** được chọn theo mặc định và đi theo mô hình mặc định của dsh. Mỗi lượt đã xong tốn một lần gọi mô hình ngắn. Trong Tether, dự đoán hiện phía trên khung soạn thảo trống: chạm vào để đưa nó vào ô nhập. | <a href="assets/features/nextPrediction.webp"><img src="assets/features/nextPrediction.webp" width="160" alt="Ảnh chụp màn hình: Dự đoán tin nhắn tiếp theo"></a> |
65
66
  | **Hoàn thành khi gõ** | <a id="feature-typingcompletion"></a>Mặc định tắt: bạn có thể bật trong **Cài đặt → Composer Plus**. Khi bạn gõ, chữ màu xám ngay sau con trỏ cho thấy tin nhắn của bạn có thể tiếp tục thế nào. `Tab` thêm phần này vào tin nhắn nhưng không gửi. `Esc` ẩn phần này. Tính năng chỉ gợi ý những từ tiếp theo của chính bạn: không bao giờ là câu trả lời cho bạn, và không bịa ra nội dung lỗi hay tên. Khi tin nhắn có vẻ đã đủ hoặc mô hình không chắc chắn, sẽ không có gì hiện ra. Nếu bạn gõ đúng các chữ tiếp theo của phần chữ xám, phần này vẫn giữ nguyên, không có lần gọi mô hình mới. Tính năng có menu **Mô hình** riêng bên dưới công tắc của nó. Mục đầu tiên, **Giống dự đoán tin nhắn tiếp theo**, dùng mô hình của **Dự đoán tin nhắn tiếp theo** (mặc định); hãy chọn mô hình khác để mỗi tính năng dùng một mô hình riêng, ví dụ một mô hình nhanh hơn cho phần hoàn thành. Tính năng gọi mô hình một lần mỗi khi bạn dừng gõ, nên tốn nhiều token hơn nhiều so với dự đoán: hãy chọn một mô hình nhanh, chi phí thấp. Tính năng không chạy với lệnh gạch chéo, tin nhắn có nhãn tệp, hoặc khi con trỏ không ở cuối. Trong Tether, phần còn lại hiện phía trên ô nhập khi bạn gõ: chạm vào để thêm. | <a href="assets/features/typingCompletion.webp"><img src="assets/features/typingCompletion.webp" width="160" alt="Ảnh chụp màn hình: Hoàn thành khi gõ"></a> |
66
- | **Cải thiện prompt** | <a id="feature-promptimprove"></a>Gõ một yêu cầu sơ bộ, rồi nhấp vào đũa thần (**Cải thiện prompt**) cạnh menu mô hình. Một lần gọi mô hình viết lại yêu cầu thành một prompt rõ ràng hơn: mục tiêu trước, các bước đánh số ngắn khi có nhiều phần, và bước kiểm tra cần chạy. Tính năng đọc cuộc trò chuyện này (bỏ qua các tin nhắn đã bị hoàn tác), README, AGENTS.md và tệp manifest của dự án, các tệp đã thay đổi và các tệp có tên khớp với từ ngữ của bạn, và giữ nguyên ngôn ngữ của bạn. Tính năng không bao giờ bịa ra tên tệp. Văn bản mới thay thế bản nháp của bạn nhưng không được gửi: hãy đọc, sửa, rồi nhấn `Enter`. `Cmd/Ctrl+Z` đưa văn bản của bạn trở lại trong một bước, nút (**Hoàn tác cải thiện**) cũng vậy. Nếu bạn gõ trong lúc tính năng đang chạy, văn bản mới của bạn được giữ lại. `Esc` hoặc nhấp lần nữa để hủy. Tính năng có menu **Mô hình** riêng trong Cài đặt (mặc định: **Giống mô hình của cuộc trò chuyện**). Không dùng cho lệnh gạch chéo hoặc tin nhắn có nhãn tệp. Trong Tether, đũa thần nằm cạnh ô nhập. | <a href="assets/features/promptImprove.webp"><img src="assets/features/promptImprove.webp" width="160" alt="Ảnh chụp màn hình: Cải thiện prompt"></a> |
67
- | **Kiểm tra mục tiêu** | <a id="feature-goalcheck"></a>Bắt đầu một mục tiêu bằng `/goal`. Khi tác tử đánh dấu mục tiêu là hoàn tất trong một vòng tự động, mục tiêu chỉ đóng sau hai bước kiểm tra. Đầu tiên, lệnh kiểm thử của dự án chạy trong thư mục của cuộc trò chuyện, theo chế độ sandbox của cuộc trò chuyện. Lệnh này là lệnh của riêng bạn hoặc lệnh tìm thấy trong `package.json`, `Makefile`, `Cargo.toml`, `go.mod` hoặc pytest. Khi bước mới nhất của chính tác tử là một lần chạy đạt của bài kiểm thử đó, lệnh không chạy lại. Sau đó, một lần gọi mô hình độc lập, không có công cụ, đọc mục tiêu, cuộc trò chuyện này, `git status` và kết quả kiểm thử. Nếu một bước kiểm tra không đạt, mục tiêu vẫn đang hoạt động và tác tử đọc lý do, rồi vòng tiếp theo tiếp tục. Một dòng bên dưới thanh mục tiêu (**Kiểm tra mục tiêu**) hiện bài kiểm thử và kết quả gần nhất. **Sửa** đặt lệnh kiểm thử của riêng bạn và giới hạn thời gian hoặc token; khi vượt giới hạn, mục tiêu bị chặn. **Chạy ngay** chạy bước kiểm tra mà không đóng mục tiêu. Tính năng có menu **Mô hình** riêng trong Cài đặt (mặc định: **Giống mô hình của cuộc trò chuyện**). Khi bạn tự hoàn tất mục tiêu, không có gì được kiểm tra. | <a href="assets/features/goalCheck.webp"><img src="assets/features/goalCheck.webp" width="160" alt="Ảnh chụp màn hình: Kiểm tra mục tiêu"></a> |
68
- | **Bộ nhớ dự án** | <a id="feature-projectmemory"></a>Mặc định tắt: hãy bật trong **Cài đặt → Composer Plus**. Mỗi thư mục dự án có bộ nhớ riêng, các cuộc trò chuyện sau này của dự án đó sẽ đọc, giống như DS Bot giữ một bộ nhớ cho mỗi Bot. Sau mỗi lượt kết thúc, một lần gọi mô hình của cuộc trò chuyện đọc các tin nhắn mới (không đọc tin nhắn đã hoàn tác), lưu sở thích, quyết định và dữ kiện lâu dài của bạn thành ghi chú ngắn, đồng thời sửa hoặc xóa ghi chú cũ. Tác tử cũng có thể tự lưu, xóa và tìm ghi chú (`memory_remember`, `memory_forget`, `memory_recall`). Ghi chú cũng có thể là ghi chú chung: mọi dự án đều đọc. Cuộc trò chuyện mới nhận các ghi chú trong system prompt; ghi chú lưu sau đó hiện từ cuộc trò chuyện tiếp theo. Các tệp là Markdown trong thư mục home của dsh (`storages/dsh-composer-plus/memory/`), không bao giờ nằm trong thư mục dự án. | <a href="assets/features/projectMemory.webp"><img src="assets/features/projectMemory.webp" width="160" alt="Ảnh chụp màn hình: Bộ nhớ dự án"></a> |
67
+ | **Cải thiện prompt** | <a id="feature-promptimprove"></a>Gõ một yêu cầu sơ bộ, rồi nhấp vào đũa thần (**Cải thiện prompt**) cạnh menu mô hình. Một lần gọi mô hình viết lại yêu cầu thành một prompt rõ ràng hơn: mục tiêu trước, các bước đánh số ngắn khi có nhiều phần, và bước kiểm tra cần chạy. Tính năng đọc cuộc trò chuyện này (bỏ qua các tin nhắn đã bị hoàn tác), README, AGENTS.md và tệp manifest của dự án, các tệp đã thay đổi và các tệp có tên khớp với từ ngữ của bạn, và giữ nguyên ngôn ngữ của bạn. Tính năng không bao giờ bịa ra tên tệp. Văn bản mới thay thế bản nháp của bạn nhưng không được gửi: hãy đọc, sửa, rồi nhấn `Enter`. `Cmd/Ctrl+Z` đưa văn bản của bạn trở lại trong một bước, nút (**Hoàn tác cải thiện**) cũng vậy. Nếu bạn gõ trong lúc tính năng đang chạy, văn bản mới của bạn được giữ lại. `Esc` hoặc nhấp lần nữa để hủy. Tính năng có menu **Mô hình** riêng trong Cài đặt (mặc định: **Giống mô hình của cuộc trò chuyện**). Với tin nhắn `/goal <objective>`, tính năng chỉ viết lại phần mục tiêu thành một điều kiện hoàn tất mà **Kiểm tra mục tiêu** có thể xác minh: kết quả đầu ra, các bước kiểm tra phải đạt, bằng chứng cần hiện trong cuộc trò chuyện, phần không làm được được đánh dấu là chưa giải quyết, và dừng lại khi cùng một trở ngại vẫn còn. Lệnh `/goal` được giữ nguyên. Không dùng cho các lệnh gạch chéo khác, từ điều khiển của `/goal` (`clear`, `pause`, `resume`) hoặc tin nhắn có nhãn tệp. Trong Tether, đũa thần nằm cạnh ô nhập. | <a href="assets/features/promptImprove.webp"><img src="assets/features/promptImprove.webp" width="160" alt="Ảnh chụp màn hình: Cải thiện prompt"></a> |
68
+ | **Kiểm tra mục tiêu** | <a id="feature-goalcheck"></a>Bắt đầu một mục tiêu bằng `/goal`. Khi tác tử đánh dấu mục tiêu là hoàn tất trong một vòng tự động, mục tiêu chỉ đóng sau hai bước kiểm tra. Đầu tiên, lệnh kiểm thử của dự án chạy trong thư mục của cuộc trò chuyện, theo chế độ sandbox của cuộc trò chuyện. Lệnh này là lệnh của riêng bạn hoặc lệnh tìm thấy trong `package.json`, `Makefile`, `Cargo.toml`, `go.mod` hoặc pytest. Khi bước mới nhất của chính tác tử là một lần chạy đạt của bài kiểm thử đó, lệnh không chạy lại. Sau đó, một lần gọi mô hình độc lập, không có công cụ, đọc mục tiêu, cuộc trò chuyện này, `git status` và kết quả kiểm thử. Mô hình trả lời bằng một bảng bằng chứng: mỗi phần của mục tiêu được đánh dấu là đã xác minh, sai hoặc chưa giải quyết, kèm bằng chứng và cách sửa; mục tiêu chỉ đóng khi mọi phần đều đã xác minh. Nếu một bước kiểm tra không đạt, mục tiêu vẫn đang hoạt động và tác tử đọc từng phần còn mở kèm bằng chứng và cách sửa, rồi vòng tiếp theo tiếp tục. Một dòng bên dưới thanh mục tiêu (**Kiểm tra mục tiêu**) hiện bài kiểm thử, kết quả gần nhất và số phần đã xác minh (di chuột lên dòng này để xem bảng). **Sửa** đặt lệnh kiểm thử của riêng bạn và giới hạn thời gian hoặc token; khi vượt giới hạn, mục tiêu bị chặn. Giới hạn token cũng tính cả các subagent của cuộc trò chuyện. **Chạy ngay** chạy bước kiểm tra mà không đóng mục tiêu. Tính năng có menu **Mô hình** riêng trong Cài đặt (mặc định: **Giống mô hình của cuộc trò chuyện**). Khi bạn tự hoàn tất mục tiêu, không có gì được kiểm tra. | <a href="assets/features/goalCheck.webp"><img src="assets/features/goalCheck.webp" width="160" alt="Ảnh chụp màn hình: Kiểm tra mục tiêu"></a> |
69
+ | **Tiếp tục trong cuộc trò chuyện mới** | <a id="feature-handoffchat"></a>Nhấp chuột phải vào một cuộc trò chuyện trên thanh bên (hoặc mở menu **…** của nó) → **Tiếp tục trong cuộc trò chuyện mới…**. Một lần gọi chính mô hình của cuộc trò chuyện viết ghi chú bàn giao từ những gì cuộc trò chuyện hiển thị: Nhiệm vụ, Kết quả đầu ra, Đã hoàn thành, Quyết định, Vấn đề còn mở và Hành động tiếp theo (các lệnh gọi công cụ và kết quả của chúng là bằng chứng; các bước bạn đã hoàn tác được bỏ ra). Ghi chú mở trong một hộp thoại: hãy đọc và sửa ghi chú. **Viết lại** viết một ghi chú mới. **Bắt đầu cuộc trò chuyện mới** (hoặc `Cmd/Ctrl+Enter`) mở một cuộc trò chuyện mới trong cùng dự án với ghi chú và liên kết đến cuộc trò chuyện cũ làm tin nhắn đầu tiên; cuộc trò chuyện cũ vẫn giữ nguyên. Dùng tính năng này khi một cuộc trò chuyện dài đã đầy hoặc chậm, hoặc để tiếp tục vào ngày mai. Không có gì được ghi vào dự án. | <a href="assets/features/handoffChat.webp"><img src="assets/features/handoffChat.webp" width="160" alt="Ảnh chụp màn hình: Tiếp tục trong cuộc trò chuyện mới"></a> |
70
+ | **Phân tích ngữ cảnh** | <a id="feature-contextbreakdown"></a>Thanh bên phải → `+` → **Ngữ cảnh**. Trang cho biết những gì đang chiếm ngữ cảnh mô hình của cuộc trò chuyện đang mở và lượng cửa sổ ngữ cảnh đã dùng: system prompt, hướng dẫn dự án (AGENTS.md), skill, tin nhắn của bạn, câu trả lời của tác tử và lệnh gọi công cụ, kết quả công cụ (theo từng công cụ), kết quả MCP (theo từng máy chủ), định nghĩa công cụ, bản tóm tắt nén và các ghi chú ngữ cảnh khác, mỗi mục kèm số token và tỷ lệ. Nhấp vào một phần để xem các công cụ hoặc máy chủ của phần đó. Trang chỉ đọc nhật ký cuộc trò chuyện, sau `/compact` và các lần hoàn tác, và không gọi mô hình nào; trang đọc lại sau mỗi lượt và khi nhấn **Làm mới**. Dùng trang này để xem vì sao một cuộc trò chuyện chậm hoặc đầy, ví dụ do một kết quả công cụ MCP lớn hoặc nhiều định nghĩa công cụ. | <a href="assets/features/contextBreakdown.webp"><img src="assets/features/contextBreakdown.webp" width="160" alt="Ảnh chụp màn hình: Phân tích ngữ cảnh"></a> |
71
+ | **Tệp được bảo vệ** | <a id="feature-protectedfiles"></a>Bật theo mặc định. Các công cụ tệp riêng của tác tử không thể đọc hoặc thay đổi các tệp khớp với mẫu của bạn: `read`, `read_image` và `grep` trên một tệp bị từ chối với mẫu **đọc và ghi**, còn `write`, `edit` và `str_replace_editor` bị từ chối với cả hai loại. Tác tử đọc lý do và được yêu cầu hỏi bạn. Mẫu mặc định là `.env*`, `*.pem` và `*.key`. Cài đặt → Composer Plus → **Tệp được bảo vệ**: thêm một mẫu (ví dụ `published/**` hoặc `config/*.yml`), nhấp vào loại của mẫu để chuyển giữa **đọc và ghi** và **chỉ ghi**, xóa mẫu bằng ✕, hoặc nhấp **Dùng giá trị mặc định**. Mẫu không có `/` khớp với tên tệp trong bất kỳ thư mục nào. Đây là rào chắn bảo vệ, không phải sandbox: lệnh shell (`cat .env`), script hoặc công cụ MCP vẫn có thể truy cập tệp (xem Giới hạn). | <a href="assets/features/protectedFiles.webp"><img src="assets/features/protectedFiles.webp" width="160" alt="Ảnh chụp màn hình: Tệp được bảo vệ"></a> |
72
+ | **Bộ nhớ dự án** | <a id="feature-projectmemory"></a>Mặc định tắt: hãy bật trong **Cài đặt → Composer Plus**. Mỗi thư mục dự án có bộ nhớ riêng, các cuộc trò chuyện sau này của dự án đó sẽ đọc, giống như DS Bot giữ một bộ nhớ cho mỗi Bot. Sau mỗi lượt kết thúc, một lần gọi mô hình của cuộc trò chuyện đọc các tin nhắn mới (không đọc tin nhắn đã hoàn tác), lưu sở thích, quyết định và dữ kiện lâu dài của bạn thành ghi chú ngắn, đồng thời sửa hoặc xóa ghi chú cũ. Tác tử cũng có thể tự lưu, xóa và tìm ghi chú (`memory_remember`, `memory_forget`, `memory_recall`). Ghi chú cũng có thể là ghi chú chung: mọi dự án đều đọc. Cuộc trò chuyện mới nhận các ghi chú trong system prompt; ghi chú lưu sau đó hiện từ cuộc trò chuyện tiếp theo. Các tệp là Markdown trong thư mục home của dsh (`storages/dsh-composer-plus/memory/`), không bao giờ nằm trong thư mục dự án. **Mở bộ nhớ** ở cùng hàng hiển thị mọi ghi chú đã lưu, nhóm theo dự án (và bộ nhớ chung), có bộ lọc. Viết bằng lời của bạn điều cần thay đổi (ví dụ "tôi đã chuyển từ yarn sang pnpm"), rồi bấm **Xem trước thay đổi**: mô hình mặc định của dsh đề xuất các thay đổi, và chỉ **Áp dụng** mới lưu chúng. Trong Tether: menu tiêu đề cuộc trò chuyện → Project memory. | <a href="assets/features/projectMemory.webp"><img src="assets/features/projectMemory.webp" width="160" alt="Ảnh chụp màn hình: Bộ nhớ dự án"></a> |
69
73
  | **Cho phép trong cuộc trò chuyện này** | <a id="feature-allowforchat"></a>Khi Đánh giá tự động hỏi bạn, thẻ phê duyệt có thêm nút **Cho phép trong cuộc trò chuyện này**: từ đó trở đi, cùng công cụ đó trong cùng cuộc trò chuyện được cho phép, với mọi đối số, cho đến khi hết giới hạn thời gian (mặc định 1 giờ; chọn trong **Cài đặt → Composer Plus → Cho phép trong cuộc trò chuyện này**). Sau đó, agent sẽ hỏi lại. Một nhãn nhỏ ở phần đầu liệt kê các quyền đã cấp kèm thời điểm kết thúc và cho phép thu hồi. Quyền vẫn còn sau khi khởi động lại. | <a href="assets/features/allowForChat.webp"><img src="assets/features/allowForChat.webp" width="160" alt="Ảnh chụp màn hình: Cho phép trong cuộc trò chuyện này"></a> |
70
74
  | **Trạng thái dự án** | <a id="feature-projectstatus"></a>Dòng dự án trên thanh bên hiện cùng dấu đang chạy / đang chờ / xong như các cuộc trò chuyện của nó. Vì vậy, dự án đã thu gọn vẫn cho bạn biết có cuộc trò chuyện bên trong đang làm việc hoặc cần bạn. Cuộc trò chuyện đang chờ bạn được hiện trước, sau đó là cuộc trò chuyện đã xong mà bạn chưa mở (chấm xanh, kể cả khi một cuộc trò chuyện khác vẫn đang chạy), rồi đến dấu đang chạy. Di chuột lên để xem chi tiết. Trong **Cây không gian làm việc**, dòng của thư mục cha cũng hiện các cuộc trò chuyện của từng dự án bên trong (ví dụ mỗi thư mục nhánh trong `.worktrees/`), kể cả khi thư mục đã thu gọn. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="Ảnh chụp màn hình: Trạng thái dự án"></a> |
71
- | **Branch Git trên dòng cuộc trò chuyện** | <a id="feature-sessionbranch"></a>Mỗi dòng cuộc trò chuyện ở thanh bên hiển thị một nhãn nhỏ màu xám với branch git mà thư mục dự án của cuộc trò chuyện đang ở trong lượt cuối của cuộc trò chuyện đó (ví dụ `main` hoặc `feature/login`; HEAD tách rời hiển thị ID commit ngắn trong ngoặc đơn). Hai cuộc trò chuyện của cùng một dự án trên các branch khác nhau không còn trông giống nhau, và bạn thấy ngay khi sắp tiếp tục một cuộc trò chuyện trên sai branch. Di chuột lên nhãn để xem tên đầy đủ. Phần Host đọc branch (`git branch --show-current`, chỉ đọc) khi một lượt bắt đầu và khi kết thúc; cuộc trò chuyện chưa có lượt nào kể từ khi bạn cài tính năng này, hoặc thư mục không phải repository git, sẽ không có nhãn. Nếu dòng dự án phía trên cuộc trò chuyện có cùng tên với branch (ví dụ thư mục của “Branch riêng cho từng cuộc trò chuyện”), dòng cuộc trò chuyện không hiển thị nhãn, nhưng “Trong một danh sách” vẫn hiển thị nhãn. | <a href="assets/features/sessionBranch.webp"><img src="assets/features/sessionBranch.webp" width="160" alt="Ảnh chụp màn hình: Branch Git trên dòng cuộc trò chuyện"></a> |
75
+ | **Branch Git trên dòng cuộc trò chuyện** | <a id="feature-sessionbranch"></a>Mỗi dòng cuộc trò chuyện ở thanh bên hiển thị một nhãn nhỏ màu xám với branch git mà thư mục dự án của cuộc trò chuyện đang ở trong lượt cuối của cuộc trò chuyện đó (ví dụ `main` hoặc `feature/login`; HEAD tách rời không có branch nên không hiển thị nhãn). Hai cuộc trò chuyện của cùng một dự án trên các branch khác nhau không còn trông giống nhau, và bạn thấy ngay khi sắp tiếp tục một cuộc trò chuyện trên sai branch. Di chuột lên nhãn để xem tên đầy đủ. Phần Host đọc branch (`git branch --show-current`, chỉ đọc) khi một lượt bắt đầu và khi kết thúc; cuộc trò chuyện chưa có lượt nào kể từ khi bạn cài tính năng này, hoặc thư mục không phải repository git, sẽ không có nhãn. Nếu dòng dự án phía trên cuộc trò chuyện có cùng tên với branch (ví dụ thư mục của “Branch riêng cho từng cuộc trò chuyện”), dòng cuộc trò chuyện không hiển thị nhãn, nhưng “Trong một danh sách” vẫn hiển thị nhãn. | <a href="assets/features/sessionBranch.webp"><img src="assets/features/sessionBranch.webp" width="160" alt="Ảnh chụp màn hình: Branch Git trên dòng cuộc trò chuyện"></a> |
72
76
  | **Đánh dấu tất cả là đã đọc** | <a id="feature-markprojectread"></a>Trên thanh bên, nhấp nút **…** của một dự án → **Đánh dấu tất cả là đã đọc**. Mọi cuộc trò chuyện trong dự án đó mất chấm xanh chưa đọc cùng lúc; các dự án khác vẫn giữ chấm của mình. Mục này hiện màu xám (**Không có cuộc trò chuyện chưa đọc**) khi dự án không có cuộc trò chuyện chưa đọc nào. | <a href="assets/features/markProjectRead.webp"><img src="assets/features/markProjectRead.webp" width="160" alt="Ảnh chụp màn hình: Đánh dấu tất cả là đã đọc"></a> |
73
77
  | **Ưu tiên dự án đang hoạt động** | <a id="feature-activeprojectsfirst"></a>Khi một cuộc trò chuyện bắt đầu chạy hoặc cần bạn, dự án của nó di chuyển lên đầu thanh bên với hiệu ứng dòng của chính dsh (giống như khi bạn kéo dự án lên đó). Dự án đã xong giữ nguyên vị trí; bạn vẫn kéo chúng đến bất kỳ đâu như thường. Các lần di chuyển được lưu vào thứ tự dự án của dsh, nên khi tắt tính năng này, thứ tự hiện tại được giữ nguyên. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="Ảnh chụp màn hình: Ưu tiên dự án đang hoạt động"></a> |
74
78
  | **Bộ lọc dự án gần đây** | <a id="feature-recentprojects"></a>Thanh bên → tùy chọn hiển thị (biểu tượng thanh trượt) → **Hoạt động trong 2 giờ qua**. Khi tùy chọn này được chọn, thanh bên chỉ hiện các dự án có cuộc trò chuyện hoạt động trong 2 giờ qua: cuộc trò chuyện được cập nhật trong khoảng thời gian này, cuộc trò chuyện đang chạy hoặc đang chờ, cuộc trò chuyện đang mở, hoặc cuộc trò chuyện đã xong mà bạn chưa mở (chấm xanh “xong” của dsh), kể cả sau 2 giờ. Các dự án không có cuộc trò chuyện như vậy bị ẩn, kể cả dự án mới và trống. Trong **Cây không gian làm việc**, thư mục cha vẫn hiển thị khi có dự án bên trong đang hoạt động, và các cuộc trò chuyện không hoạt động trong 2 giờ qua cũng bị ẩn, nên chỉ hiện các cuộc trò chuyện gần đây. Chọn lại tùy chọn để hiện tất cả dự án. Lựa chọn được lưu trên thiết bị này. | <a href="assets/features/recentProjects.webp"><img src="assets/features/recentProjects.webp" width="160" alt="Ảnh chụp màn hình: Bộ lọc dự án gần đây"></a> |
75
79
  | **Thu gọn tất cả dự án** | <a id="feature-collapseprojects"></a>Khi có dự án đang mở trên thanh bên, một nút xuất hiện cạnh tùy chọn hiển thị (biểu tượng thanh trượt). Nhấp vào nút để đóng mọi dự án đang mở cùng lúc, ví dụ 3 dự án đang mở trong số 5. Nút lại ẩn đi khi không còn dự án nào mở. | <a href="assets/features/collapseProjects.webp"><img src="assets/features/collapseProjects.webp" width="160" alt="Ảnh chụp màn hình: Thu gọn tất cả dự án"></a> |
76
80
  | **Sắp xếp theo trạng thái** | <a id="feature-statusorder"></a>Thanh bên → tùy chọn hiển thị → **Sắp xếp theo** → **Theo trạng thái** (cùng với **Trong một danh sách**). Các cuộc trò chuyện đã xong đứng đầu (chấm “xong” của dsh; lượt kết thúc do lỗi cũng có chấm này), sau đó là cuộc trò chuyện đang chạy hoặc đang chờ, rồi đến cuộc trò chuyện có tự động hóa đang hoạt động (Tác vụ tự động), cuối cùng là phần còn lại theo thứ tự của dsh. Khi bạn mở một cuộc trò chuyện đã xong, nó chuyển xuống dưới. Chỉ chế độ xem thay đổi: chọn **Thủ công** hoặc **Cập nhật gần nhất** để quay lại. | <a href="assets/features/statusOrder.webp"><img src="assets/features/statusOrder.webp" width="160" alt="Ảnh chụp màn hình: Sắp xếp theo trạng thái"></a> |
77
81
  | **Thông báo nền** | <a id="feature-notifications"></a>Khi dsh chạy nền, bạn nhận thông báo khi một lượt kết thúc (dòng đầu tiên của câu trả lời), hoặc khi một cuộc trò chuyện thật sự chờ bạn: một phê duyệt (tên công cụ), một câu trả lời (câu hỏi) hoặc một lần xem xét kế hoạch. Yêu cầu phải vẫn còn mở sau 1,5 giây, nên các phê duyệt được trả lời tự động (quyền của Đánh giá tự động, plugin khác) không gây thông báo. Thông báo bị thu hồi ngay khi yêu cầu của nó được trả lời. Huy hiệu trên Dock/thanh tác vụ đếm số cuộc trò chuyện đang chờ. Nhấp vào thông báo sẽ mở cuộc trò chuyện đó. | <a href="assets/features/notifications.webp"><img src="assets/features/notifications.webp" width="160" alt="Ảnh chụp màn hình: Thông báo nền"></a> |
78
- | **Mở cuộc trò chuyện đang chờ khi không hoạt động** | <a id="feature-idleswitch"></a>Khi một cuộc trò chuyện đặt câu hỏi hoặc đang chờ phê duyệt hay xem xét kế hoạch (chấm cam) và bạn không dùng dsh trong 30 giây, dsh sẽ mở cuộc trò chuyện đó. Khi có nhiều cuộc trò chuyện cùng chờ, cuộc chờ lâu nhất được mở trước; cuộc tiếp theo mở sau thêm 30 giây không dùng. Một phím, một cú nhấp, di chuột, con lăn hoặc một lần chạm sẽ bắt đầu lại 30 giây. Văn bản trong ô đang có tiêu điểm, văn bản đang chọn, hoặc một menu hay hộp thoại đang mở cũng ngăn việc chuyển. Khi một cuộc trò chuyện đang chờ ở trên màn hình, không có gì thay đổi. Nếu bạn rời một cuộc trò chuyện đang chờ mà chưa trả lời, nó có thể mở lại sau 30 giây không dùng tiếp theo. Tính năng cũng chạy khi dsh ở chế độ nền, nhưng dsh không được đưa lên trước. | <a href="assets/features/idleSwitch.webp"><img src="assets/features/idleSwitch.webp" width="160" alt="Ảnh chụp màn hình: Mở cuộc trò chuyện đang chờ khi không hoạt động"></a> |
82
+ | **Mở cuộc trò chuyện đang chờ khi không hoạt động** | <a id="feature-idleswitch"></a>Khi một cuộc trò chuyện đặt câu hỏi, đang chờ phê duyệt hay xem xét kế hoạch (chấm cam), hoặc hoàn tất một lượt mà bạn chưa đọc (chấm xanh), và bạn không dùng dsh trong 30 giây, dsh sẽ mở cuộc trò chuyện đó. Cuộc trò chuyện chấm cam được mở trước cuộc trò chuyện chấm xanh. Trong mỗi nhóm, cuộc chờ lâu nhất được mở trước; cuộc tiếp theo mở sau thêm 30 giây không dùng. Một phím, một cú nhấp, di chuột, con lăn hoặc một lần chạm sẽ bắt đầu lại 30 giây. Văn bản trong ô đang có tiêu điểm, văn bản đang chọn, hoặc một menu hay hộp thoại đang mở cũng ngăn việc chuyển. Khi một cuộc trò chuyện đang chờ ở trên màn hình, không có gì thay đổi. Nếu bạn rời một cuộc trò chuyện đang chờ mà chưa trả lời, nó có thể mở lại sau 30 giây không dùng tiếp theo. Khi một cuộc trò chuyện chấm xanh mở ra, chấm của nó biến mất; cuộc trò chuyện chấm xanh tiếp theo chỉ mở sau khi bạn dùng lại dsh rồi không dùng trong 30 giây. Tính năng cũng chạy khi dsh ở chế độ nền, nhưng dsh không được đưa lên trước. | <a href="assets/features/idleSwitch.webp"><img src="assets/features/idleSwitch.webp" width="160" alt="Ảnh chụp màn hình: Mở cuộc trò chuyện đang chờ khi không hoạt động"></a> |
79
83
  | **Ngôn ngữ ứng dụng** | <a id="feature-language"></a>Cài đặt → Composer Plus → **Ngôn ngữ ứng dụng** chuyển toàn bộ giao diện dsh sang Türkçe, Español, Português (Brasil), Français, Deutsch, Русский, 日本語, 한국어, Bahasa Indonesia, Tiếng Việt hoặc हिन्दी (xem bên dưới). | <a href="assets/features/language.webp"><img src="assets/features/language.webp" width="160" alt="Ảnh chụp màn hình: Ngôn ngữ ứng dụng"></a> |
80
84
  | **Kết nối di động (iPhone)** | <a id="feature-mobileconnect"></a>Dùng dsh từ iPhone với ứng dụng [Tether](tether/), trong cùng mạng Wi-Fi hoặc qua [Tailscale](https://tailscale.com). Bật tính năng trong **Cài đặt → Composer Plus** (mặc định tắt, vì tính năng này mở một cổng mạng trên máy Mac này). Sau đó nhấp **Kết nối di động** ở góc dưới bên trái thanh bên: quét mã QR bằng Camera của iPhone (chạm vào **Open in Tether**) hoặc bằng **Scan code** trong Tether, chạm vào **Connect** và nhấp **Approve**. Hãy cài đặt Tether trước: nếu không có Tether, Camera không thể mở mã này. Điện thoại hiện các cuộc trò chuyện của bạn, gửi tin nhắn (kèm ảnh: **+** trong khung soạn thảo → Camera, Photos hoặc Paste image), trả lời phê duyệt và câu hỏi, và chuyển đổi mô hình và agent. Bạn có thể ghép nối bao nhiêu máy Mac tùy ý: tên máy Mac ở góc trên bên trái ứng dụng dùng để chuyển giữa các máy. Bảng **Kết nối di động** liệt kê các iPhone đã ghép nối kèm lần kết nối gần nhất: **Remove** ngắt ngay một máy. “Tailscale only” từ chối mạng cục bộ (dành cho Wi-Fi dùng chung), và nhật ký truy cập cho biết ai đã thử kết nối. Trong Tether, “Settings → Privacy” khóa ứng dụng bằng Face ID. | <a href="assets/features/mobileConnect.webp"><img src="assets/features/mobileConnect.webp" width="160" alt="Ảnh chụp màn hình: Kết nối di động (iPhone)"></a> |
81
85
  | **Tự động cập nhật** | <a id="feature-autoupdate"></a>Khi dsh khởi động, plugin kiểm tra [bản phát hành GitHub mới nhất](https://github.com/furkancak1r/dsh-composer-plus/releases/latest). Nếu bản đó mới hơn và đã có trên npm, plugin cài đúng phiên bản đó qua trình quản lý plugin của chính dsh (cùng cách với Cài đặt → Plugin) và thông báo cho bạn. Khởi động lại dsh để tải bản mới. **Cài đặt → Composer Plus → Cập nhật Composer Plus** hiện phiên bản và có nút **Kiểm tra cập nhật** / **Cập nhật ngay**. Lần đầu dsh khởi động với phiên bản mới, cửa sổ **Có gì mới trong Composer Plus N** hiện ghi chú phát hành của phiên bản đó một lần (lấy từ chính lần kiểm tra cập nhật, không gọi mạng thêm); **Đóng** hoặc `Esc` đóng nó. | <a href="assets/features/autoUpdate.webp"><img src="assets/features/autoUpdate.webp" width="160" alt="Ảnh chụp màn hình: Tự động cập nhật"></a> |
@@ -160,7 +164,10 @@ Khi menu `/` hoặc `@` đang mở, menu đó giữ các phím này cho riêng n
160
164
  - **Hoàn thành khi gõ:** tắt cho đến khi bạn bật. Khi bật, mỗi lần bạn dừng gõ, phần Host gửi văn bản bạn đã gõ đến lúc đó cùng các tin nhắn của chính bạn trong cuộc trò chuyện và các câu trả lời dạng văn bản của tác tử (không có đầu ra công cụ, ngữ cảnh ẩn hay phần suy luận), tối đa khoảng 3.000 ký tự của cuộc trò chuyện, đến mô hình đã chọn trong **Hoàn thành khi gõ** (mặc định là mô hình của **Dự đoán tin nhắn tiếp theo**). Lần dừng gõ mới sẽ hủy yêu cầu trước đó. Không có gì được lưu vào cuộc trò chuyện. Công tắc nằm trong `$DSH_HOME/storages/dsh-composer-plus/complete.json` (tệp chỉ chủ sở hữu truy cập được).
161
165
  - **Cải thiện prompt:** không có gì chạy cho đến khi bạn nhấp vào đũa thần. Khi đó, phần Host gửi bản nháp của bạn, các tin nhắn của chính bạn trong cuộc trò chuyện và các câu trả lời dạng văn bản của tác tử (không có đầu ra công cụ, ngữ cảnh ẩn, phần suy luận hay tin nhắn đã bị hoàn tác; tối đa khoảng 6.000 ký tự, phần mới nhất), cùng bản tóm tắt dự án như **Ý tưởng tính năng** (với cùng quy tắc tệp: không có `.env*` hay tệp khóa, không có symlink trỏ ra ngoài thư mục, không có FIFO), các đường dẫn mà `git status` liệt kê là đã thay đổi và tối đa 30 đường dẫn được theo dõi hoặc chưa được theo dõi (không bị bỏ qua) có tên chứa từ trùng với bản nháp của bạn, đến mô hình đã chọn trong **Cải thiện prompt** (mặc định là mô hình của chính cuộc trò chuyện), dưới dạng một yêu cầu duy nhất. Ngoài bản tóm tắt đó, nội dung tệp không được gửi. Không có gì được ghi vào cuộc trò chuyện hay dự án: câu trả lời chỉ thay thế bản nháp của bạn trong khung soạn thảo, và bạn quyết định có gửi hay không. Mô hình đã chọn nằm trong `$DSH_HOME/storages/dsh-composer-plus/improve.json` (tệp chỉ chủ sở hữu truy cập được).
162
166
  - **Kiểm tra mục tiêu:** chỉ chạy khi tác tử đánh dấu một `/goal` là hoàn tất trong một vòng tự động (hoặc khi bạn nhấp **Chạy ngay**). Phần Host chạy lệnh kiểm thử trong thư mục của cuộc trò chuyện theo chế độ sandbox của cuộc trò chuyện (giống công cụ `bash` của chính dsh: cùng chính sách truy cập tệp; khi sandbox đó không khởi động được, bài kiểm thử không chạy và bước kiểm tra thất bại). Để tìm lệnh, phần Host chỉ đọc `package.json`, `Makefile`, `Cargo.toml`, `go.mod`, `pyproject.toml` và `pytest.ini`, dưới dạng tệp thông thường bên trong thư mục (không có symlink trỏ ra ngoài thư mục, không có FIFO). Sau đó phần Host gửi mục tiêu, cuộc trò chuyện kể từ khi mục tiêu bắt đầu (tin nhắn của bạn, câu trả lời của tác tử, các lệnh gọi công cụ cắt còn 1.000 ký tự và 2.000 ký tự cuối của mỗi kết quả công cụ; không có phần suy luận, không có bước đã bị hoàn tác; tối đa khoảng 60.000 ký tự, phần mới nhất), `git status --short` và phần cuối đầu ra kiểm thử đến mô hình đã chọn trong **Kiểm tra mục tiêu** (mặc định là mô hình của chính cuộc trò chuyện), dưới dạng một yêu cầu duy nhất không có công cụ. Đầu ra công cụ có thể chứa những gì tác tử đã đọc, nên yêu cầu này có thể chứa một phần tệp của bạn, giống như chính cuộc trò chuyện. Không có gì được ghi vào cuộc trò chuyện hay dự án. Lệnh kiểm thử của bạn, các giới hạn, kết quả gần nhất (kèm phần cuối đầu ra) và mô hình đã chọn nằm trong `$DSH_HOME/storages/dsh-composer-plus/goal-check.json` (tệp chỉ chủ sở hữu truy cập được, 500 cuộc trò chuyện mới nhất).
163
- - **Bộ nhớ dự án:** tắt cho đến khi bạn bật. Khi bật, sau mỗi lượt kết thúc của một cuộc trò chuyện cấp cao nhất, phần Host gửi các tin nhắn mới của chính cuộc trò chuyện đó kể từ lần xem xét trước (tin nhắn của bạn và câu trả lời dạng văn bản của tác tử; không có đầu ra công cụ, suy luận, ngữ cảnh ẩn hay tin nhắn đã hoàn tác; trong cuộc trò chuyện rẽ nhánh, bản sao từ cuộc trò chuyện cha bị bỏ qua; tối đa khoảng 16.000 ký tự) và các ghi chú đã lưu tới mô hình của chính cuộc trò chuyện, trong một yêu cầu không có công cụ. Ghi chú là các tệp Markdown trong `$DSH_HOME/storages/dsh-composer-plus/memory/` (chỉ chủ sở hữu đọc/ghi): `projects/<id>/` cho mỗi thư mục dự án (`<id>` là mã băm của đường dẫn thật của thư mục; `project.json` ghi tên thư mục), `global/`, `journal.jsonl` (mỗi thay đổi kèm dòng trước và sau) và `reviewed.json` (đã đọc mỗi cuộc trò chuyện đến đâu). Không có gì được ghi vào thư mục dự án. Ghi chú trông giống khóa, token, mật khẩu hoặc số giấy tờ tùy thân bị từ chối. Ghi chú của một dự án đi vào system prompt của mỗi cuộc trò chuyện mới trong thư mục đó, nên chúng tới mô hình cùng mọi yêu cầu của cuộc trò chuyện đó. Công tắc nằm trong `memory.json` ở cùng chỗ.
167
+ - **Tiếp tục trong cuộc trò chuyện mới:** không có gì chạy cho đến khi bạn nhấp. Sau đó phần Host gửi cuộc trò chuyện (như Kiểm tra mục tiêu đọc: không có phần suy luận, không có bước đã bị hoàn tác) đến mô hình của chính cuộc trò chuyện và hiện ghi chú bàn giao; chỉ **Bắt đầu cuộc trò chuyện mới** mới tạo cuộc trò chuyện mới. Không có gì được ghi vào dự án.
168
+ - **Phân tích ngữ cảnh:** phần Host chỉ đọc nhật ký cuộc trò chuyện; không gọi mô hình, không đọc tệp dự án.
169
+ - **Tệp được bảo vệ:** danh sách và công tắc nằm trong `$DSH_HOME/storages/dsh-composer-plus/protected-files.json` (tệp chỉ chủ sở hữu truy cập được). Bước kiểm tra chỉ đọc đường dẫn của mỗi lệnh gọi công cụ tệp (và đường dẫn thật của nó), không bao giờ đọc tệp.
170
+ - **Bộ nhớ dự án:** tắt cho đến khi bạn bật. Khi bật, sau mỗi lượt kết thúc của một cuộc trò chuyện cấp cao nhất, phần Host gửi các tin nhắn mới của chính cuộc trò chuyện đó kể từ lần xem xét trước (tin nhắn của bạn và câu trả lời dạng văn bản của tác tử; không có đầu ra công cụ, suy luận, ngữ cảnh ẩn hay tin nhắn đã hoàn tác; trong cuộc trò chuyện rẽ nhánh, bản sao từ cuộc trò chuyện cha bị bỏ qua; tối đa khoảng 16.000 ký tự) và các ghi chú đã lưu tới mô hình của chính cuộc trò chuyện, trong một yêu cầu không có công cụ. Ghi chú là các tệp Markdown trong `$DSH_HOME/storages/dsh-composer-plus/memory/` (chỉ chủ sở hữu đọc/ghi): `projects/<id>/` cho mỗi thư mục dự án (`<id>` là mã băm của đường dẫn thật của thư mục; `project.json` ghi tên thư mục), `global/`, `journal.jsonl` (mỗi thay đổi kèm dòng trước và sau) và `reviewed.json` (đã đọc mỗi cuộc trò chuyện đến đâu). Không có gì được ghi vào thư mục dự án. Ghi chú trông giống khóa, token, mật khẩu hoặc số giấy tờ tùy thân bị từ chối. Ghi chú của một dự án đi vào system prompt của mỗi cuộc trò chuyện mới trong thư mục đó, nên chúng tới mô hình cùng mọi yêu cầu của cuộc trò chuyện đó. Công tắc nằm trong `memory.json` ở cùng chỗ. **Mở bộ nhớ** không gửi gì cho đến khi bạn bấm **Xem trước thay đổi**; khi đó nó gửi các ghi chú đang hiển thị và văn bản của bạn tới mô hình mặc định của dsh, trong một yêu cầu không có công cụ. Các thay đổi chỉ được ghi khi **Áp dụng**, với `editor` trong nhật ký. Tether đọc và thay đổi ghi chú qua cùng một tuyến.
164
171
  - **Sao lưu:** không có gì rời khỏi máy của bạn. Tệp lưu trữ được ghi vào `~/Desktop/dsh-backups` (tệp chỉ chủ sở hữu truy cập được). Thông tin bí mật không có trong tệp lưu trữ: các tệp thông tin xác thực (`.credentials.yaml`, `.env`), tệp khóa (`.pem`, `.key`, `.p12`, `.pfx`) và giá trị của các cài đặt token, secret, password và khóa API trong các tệp yml được che; bản thật của chúng nằm trong `composer-plus-vault/<archive>/` ở cùng thư mục (chỉ chủ sở hữu truy cập được), chỉ trên máy tính này. **Cho máy tính khác** không sao chép vault: hãy nhập lại các thông tin bí mật đó ở máy kia. Nhật ký trò chuyện, cài đặt và phần còn lại của thư mục home của dsh nằm nguyên trong tệp lưu trữ: hãy giữ thư mục này riêng tư, như chính `$DSH_HOME`. Quá trình sao lưu đọc tệp bằng `O_NOFOLLOW | O_NONBLOCK`; symlink được lưu dưới dạng liên kết (không bao giờ đi theo), còn FIFO hoặc thiết bị bị bỏ qua. Công tắc và cài đặt của sao lưu tự động nằm trong `$DSH_HOME/storages/dsh-composer-plus/auto-backup.json`, công tắc của bảng điều khiển cứu hộ nằm trong `rescue-console.json`, và trong lúc dsh chạy, `running/host-<pid>.json` cho biết từng tiến trình dsh (bảng điều khiển cứu hộ đọc các tệp này để từ chối khôi phục).
165
172
  - **Bảng điều khiển cứu hộ:** một menu trong terminal; nó không mở cổng mạng nào. Khi khôi phục, nó chỉ ghi vào một thư mục mới bên cạnh thư mục home của dsh (tệp được ghi với `O_EXCL | O_NOFOLLOW`, symlink được tạo sau cùng và không bao giờ đi theo) và từ chối tệp lưu trữ có tên không an toàn (`..`, đường dẫn tuyệt đối), thiết bị hoặc FIFO, nhiều hơn một thư mục cấp cao nhất hoặc một mục nằm dưới liên kết.
166
173
 
@@ -182,7 +189,7 @@ Khi menu `/` hoặc `@` đang mở, menu đó giữ các phím này cho riêng n
182
189
  - **Dòng cuộc trò chuyện không có nhãn branch:** cuộc trò chuyện chưa có lượt nào kể từ khi bạn cài phiên bản này, thư mục của nó không phải repository git, hoặc **Branch Git trên dòng cuộc trò chuyện** đang tắt. Sau khi cập nhật, hãy khởi động lại dsh (phần Host ghi lại branch).
183
190
  - **Kiểm tra mục tiêu báo bài kiểm thử thoát với mã 127 hoặc "not found":** dsh khởi động từ Finder hoặc Dock có thể có PATH ngắn hơn terminal của bạn, nên không tìm thấy `npm`, `pnpm` hoặc `cargo`. Hãy khởi động dsh từ terminal, hoặc đặt lệnh kiểm thử của riêng bạn với đường dẫn đầy đủ trong **Kiểm tra mục tiêu** → **Sửa**. **Chạy ngay** hiện kết quả ngay lập tức.
184
191
  - **Mục tiêu không đóng và tác tử tiếp tục làm việc:** **Kiểm tra mục tiêu** đã tìm thấy một bài kiểm thử thất bại hoặc phần việc còn thiếu; dòng bên dưới mục tiêu cho biết lý do (di chuột lên kết quả để xem chi tiết). Hãy sửa nguyên nhân hoặc lệnh kiểm thử, hoặc tự hoàn tất mục tiêu bằng `/goal` hoặc thanh mục tiêu (việc này không được kiểm tra).
185
- - **Cài đặt thất bại ngay sau một bản phát hành:** thêm số phiên bản (`dsh-composer-plus@1.16.1`), xem ghi chú cài đặt ở trên.
192
+ - **Cài đặt thất bại ngay sau một bản phát hành:** thêm số phiên bản (`dsh-composer-plus@1.17.0`), xem ghi chú cài đặt ở trên.
186
193
  - **Sao lưu ngay báo "Một thao tác sao lưu khác đang chạy":** một thao tác đang chạy trong cửa sổ dsh khác hoặc trong bảng điều khiển cứu hộ (chúng dùng chung tệp khóa `.composer-plus.lock` trong thư mục sao lưu). Hãy chờ thao tác đó xong. Nếu không có thao tác nào đang chạy, khóa của tiến trình đã đóng sẽ được tiếp quản ở lần nhấp tiếp theo.
187
194
  - **Bảng điều khiển cứu hộ báo "dsh is running":** trước tiên hãy thoát dsh. Nếu dsh thật sự đã đóng, tệp được nêu trong thông báo là phần còn sót lại sau một sự cố: hãy xóa tệp đó rồi thử lại.
188
195
  - **Sau khi khôi phục, dsh không khởi động hoặc thiếu một plugin:** cần cài lại các gói plugin của profile. Bảng điều khiển cứu hộ đề nghị việc này sau khi khôi phục; hoặc chạy `pnpm install` trong từng thư mục dưới `$DSH_HOME/profiles/` mà nó liệt kê. Các thông tin bí mật không có trong vault (máy tính khác) phải được nhập lại: bảng điều khiển liệt kê chúng.
@@ -205,6 +212,7 @@ Khi menu `/` hoặc `@` đang mở, menu đó giữ các phím này cho riêng n
205
212
  - **Cho phép trong cuộc trò chuyện này** tính giới hạn thời gian từ lúc cấp quyền. Giới hạn thời gian mới áp dụng ngay cho các quyền đang có hiệu lực, nên một giới hạn ngắn hơn có thể kết thúc chúng ngay. Quyền từ phiên bản 1.12 trở về trước không có thời gian: sau khi cập nhật, agent sẽ hỏi lại một lần cho các công cụ đó.
206
213
  - **Giữ con trỏ trong khung soạn thảo** chỉ trả lại tiêu điểm sau một lệnh `/` hoặc một skill. Trong lúc dsh xử lý lệnh, khung soạn thảo ở chế độ chỉ đọc trong vài mili giây, nên các phím nhấn trong khoảng đó bị mất. Nếu menu `/` của dsh vẫn đang mở, `Enter` chọn dòng đang được tô sáng và không gửi.
207
214
  - **Vừa thẻ câu hỏi với cửa sổ** chỉ thay đổi thẻ câu hỏi của dsh, không thay đổi thẻ duyệt kế hoạch. Tính năng tìm thẻ qua mã đánh dấu của dsh (`data-question-key`, `data-question-scroll`); nếu một bản cập nhật dsh thay đổi mã đánh dấu đó, thẻ hiển thị như dsh vẽ. Chiều cao của thẻ theo cửa sổ, không theo cuộc trò chuyện: trong một cuộc trò chuyện ở bảng bên hẹp, một thẻ cao vẫn có thể vượt lên trên cuộc trò chuyện.
215
+ - **Vừa tiêu đề cuộc trò chuyện với cửa sổ** tìm tiêu đề cuộc trò chuyện của dsh qua các tên lớp do dsh tạo (`_titleRow`, `_titleCluster`, `_crumbs`, `_headerActions`, `_headerUtilities`), vì dsh không có điểm móc bố cục cho nó. Nếu bản cập nhật dsh đổi các tên này, tiêu đề hiển thị như dsh vẽ. Trong cột trò chuyện rất hẹp, tiêu đề có thể chiếm hai hoặc ba dòng, nên vùng phía trên tin nhắn thấp hơn.
208
216
  - **Kết nối di động** chỉ hoạt động trên macOS (dùng `en0`, `openssl`, `swift` và `dns-sd`). Tính năng dùng cố định cổng 19390 và 19391, nên trên mỗi máy Mac, mỗi lúc chỉ một dsh có thể chạy tính năng này (mỗi máy Mac là một mục trong danh sách Mac của điện thoại). Điện thoại chỉ nhận thông báo khi Tether đang mở hoặc vừa chuyển sang chạy nền (không có dịch vụ push). Tether chỉ gửi thông báo sau khi bạn bật "Settings → Notifications → Send notifications" trong Tether. Tùy chọn này tắt theo mặc định, và iOS hỏi quyền khi bạn bật nó. Ứng dụng iOS chưa có trên App Store: hãy build ứng dụng từ `tether/ios` bằng Xcode. "Tailscale only" vẫn cần máy Mac có địa chỉ Wi-Fi hoặc Ethernet (gateway chỉ khởi động khi có địa chỉ đó). Nhật ký truy cập là riêng cho từng máy Mac và chỉ giữ 200 lần thử mới nhất; một lần thử lặp lại trong vòng một phút sẽ tăng số đếm của cùng một dòng thêm một. Khóa ứng dụng của Tether không ẩn bản xem trước thông báo trên Màn hình khóa của iPhone: hãy tắt chúng trong Cài đặt của iOS. Chấm xanh trong Tether theo Mac: cuộc trò chuyện bạn mở trong dsh cũng mất chấm trên điện thoại. Cuộc trò chuyện bạn mở trong Tether chỉ mất chấm trên điện thoại. Chấm riêng của dsh trên Mac vẫn còn cho đến khi bạn mở cuộc trò chuyện đó trên Mac.
209
217
  - Liên kết phiên hoạt động bên trong cuộc trò chuyện; nhấp vào liên kết không mở cuộc trò chuyện. Liên kết tạo bằng **Sao chép liên kết tin nhắn** chỉ mở tin nhắn của nó trên dsh 0.2.1 trở lên, và chỉ từ một tin nhắn trong cuộc trò chuyện (dsh 0.2.0 không có quy tắc văn bản người dùng, nên ở đó liên kết vẫn được sao chép nhưng hiện dưới dạng văn bản thường). Tin nhắn mà một lần hoàn tác đã đưa ra, hoặc mà việc nén đã xóa khỏi lịch sử dsh tải, không thể hiển thị: khi đó liên kết sẽ báo như vậy. Các nút 🔗 gắn vào các dòng tin nhắn của dsh; nếu một bản cập nhật dsh thay đổi markup đó, các nút không hiện.
210
218
  - **Đánh dấu tất cả là đã đọc** thay đổi các chấm chưa đọc của chính dsh qua một phần của dsh không phải API công khai (danh sách `completionUnread` trong trạng thái phiên của dsh). Nếu một bản cập nhật dsh đổi tên phần này, mục không hiện. Mục được đặt trong menu "…" của dự án trong dsh, và menu này không có vị trí dành cho plugin; nếu dsh thay đổi menu đó, mục cũng không hiện.
@@ -219,7 +227,7 @@ Khi menu `/` hoặc `@` đang mở, menu đó giữ các phím này cho riêng n
219
227
  - **Branch riêng cho từng cuộc trò chuyện**: khi thư mục branch của một cuộc trò chuyện (`<project>/.worktrees/<name>`) bị xóa, ví dụ khi chính agent của cuộc trò chuyện gỡ worktree và xóa branch, bước tiếp theo của cuộc trò chuyện sẽ chuyển cuộc trò chuyện ra khỏi thư mục đó. Dự án của thư mục branch biến mất khỏi thanh bên, còn cuộc trò chuyện hiển thị dưới Chưa nhóm và vẫn mở. Trên dsh 0.2.1 trở lên, cuộc trò chuyện tiếp tục trong thư mục chính của dự án, và mô hình nhận được một ghi chú về thư mục mới. Trên dsh 0.2.0, cuộc trò chuyện vẫn giữ thư mục đã xóa: lệnh chạy ở đó sẽ lỗi cho đến khi bạn bắt đầu cuộc trò chuyện mới. Dự án của một branch đã xóa mà không cuộc trò chuyện nào dùng cũng biến mất khỏi thanh bên: Composer Plus kiểm tra các thư mục branch khi khởi động và mỗi 30 giây, kể cả khi không có bộ lọc thanh bên. Trong lúc một cuộc trò chuyện đang được chuyển, **Branch mới** trong cùng kho mã sẽ trả lời "hãy thử lại". Khi tắt công tắc, lỗi của chính dsh lại hiện ra ("working-directory: directory does not exist").
220
228
  - **Branch trong cây không gian làm việc** ghi vào git mà không cần nhấp: khi chuyển một cuộc trò chuyện, nó đưa thư mục dự án về branch trước đó (`git switch`) và thêm một worktree (`git worktree add`). Nó không bao giờ xóa branch, worktree hay tệp. dsh không thể đổi thư mục của một cuộc trò chuyện, nên cuộc trò chuyện được chuyển là một bản sao (fork của chính dsh, với id mới) và cuộc trò chuyện cũ được lưu trữ. Bản sao tiếp tục công việc đã dừng; lệnh gọi công cụ đang chạy khi branch xuất hiện kết thúc bằng một lời từ chối, và agent chạy lại nó trong thư mục mới. Mục tiêu của cuộc trò chuyện cũ không đi theo. Chỉ cuộc trò chuyện có thư mục là thư mục chính của kho mới được chuyển, và chỉ với branch mà nó đã tạo và chuyển sang trong lượt đó (`git switch -c`, `git checkout -b`): branch chỉ tạo bằng `git branch`, thư mục có thay đổi chưa commit, worktree được liên kết hoặc thư mục con đều không chuyển gì. Trong cây chỉ hiện các worktree nằm trực tiếp trong `<project>/.worktrees/` và có branch; worktree tách rời (detached) hoặc ở nơi khác thì không hiện. Bản sao chỉ tự mở khi cuộc trò chuyện của nó là cuộc trò chuyện đang mở (plugin đọc điều này từ hàng thanh bên của dsh); nếu không, nó nằm trong dự án của branch.
221
229
  - **Tìm trong cuộc trò chuyện** chỉ tìm trong những gì trang hiển thị: các tin nhắn và câu trả lời đã được tải (cuộn lên hoặc nhấp **Tải cũ hơn** để xem các tin cũ hơn), không tìm trong các bước công cụ đang đóng và không tìm trong văn bản bị thu gọn bên trong đầu ra của công cụ. Tính năng đếm tối đa 2.000 kết quả khớp (sau đó là "2000+"). Tính năng dùng API tô sáng của trình duyệt (Chromium 105 trở lên; ứng dụng máy tính có API này): trong trình duyệt cũ hơn, số đếm và việc di chuyển vẫn hoạt động nhưng không có màu. `Cmd+F` trên Mac (`Ctrl+F` trên Windows và Linux) chỉ mở tính năng khi có một cuộc trò chuyện trên màn hình; ở nơi khác, chức năng tìm của chính trình duyệt vẫn hoạt động như trước. Trên Mac, `Ctrl+F` vẫn giữ chức năng của macOS trong ô văn bản (con trỏ tiến lên một ký tự).
222
- - **Mở cuộc trò chuyện đang chờ khi không hoạt động** chỉ biết những gì cửa sổ dsh thấy: làm việc trong ứng dụng khác không được tính, nên khi dsh chạy nền, tính năng có thể mở một cuộc trò chuyện đang chờ sau 30 giây. dsh không được đưa lên trước. Chỉ đọc mà không bấm phím, nhấp hay di chuột được tính là không hoạt động. Tính năng chỉ xét các cuộc trò chuyện có chấm cam của dsh (câu hỏi, phê duyệt hoặc xem xét kế hoạch); yêu cầu của subagent hiện trong cuộc trò chuyện cha của nó. Khi một cuộc trò chuyện đang chờ ở trên màn hình, không mở cuộc khác; cuộc trò chuyện bạn rời đi mà chưa trả lời có thể mở lại sau 30 giây không dùng tiếp theo. Không thể thay đổi 30 giây.
230
+ - **Mở cuộc trò chuyện đang chờ khi không hoạt động** chỉ biết những gì cửa sổ dsh thấy: làm việc trong ứng dụng khác không được tính, nên khi dsh chạy nền, tính năng có thể mở một cuộc trò chuyện đang chờ sau 30 giây. dsh không được đưa lên trước. Chỉ đọc mà không bấm phím, nhấp hay di chuột được tính là không hoạt động. Tính năng chỉ xét các cuộc trò chuyện có chấm cam của dsh (câu hỏi, phê duyệt hoặc xem xét kế hoạch) hoặc chấm xanh (một lượt đã xong mà bạn chưa mở); yêu cầu của subagent hiện trong cuộc trò chuyện cha của nó. Cuộc trò chuyện chấm cam được mở trước. Mở một cuộc trò chuyện chấm xanh sẽ xóa chấm của nó, nên 30 giây của cuộc trò chuyện chấm xanh tiếp theo chỉ bắt đầu sau lần bấm phím, nhấp, di chuột, cuộn con lăn hoặc chạm tiếp theo của bạn: khi bạn quay lại, các chấm xanh khác vẫn còn. Khi một cuộc trò chuyện đang chờ ở trên màn hình, không mở cuộc khác; cuộc trò chuyện bạn rời đi mà chưa trả lời có thể mở lại sau 30 giây không dùng tiếp theo. Không thể thay đổi 30 giây.
223
231
  - Nhấp vào thông báo đã gửi trước khi khởi động lại chỉ đưa dsh ra phía trước.
224
232
  - Dự án đang hoạt động được di chuyển bằng thứ tự dự án đã lưu của dsh, nên thứ tự mới vẫn được giữ sau khi khởi động lại. Không thể di chuyển cuộc trò chuyện nằm ngoài mọi dự án ("Chưa nhóm"); dsh luôn liệt kê chúng ở cuối.
225
233
  - dsh không có điểm mở rộng trong menu tùy chọn hiển thị của thanh bên, nên tùy chọn dự án gần đây được thêm vào chính menu của dsh. Nếu một bản cập nhật dsh thay đổi menu đó, tùy chọn không hiện và mọi dự án vẫn hiển thị. Bộ lọc hoạt động trên các dòng dự án, nên **Trong một danh sách** không bị lọc. Trong **Cây không gian làm việc**, thư mục cha vẫn hiển thị khi có một dự án bên trong đang hoạt động, và các dòng trò chuyện không hoạt động trong 2 giờ qua cũng bị ẩn; trong **Không gian làm việc**, chỉ các dòng dự án được lọc. Bộ lọc đọc chế độ xem hiện tại của dsh từ cài đặt chế độ xem mà dsh lưu (không phải API công khai); nếu một bản cập nhật dsh đổi tên cài đặt đó, **Cây không gian làm việc** được lọc như **Không gian làm việc**. Trạng thái dự án đọc cùng cài đặt đó: trong **Cây không gian làm việc**, dòng của thư mục cha cũng tính các cuộc trò chuyện của các dự án bên trong; nếu dsh đổi tên cài đặt, mỗi dòng chỉ hiện các cuộc trò chuyện của chính nó. **Theo trạng thái** có giới hạn tương tự: dsh không có vị trí dành cho kiểu sắp xếp, nên mục này và thứ tự dòng gắn vào markup menu và danh sách của dsh.
@@ -228,10 +236,13 @@ Khi menu `/` hoặc `@` đang mở, menu đó giữ các phím này cho riêng n
228
236
  - dsh cũng không có điểm mở rộng để chọn nơi **Phiên mới** mở. **Không gian làm việc mặc định cho Phiên mới** bọc một phương thức của dsh không phải API công khai (`startSession` của dịch vụ không gian làm việc của dsh). Nếu một bản cập nhật dsh đổi tên nó, **Phiên mới** sẽ mở ở nơi dsh chọn (dự án đang mở hoặc gần nhất). Mọi lệnh gọi không chỉ định dự án đều dùng mặc định: nút trên thanh bên, phím tắt của nút, logo và cả **Mới** trên trang **Tác vụ tự động**. dsh vẫn mở cuộc trò chuyện cuối cùng khi khởi động. Thư mục chung được tạo và thêm vào dự án của bạn ở lần dùng đầu tiên; trên Windows hoặc Linux có thư mục Documents đã di chuyển, thư mục này có thể khác thư mục của dsh.
229
237
  - dsh cũng không có điểm mở rộng cho gợi ý trong khung soạn thảo, nên văn bản của **Dự đoán tin nhắn tiếp theo** nằm đè lên văn bản giữ chỗ của chính dsh (`[data-composer-placeholder]`). Nếu một bản cập nhật dsh thay đổi markup đó, dự đoán sẽ không hiện. Khi tính năng đang bật, mỗi lượt đã xong tốn một lần gọi mô hình ngắn.
230
238
  - **Hoàn thành khi gõ** hiện văn bản qua gợi ý khung soạn thảo của chính dsh (kiểu `--dsh-composer-hint` mà dsh dùng cho gợi ý đối số của lệnh gạch chéo). Tính năng không chạy với lệnh gạch chéo, tin nhắn có nhãn tệp hoặc nhãn ký hiệu, hoặc khi con trỏ không ở cuối tin nhắn. Nếu một bản cập nhật dsh thay đổi kiểu đó, phần hoàn thành sẽ không hiện. Mỗi lần bạn dừng gõ tốn một lần gọi mô hình.
231
- - **Cải thiện prompt** chỉ thấy bản tóm tắt ngắn về dự án, các đường dẫn đã thay đổi và các đường dẫn có tên khớp với từ ngữ của bạn: không thấy chính mã nguồn. Vì vậy tính năng có thể bỏ sót đúng tệp cần dùng, và chỉ nêu những đường dẫn được cung cấp. Hãy đọc văn bản mới trước khi gửi. Tính năng không chạy với lệnh gạch chéo hoặc tin nhắn có nhãn tệp hoặc nhãn ký hiệu (văn bản mới là văn bản thuần, nên sẽ mất nhãn), và một tin nhắn có tối đa 8.000 ký tự. Hình ảnh vẫn được đính kèm: chỉ văn bản thay đổi. Mỗi lần nhấp tốn một lần gọi mô hình; một mô hình mạnh có thể mất một phút (`Esc` để hủy).
232
- - **Kiểm tra mục tiêu** chỉ kiểm tra lần hoàn tất mà tác tử thực hiện trong một vòng mục tiêu tự động: lần hoàn tất mà bạn yêu cầu trong cuộc trò chuyện, `/goal` và thanh mục tiêu không được kiểm tra. Tác tử có thể tự thay đổi các bài kiểm thử hoặc các tệp của lệnh kiểm thử; bộ xác minh đọc cuộc trò chuyện và có thể thấy điều đó, nhưng có thể sai theo cả hai hướng (một kết quả "chưa xong" sai tốn thêm một vòng; một kết quả "đã xong" sai đóng mục tiêu). Bộ xác minh thấy cuộc trò chuyện và `git status`, không thấy chính mã nguồn. Một lần chạy kiểm thử chỉ được dùng lại khi bước mới nhất có thể thay đổi tệp của tác tử là lần chạy `bash` đạt của chính tác tử với đúng cùng một lệnh trong cùng thư mục; lệnh có pipe (`| tail`) hoặc `&&` không được dùng lại. Ngân sách được đo khi một lượt kết thúc, nên một lượt có thể vượt quá ngân sách. Chỉ tính các lần gọi mô hình của chính cuộc trò chuyện (không tính của các subagent). `update_goal` chờ trong khi bước kiểm tra chạy (bài kiểm thử tối đa 15 phút, bộ xác minh tối đa 3 phút). Cuộc trò chuyện tách nhánh nhận một id cuộc trò chuyện mới, nên bắt đầu mà không có lệnh kiểm thử và các giới hạn riêng của cuộc trò chuyện gốc. Mỗi lần hoàn tất đi đến bộ xác minh tốn một lần gọi mô hình.
239
+ - **Cải thiện prompt** chỉ thấy bản tóm tắt ngắn về dự án, các đường dẫn đã thay đổi và các đường dẫn có tên khớp với từ ngữ của bạn: không thấy chính mã nguồn. Vì vậy tính năng có thể bỏ sót đúng tệp cần dùng, và chỉ nêu những đường dẫn được cung cấp. Hãy đọc văn bản mới trước khi gửi. Tính năng không chạy với lệnh gạch chéo khác `/goal <mục tiêu>`, với từ điều khiển của `/goal` (`clear`, `pause`, `resume`) hoặc tin nhắn có nhãn tệp hoặc nhãn ký hiệu (văn bản mới là văn bản thuần, nên sẽ mất nhãn), và một tin nhắn có tối đa 8.000 ký tự. Với một mục tiêu `/goal`, tính năng chỉ viết điều kiện từ bản nháp và ngữ cảnh; một điều kiện quá chặt có thể tốn thêm vòng mục tiêu, nên hãy đọc điều kiện trước khi gửi. Hình ảnh vẫn được đính kèm: chỉ văn bản thay đổi. Mỗi lần nhấp tốn một lần gọi mô hình; một mô hình mạnh có thể mất một phút (`Esc` để hủy).
240
+ - **Kiểm tra mục tiêu** chỉ kiểm tra lần hoàn tất mà tác tử thực hiện trong một vòng mục tiêu tự động: lần hoàn tất mà bạn yêu cầu trong cuộc trò chuyện, `/goal` và thanh mục tiêu không được kiểm tra. Tác tử có thể tự thay đổi các bài kiểm thử hoặc các tệp của lệnh kiểm thử; bộ xác minh đọc cuộc trò chuyện và có thể thấy điều đó, nhưng có thể sai theo cả hai hướng (một kết quả "chưa xong" sai tốn thêm một vòng; một kết quả "đã xong" sai đóng mục tiêu). Bộ xác minh thấy cuộc trò chuyện và `git status`, không thấy chính mã nguồn. Một lần chạy kiểm thử chỉ được dùng lại khi bước mới nhất có thể thay đổi tệp của tác tử là lần chạy `bash` đạt của chính tác tử với đúng cùng một lệnh trong cùng thư mục; lệnh có pipe (`| tail`) hoặc `&&` không được dùng lại. Ngân sách được đo khi một lượt kết thúc, nên một lượt có thể vượt quá ngân sách. Ngân sách token cũng tính các lần gọi của các cuộc trò chuyện subagent của cuộc trò chuyện (đọc từ nhật ký đã lưu của chúng ở cuối mỗi lượt, nên một cuộc trò chuyện có nhiều subagent cần lâu hơn một chút để kiểm tra). Bảng bằng chứng đến từ việc bộ xác minh tự đọc cuộc trò chuyện: một phần mà bộ xác minh gọi là đã xác minh vẫn cần bạn tự xem lại khi phần đó quan trọng. `update_goal` chờ trong khi bước kiểm tra chạy (bài kiểm thử tối đa 15 phút, bộ xác minh tối đa 3 phút). Cuộc trò chuyện tách nhánh nhận một id cuộc trò chuyện mới, nên bắt đầu mà không có lệnh kiểm thử và các giới hạn riêng của cuộc trò chuyện gốc. Mỗi lần hoàn tất đi đến bộ xác minh tốn một lần gọi mô hình.
241
+ - **Tệp được bảo vệ** là rào chắn bảo vệ, không phải sandbox. Tính năng bao gồm các công cụ tệp của chính dsh (`read`, `read_image`, `grep` trên một tệp, `write`, `edit`, `str_replace_editor`). Một lệnh shell (`cat .env`), một script mà tác tử viết, shell của một subagent, một công cụ MCP, một danh sách `glob` và một lệnh `grep` trên cả thư mục vẫn có thể truy cập tệp được bảo vệ. Để có giới hạn thật, hãy dùng các chế độ sandbox của dsh hoặc giữ bí mật bên ngoài thư mục dự án. Mẫu hiểu `*`, `**` và `?`, không hiểu `{a,b}` hoặc `[ab]`, và không phân biệt chữ hoa/thường.
242
+ - **Tiếp tục trong cuộc trò chuyện mới** gửi cuộc trò chuyện (tin nhắn, lệnh gọi công cụ và phần cuối của mỗi kết quả công cụ, tối đa khoảng 60.000 ký tự, phần mới nhất) đến mô hình của chính cuộc trò chuyện. Ghi chú bàn giao có thể bỏ sót một quyết định hoặc một tệp: hãy đọc ghi chú trước khi bắt đầu. Cuộc trò chuyện mới chỉ biết ghi chú và cuộc trò chuyện được liên kết (dsh đính kèm cuộc trò chuyện cũ làm ngữ cảnh chỉ đọc); ngữ cảnh mô hình của nó bắt đầu nhỏ, cuộc trò chuyện cũ vẫn giữ nguyên. Mỗi cuộc trò chuyện chỉ có một lần viết ghi chú hoặc bắt đầu tại một thời điểm.
243
+ - **Phân tích ngữ cảnh** hiện số ước tính theo quy tắc của chính dsh (khoảng 4 ký tự cho mỗi token), cùng quy tắc với vòng ngữ cảnh của dsh; số đếm của chính mô hình có thể khác. Định nghĩa công cụ là định nghĩa của yêu cầu mới nhất. Tính năng hiện ngữ cảnh như nhật ký cuộc trò chuyện ghi lại; một lượt đang chạy xuất hiện sau bước tiếp theo của lượt đó.
233
244
  - **Ưu tiên tin nhắn gửi sau khi Dừng** chỉ hoạt động sau khi bạn dừng cuộc trò chuyện (hoặc sau một lượt bị lỗi, hoặc khi bạn mở một cuộc trò chuyện vẫn còn hàng đợi): tin nhắn bạn gửi khi một lượt đang chạy vẫn chờ ở cuối hàng đợi. Nó chỉ vượt lên trước các tin nhắn của chính bạn trong hàng đợi: nếu trong hàng đợi có một vòng mục tiêu hoặc một câu trả lời cho câu hỏi đang chờ, thứ tự của dsh được giữ nguyên. Nó đọc một phần của dsh không phải là API công khai (lượt đã dừng có còn đang kết thúc không); nếu một bản cập nhật dsh đổi tên phần đó, tin nhắn chỉ được đưa lên đầu sau khi lượt đó kết thúc. Cuộc trò chuyện của subagent giữ thứ tự của dsh.
234
- - **Bộ nhớ dự án** thuộc về thư mục đầu tiên của cuộc trò chuyện (thư mục dự án của dsh): cuộc trò chuyện đổi thư mục bằng `cd` vẫn giữ bộ nhớ của dự án đầu tiên, và cùng thư mục được mở qua một đường dẫn khác tới cùng các tệp sẽ dùng chung bộ nhớ. Cuộc trò chuyện cố định phần bộ nhớ khi bắt đầu, nên ghi chú lưu sau đó hiện từ cuộc trò chuyện tiếp theo (`memory_recall` tìm thấy ngay). Việc xem xét chỉ giữ những gì mô hình quyết định giữ: có thể bỏ sót một dữ kiện hoặc giữ một dữ kiện sai; hãy mở các tệp để kiểm tra, và sửa hoặc xóa bằng tay khi dsh đã đóng. Mỗi lượt kết thúc có tin nhắn của bạn tốn một lần gọi mô hình; lần gọi thất bại sẽ đọc lại cùng các tin nhắn sau lượt tiếp theo. Cuộc trò chuyện của tác tử con không được xem xét. Ý tưởng và định dạng tệp lấy từ [DS Bot](https://github.com/Fei2411/DS-Bot) (Apache-2.0); Composer Plus không dùng mã của nó và không bao giờ đọc hay ghi bộ nhớ riêng của DS Bot.
245
+ - **Bộ nhớ dự án** thuộc về thư mục đầu tiên của cuộc trò chuyện (thư mục dự án của dsh): cuộc trò chuyện đổi thư mục bằng `cd` vẫn giữ bộ nhớ của dự án đầu tiên, và cùng thư mục được mở qua một đường dẫn khác tới cùng các tệp sẽ dùng chung bộ nhớ. Cuộc trò chuyện cố định phần bộ nhớ khi bắt đầu, nên ghi chú lưu sau đó hiện từ cuộc trò chuyện tiếp theo (`memory_recall` tìm thấy ngay). Việc xem xét chỉ giữ những gì mô hình quyết định giữ: có thể bỏ sót một dữ kiện hoặc giữ một dữ kiện sai; hãy kiểm tra trong **Mở bộ nhớ** và sửa ở đó, hoặc sửa các tệp bằng tay khi dsh đã đóng. **Mở bộ nhớ** gửi ghi chú của dự án được chọn và ghi chú chung (mọi dự án khi bạn chọn Tất cả ghi chú; tối đa khoảng 60.000 ký tự, phần còn lại chỉ được đếm và không thể thay đổi trong yêu cầu đó) cùng văn bản của bạn tới mô hình mặc định của dsh, không phải mô hình của cuộc trò chuyện. Bản xem trước được giữ trên Mac trong 30 phút và cho đến khi dsh khởi động lại; nếu việc xem xét hoặc tác tử thay đổi ghi chú trong lúc đó, **Áp dụng** sẽ từ chối và bạn xem trước lại. **Áp dụng** lưu tất cả thay đổi của một bản xem trước hoặc không lưu gì: nếu một thay đổi không lưu được (ví dụ MEMORY.md đã đầy), ghi chú giữ nguyên và lý do được hiển thị. Mỗi lượt kết thúc có tin nhắn của bạn tốn một lần gọi mô hình; lần gọi thất bại sẽ đọc lại cùng các tin nhắn sau lượt tiếp theo. Cuộc trò chuyện của tác tử con không được xem xét. Ý tưởng và định dạng tệp lấy từ [DS Bot](https://github.com/Fei2411/DS-Bot) (Apache-2.0); Composer Plus không dùng mã của nó và không bao giờ đọc hay ghi bộ nhớ riêng của DS Bot.
235
246
  - **Sao lưu** dùng một thư mục cố định duy nhất, `~/Desktop/dsh-backups` (thư mục mặc định của dsh-backup, nên các tệp lưu trữ của nó vẫn dùng được); không có cài đặt cho thư mục khác. Một tệp lưu trữ lớn gần bằng thư mục home của dsh khi không tính `cache/` và `dsh-runtimes/` (đo thực tế: 1,6 GB tệp tạo ra tệp lưu trữ 830 MB trong khoảng 30 giây trên Apple Silicon; dsh vẫn phản hồi bình thường). Một tệp thay đổi trong lúc được đọc sẽ được lưu ở trạng thái lúc quá trình sao lưu mở nó, nên nhật ký của một cuộc trò chuyện đang mở có thể kết thúc bằng một bản ghi bị cắt, và dsh sửa bản ghi đó ở lần ghi tiếp theo. Việc che tìm thông tin bí mật trong tệp yml theo tên khóa trên một dòng (`token:`, `apiKey:`, …); thông tin bí mật trong flow map (`{token: x}`), trong một danh sách dưới khóa như vậy, trong tệp JSON (ví dụ `apiKey` của một máy chủ MCP trong tệp `.json`) hoặc dưới tên khác vẫn nằm trong tệp lưu trữ. Các tệp lưu trữ theo loại của dsh-backup (`dsh-t-…`) không được liệt kê. **Cho máy tính khác** sao chép tệp lưu trữ (trên APFS là bản clone: không tốn thêm dung lượng); vault không đi kèm. **Sao lưu ngay** không xóa bản sao lưu nào. Một lần sao lưu tự động giữ các bản sao lưu mới nhất do Composer Plus tạo (cài đặt **Giữ** của **Tự động sao lưu**) và xóa các bản cũ hơn do nó tạo; các snapshot trước khi nâng cấp được đếm riêng (giữ lại 2 bản mới nhất). Các tệp lưu trữ của dsh-backup không bao giờ bị xóa: hãy xóa chúng bằng **Xóa**. Khi dsh-backup vẫn còn được cài, nó tính các tệp lưu trữ của Composer Plus vào số bản giữ lại của riêng nó và có thể xóa chúng.
236
247
  - **Khôi phục** chỉ chạy trong bảng điều khiển cứu hộ, khi dsh đã đóng: nó thay toàn bộ thư mục home của dsh. Thư mục cũ vẫn nằm bên cạnh dưới tên `.dsh.pre-restore-<time>` cho đến khi bạn xóa, nên ổ đĩa cần đủ chỗ cho cả hai. Các cuộc trò chuyện giữ nguyên đường dẫn dự án: trên máy tính khác, một dự án ở đường dẫn khác sẽ hiện là bị thiếu cho đến khi bạn thêm lại. Các symlink trỏ ra ngoài thư mục home của dsh (ví dụ skill được liên kết từ thư mục khác) được khôi phục dưới dạng liên kết; đích của chúng phải có trên máy tính đó.
237
248
  - **Kiểm tra sức khỏe nhật ký phiên** đọc nhật ký mới nhất của mỗi cuộc trò chuyện theo chính các quy tắc của dsh về những gì mở được: một dòng không phải JSON hoặc sai thứ tự chỉ được tính là hỏng khi sau nó có một lần kết thúc lượt (nếu không, dsh mở cuộc trò chuyện mà không có các dòng từ chỗ đó trở đi, nên cuộc trò chuyện không được liệt kê). Nó không đối chiếu các sự kiện trong nhật ký với quy tắc sự kiện của chính dsh, nên một nhật ký mà nó coi là còn tốt vẫn có thể không mở được sau khi nâng cấp dsh. Việc sửa lấy bản sao từ một bản sao lưu: các tin nhắn sau bản sao lưu đó bị mất khỏi cuộc trò chuyện (tệp bị hỏng vẫn nằm bên cạnh). Một cuộc trò chuyện đang mở trong dsh này không được sửa trong Cài đặt: dsh đang giữ nó.
@@ -264,7 +275,7 @@ Khi menu `/` hoặc `@` đang mở, menu đó giữ các phím này cho riêng n
264
275
 
265
276
  **Có thể khiến tác tử thôi tự đánh dấu công việc của mình là đã xong, giống các vòng lặp xác minh trong loop engineering không?** Có, với **Kiểm tra mục tiêu** (mặc định bật): bắt đầu một mục tiêu bằng `/goal`. Khi tác tử nói mục tiêu đã hoàn tất, các bài kiểm thử của dự án chạy và một lần gọi mô hình độc lập đối chiếu mục tiêu với cuộc trò chuyện; nếu một trong hai không đạt, mục tiêu vẫn mở và tác tử đọc lý do. Đặt lệnh kiểm thử của riêng bạn, giới hạn thời gian hoặc giới hạn token bằng **Sửa** trong dòng **Kiểm tra mục tiêu** bên dưới mục tiêu.
266
277
 
267
- **Tác tử có thể nhớ sở thích của tôi giữa các cuộc trò chuyện, như bộ nhớ của DS Bot không?** Có, với **Bộ nhớ dự án** (mặc định tắt): hãy bật trong **Cài đặt → Composer Plus**. Sau mỗi lượt, sở thích và quyết định lâu dài của bạn được lưu thành ghi chú ngắn cho dự án của cuộc trò chuyện, và mọi cuộc trò chuyện mới trong dự án đó đều đọc chúng. Hãy bảo tác tử nhớ một điều, nó sẽ lưu ngay.
278
+ **Tác tử có thể nhớ sở thích của tôi giữa các cuộc trò chuyện, như bộ nhớ của DS Bot không?** Có, với **Bộ nhớ dự án** (mặc định tắt): hãy bật trong **Cài đặt → Composer Plus**. Sau mỗi lượt, sở thích và quyết định lâu dài của bạn được lưu thành ghi chú ngắn cho dự án của cuộc trò chuyện, và mọi cuộc trò chuyện mới trong dự án đó đều đọc chúng. Hãy bảo tác tử nhớ một điều, nó sẽ lưu ngay. Để xem hoặc thay đổi ghi chú, bấm **Mở bộ nhớ** ở cùng hàng và viết điều cần thay đổi.
268
279
 
269
280
  **dsh có thể sao lưu các cuộc trò chuyện và cài đặt của tôi như dsh-backup không?** Có: **Cài đặt → Composer Plus → Sao lưu → Sao lưu ngay**. Nó ghi cùng định dạng tệp lưu trữ vào cùng thư mục (`~/Desktop/dsh-backups`), nên các tệp lưu trữ của dsh-backup cũng hiện ra và khôi phục được, và bạn có thể gỡ dsh-backup. Bật **Tự động sao lưu** để sao lưu theo lịch.
270
281
 
@@ -304,7 +315,7 @@ Khi menu `/` hoặc `@` đang mở, menu đó giữ các phím này cho riêng n
304
315
 
305
316
  **Làm sao để nhận thông báo macOS / Windows khi một tác vụ dsh xong hoặc cần phê duyệt?** Giữ **Thông báo nền** ở trạng thái bật (mặc định) và cho phép DeepSeek Harness gửi thông báo trong cài đặt của hệ điều hành.
306
317
 
307
- **dsh có thể tự mở cuộc trò chuyện đang hỏi tôi không?** Có, với **Mở cuộc trò chuyện đang chờ khi không hoạt động** (bật theo mặc định): khi một cuộc trò chuyện chờ câu trả lời, phê duyệt hoặc xem xét kế hoạch và bạn không dùng dsh trong 30 giây, dsh sẽ mở nó. Khi bạn đang gõ, cuộn hoặc di chuột, tính năng sẽ chờ.
318
+ **dsh có thể tự mở cuộc trò chuyện đang hỏi tôi không?** Có, với **Mở cuộc trò chuyện đang chờ khi không hoạt động** (bật theo mặc định): khi một cuộc trò chuyện chờ câu trả lời, phê duyệt hoặc xem xét kế hoạch và bạn không dùng dsh trong 30 giây, dsh sẽ mở nó. Cuộc trò chuyện đã hoàn tất một lượt mà bạn chưa đọc (chấm xanh) cũng mở theo cách đó, sau các cuộc chấm cam. Khi bạn đang gõ, cuộn hoặc di chuột, tính năng sẽ chờ.
308
319
 
309
320
  **Làm sao để chuyển giao diện DeepSeek Harness sang tiếng Thổ Nhĩ Kỳ, tiếng Tây Ban Nha, tiếng Nhật…?** Cài đặt → Composer Plus → **Ngôn ngữ ứng dụng**.
310
321
 
@@ -343,6 +354,8 @@ PLAYWRIGHT=/path/to/playwright node test/browser-readme-anchors.mjs
343
354
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-keep-focus.mjs /path/to/dsh/lib/bin.js
344
355
  # Fit question card to window (fake model asks a long question at 1280 × 820): question, answers, Skip and Submit readable, height follows the window + its thumbnail
345
356
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-question-fit.mjs /path/to/dsh/lib/bin.js
357
+ # Fit chat header to window (fake model, subagent + background jobs, branch pill, grants chip): no overlap from 1280 to 320 px, wide header unchanged + its thumbnail
358
+ SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-header-fit.mjs /path/to/dsh/lib/bin.js
346
359
  # Mobile connect: switch on, QR popover, a fake iPhone pairs and calls dsh through the gateway, switch off + its thumbnail
347
360
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-mobile-connect.mjs /path/to/dsh/lib/bin.js
348
361
  # Resume after restart (fake slow model, real quit and start): a running chat and a goal continue, a stopped chat does not
package/README.zh.md CHANGED
@@ -29,7 +29,7 @@ dsh plugin --profile web add dsh-composer-plus
29
29
 
30
30
  然后重启 dsh。(CLI 无法安装到桌面版 profile 中;桌面版 profile 由应用自己管理。)
31
31
 
32
- > dsh 使用的 pnpm 会跳过发布不到 24 小时的版本。刚发布新版本时,请加上版本号:`dsh-composer-plus@1.16.1`。
32
+ > dsh 使用的 pnpm 会跳过发布不到 24 小时的版本。刚发布新版本时,请加上版本号:`dsh-composer-plus@1.17.0`。
33
33
 
34
34
  ## 功能
35
35
 
@@ -47,6 +47,7 @@ dsh plugin --profile web add dsh-composer-plus
47
47
  | **Shift+Tab 计划模式** | <a id="feature-plantoggle"></a>`Shift+Tab` 会在草稿开头添加 `/plan `(再按一次可移除)。如果对话已处于计划模式,`Shift+Tab` 会退出计划模式。 | <a href="assets/features/planToggle.webp"><img src="assets/features/planToggle.webp" width="160" alt="截图:Shift+Tab 计划模式"></a> |
48
48
  | **保持输入框焦点** | <a id="feature-keepfocus"></a>发送 `/` 命令或技能后,光标仍留在输入框中,你可以立即继续输入。对于输入命令后按 `Enter` 的键盘宏,这同样有效。dsh 在解析命令时会把输入框设为只读,浏览器随后会移除焦点。本功能会把焦点放回输入框,除非菜单、对话框或其他输入框正持有焦点。 | <a href="assets/features/keepFocus.webp"><img src="assets/features/keepFocus.webp" width="160" alt="截图:保持输入框焦点"></a> |
49
49
  | **问题卡片适应窗口** | <a id="feature-questionfit"></a>代理向你提问时,问题和答案在卡片中一起滚动,**跳过**和**提交**始终显示在底部。卡片使用窗口的高度(减去 200 px,留给对话标题和一部分对话),所以会随窗口变大变小。没有本功能时,dsh 把卡片限制在窗口的 60%(最多 520 px),并且只有答案可以滚动:较长的问题会把它自己的结尾、答案和按钮挤出卡片。 | <a href="assets/features/questionFit.webp"><img src="assets/features/questionFit.webp" width="160" alt="截图:问题卡片适应窗口"></a> |
50
+ | **对话标题栏适应窗口** | <a id="feature-headerfit"></a>窗口较窄时,dsh 对话标题栏中的按钮(模式、子代理、后台任务、打开方式、分支标签和授权标签)不再互相遮挡。对话标题至少保留 120 px;放不下的按钮换到右侧的第二行,每个按钮仍可点击。所有内容能放在一行时(宽窗口),标题栏与 dsh 原样一致。没有本功能时,dsh 只压缩标题:有子代理和后台任务时,在较窄的对话栏中按钮会互相覆盖。即使关闭本开关,分支标签(**每个对话一个分支**)和授权标签(**本对话内允许**)也会让标题栏适应窗口。 | <a href="assets/features/headerFit.webp"><img src="assets/features/headerFit.webp" width="160" alt="截图:对话标题栏适应窗口"></a> |
50
51
  | **一键继续** | <a id="feature-continuebutton"></a>回合被停止、失败或中断后,空输入框会显示 **▶**。点击一次即可在现有对话的基础上继续,不需要在输入框中输入内容,也不会添加可见的对话消息(模型会收到一条简短的隐藏提示“从停止的地方继续”,因为部分提供商,例如 Claude,会拒绝以助手回复结尾的请求)。队列中的消息会保留:▶ 只继续被停止的任务,之后再运行队列。已完成的回合仍显示普通的发送按钮。 | <a href="assets/features/continueButton.webp"><img src="assets/features/continueButton.webp" width="160" alt="截图:一键继续"></a> |
51
52
  | **重启后继续** | <a id="feature-resumeafterrestart"></a>默认关闭:请在 **设置 → Composer Plus** 中开启。如果你在对话仍在运行时退出 dsh(或 dsh 被关闭),再次打开 dsh 后,该对话会自动继续,并使用与“一键继续”相同的隐藏提示。如果当时有目标轮次(`/goal`)正在运行,该目标会继续下一轮(dsh 每次启动时都会暂停目标,直到你恢复它们)。你停止的、已完成的或失败的对话不会继续。dsh 本身没有这项设置:它只会把这样的回合标记为已中断。 | <a href="assets/features/resumeAfterRestart.webp"><img src="assets/features/resumeAfterRestart.webp" width="160" alt="截图:重启后继续"></a> |
52
53
  | **队列拖拽排序** | <a id="feature-queuereorder"></a>排队的消息会带一个把手(⠿)。拖动它即可调整顺序,或者让把手获得焦点后按 `↑` / `↓`。按 `Esc` 取消。 | <a href="assets/features/queueReorder.webp"><img src="assets/features/queueReorder.webp" width="160" alt="截图:队列拖拽排序"></a> |
@@ -63,19 +64,22 @@ dsh plugin --profile web add dsh-composer-plus
63
64
  | **工作区树中的分支** | <a id="feature-branchtree"></a>设置 → Composer Plus → **工作区树中的分支**(默认关闭)。开启后,每个在 `<project>/.worktrees/` 中有 worktree 文件夹的分支都会作为所属项目内的一个项目显示;在 dsh 中选择 **视图选项** → **按工作区树** 即可看到嵌套结构。文件夹被删除的分支会从列表中移除,dsh 会在 **未分组** 下显示它的对话。当项目文件夹中某个对话的智能体创建并切换到一个分支(`git switch -c`、`git checkout -b`),且该文件夹没有未提交的改动时,项目文件夹会切回原来的分支,该分支获得自己的文件夹,对话也会移进去:副本在分支项目中打开并继续执行任务,旧对话被归档。列表会在启动时、每 30 秒、每轮结束后以及你回到窗口时检查。 | <a href="assets/features/branchTree.webp"><img src="assets/features/branchTree.webp" width="160" alt="截图:工作区树中的分支"></a> |
64
65
  | **下一条消息预测** | <a id="feature-nextprediction"></a>默认开启;可在 **设置 → Composer Plus** 中关闭。智能体完成一个回合后(被停止或失败的回合除外),空输入框会以灰色文字显示对你下一条消息的猜测,并带有 **按 Tab 接受** 提示。`Tab` 会把文字放入输入框,但不会发送。`Esc` 会在本回合隐藏它。开始输入也会隐藏它,新的回合会替换它。开关下方的 **模型** 菜单列出 dsh 自己的模型(与 dsh 模型菜单的列表相同)。默认选中 **dsh 默认**,它跟随 dsh 的默认模型。每完成一个回合会进行一次简短的模型调用。在 Tether 中,猜测显示在空输入框上方:轻点它即可放入输入框。 | <a href="assets/features/nextPrediction.webp"><img src="assets/features/nextPrediction.webp" width="160" alt="截图:下一条消息预测"></a> |
65
66
  | **输入时补全** | <a id="feature-typingcompletion"></a>默认关闭;可在 **设置 → Composer Plus** 中开启。输入时,光标后紧跟的灰色文字会显示你的消息可能的后续内容。`Tab` 会把它添加到消息中,但不会发送。`Esc` 会隐藏它。它只建议你自己接下来要写的话:不会回答你,也不会编造错误信息或名称。消息看起来已完整,或模型不确定时,不显示任何内容。继续输入灰色文字中接下来的字符时,它会保留,不会再次调用模型。它的开关下方有自己的 **模型** 菜单。第一项 **与“下一条消息预测”相同**(默认)使用 **下一条消息预测** 的模型;选择其他模型,就可以为每个功能使用不同的模型,例如为补全选择更快的模型。你每次输入停顿时,它都会调用一次模型,因此消耗的 token 比预测多得多:请选择快速、低成本的模型。输入斜杠命令、消息中带有文件标签,或光标不在末尾时,它不会运行。在 Tether 中,输入时剩余部分会显示在输入框上方:轻点它即可添加。 | <a href="assets/features/typingCompletion.webp"><img src="assets/features/typingCompletion.webp" width="160" alt="截图:输入时补全"></a> |
66
- | **优化提示词** | <a id="feature-promptimprove"></a>输入一个粗略的请求,然后点击模型菜单旁边的魔法棒(**优化提示词**)。一次模型调用会把它改写成更清晰的提示词:先写目标,有多个部分时列出简短的编号步骤,并写明要运行的检查。它会读取此对话(已回滚的消息除外)、项目的 README、AGENTS.md 和清单文件、已更改的文件以及文件名与你的用词匹配的文件,并保留你的语言。它从不编造文件名。新文本会替换你的草稿,但不会发送:阅读、修改后再按 `Enter`。`Cmd/Ctrl+Z` 一步即可恢复你的原文,该按钮(**撤销优化**)也可以。如果你在它处理时继续输入,你的新文本会保留。`Esc` 或再次点击可取消。它在设置中有自己的 **模型** 菜单(默认:**与对话的模型相同**)。不适用于斜杠命令或带文件标签的消息。在 Tether 中,魔法棒位于输入框旁边。 | <a href="assets/features/promptImprove.webp"><img src="assets/features/promptImprove.webp" width="160" alt="截图:优化提示词"></a> |
67
- | **目标检查** | <a id="feature-goalcheck"></a>用 `/goal` 开始一个目标。当智能体在自动轮次中把目标标记为完成时,目标要通过两项检查才会关闭。首先,项目的测试命令会在对话的文件夹中、按对话的沙箱模式运行。命令是你自己设置的,或者从 `package.json`、`Makefile`、`Cargo.toml`、`go.mod` 或 pytest 中找到的。如果智能体自己最新的一步就是该测试的成功运行,则不再重复运行。然后,一次不带工具的独立模型调用会阅读目标、此对话、`git status` 和测试结果。任一检查失败时,目标保持进行中,智能体会看到原因,下一轮继续。目标栏下方的一行(**目标检查**)显示测试和上次结果。**编辑** 可设置你自己的测试命令以及时间或 token 上限;超过上限时目标会变为受阻。**立即运行** 会运行检查但不关闭目标。它在设置中有自己的 **模型** 菜单(默认:**与对话的模型相同**)。你自己完成目标时,不做任何检查。 | <a href="assets/features/goalCheck.webp"><img src="assets/features/goalCheck.webp" width="160" alt="截图:目标检查"></a> |
68
- | **项目记忆** | <a id="feature-projectmemory"></a>默认关闭:请在 **设置 → Composer Plus** 中开启。每个项目文件夹都有自己的记忆,该项目之后的对话都会读取,就像 DS Bot 为每个 Bot 保存一份记忆。每个回合结束后,会用对话的模型调用一次,读取新消息(不含已回滚的消息),把你长期的偏好、决定和事实保存为简短笔记,并修改或删除旧笔记。智能体也可以自己保存、删除和搜索笔记(`memory_remember`、`memory_forget`、`memory_recall`)。笔记也可以是全局的:所有项目都会读取。新对话会在系统提示词中获得这些笔记;之后保存的笔记从下一个对话开始显示。文件是 dsh 主目录下的 Markdown(`storages/dsh-composer-plus/memory/`),绝不写入项目文件夹。 | <a href="assets/features/projectMemory.webp"><img src="assets/features/projectMemory.webp" width="160" alt="截图:项目记忆"></a> |
67
+ | **优化提示词** | <a id="feature-promptimprove"></a>输入一个粗略的请求,然后点击模型菜单旁边的魔法棒(**优化提示词**)。一次模型调用会把它改写成更清晰的提示词:先写目标,有多个部分时列出简短的编号步骤,并写明要运行的检查。它会读取此对话(已回滚的消息除外)、项目的 README、AGENTS.md 和清单文件、已更改的文件以及文件名与你的用词匹配的文件,并保留你的语言。它从不编造文件名。新文本会替换你的草稿,但不会发送:阅读、修改后再按 `Enter`。`Cmd/Ctrl+Z` 一步即可恢复你的原文,该按钮(**撤销优化**)也可以。如果你在它处理时继续输入,你的新文本会保留。`Esc` 或再次点击可取消。它在设置中有自己的 **模型** 菜单(默认:**与对话的模型相同**)。对于 `/goal <objective>` 消息,它只改写目标,把它写成 **目标检查** 能够验证的完成条件:产出、必须通过的检查、要在对话中展示的证据、把无法完成的部分标记为未解决,以及同一障碍持续存在时停止。`/goal` 命令保持不变。不适用于其他斜杠命令、`/goal` 控制词(`clear`、`pause`、`resume`)或带文件标签的消息。在 Tether 中,魔法棒位于输入框旁边。 | <a href="assets/features/promptImprove.webp"><img src="assets/features/promptImprove.webp" width="160" alt="截图:优化提示词"></a> |
68
+ | **目标检查** | <a id="feature-goalcheck"></a>用 `/goal` 开始一个目标。当智能体在自动轮次中把目标标记为完成时,目标要通过两项检查才会关闭。首先,项目的测试命令会在对话的文件夹中、按对话的沙箱模式运行。命令是你自己设置的,或者从 `package.json`、`Makefile`、`Cargo.toml`、`go.mod` 或 pytest 中找到的。如果智能体自己最新的一步就是该测试的成功运行,则不再重复运行。然后,一次不带工具的独立模型调用会阅读目标、此对话、`git status` 和测试结果。模型会用一张证据表回答:目标的每一部分都标为已验证、不正确或未解决,并附上证据和修正办法;只有每一部分都已验证时,目标才会关闭。任一检查失败时,目标保持进行中,智能体会看到每个未完成的部分及其证据和修正办法,下一轮继续。目标栏下方的一行(**目标检查**)显示测试、上次结果以及已验证的部分数量(将鼠标悬停在上面可查看表格)。**编辑** 可设置你自己的测试命令以及时间或 token 上限;超过上限时目标会变为受阻。token 上限也会计入该对话的子智能体。**立即运行** 会运行检查但不关闭目标。它在设置中有自己的 **模型** 菜单(默认:**与对话的模型相同**)。你自己完成目标时,不做任何检查。 | <a href="assets/features/goalCheck.webp"><img src="assets/features/goalCheck.webp" width="160" alt="截图:目标检查"></a> |
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
+ | **上下文明细** | <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-protectedfiles"></a>默认开启。智能体自己的文件工具不能读取或更改与你的模式匹配的文件:对于 **读取和写入** 模式,对文件使用的 `read`、`read_image` 和 `grep` 会被拒绝;两种模式下 `write`、`edit` 和 `str_replace_editor` 都会被拒绝。智能体会看到原因,并被告知要问你。默认模式是 `.env*`、`*.pem` 和 `*.key`。设置 → Composer Plus → **受保护的文件**:添加一个模式(例如 `published/**` 或 `config/*.yml`),点击它的类型可在 **读取和写入** 与 **仅写入** 之间切换,用 ✕ 移除它,或点击 **使用默认值**。不含 `/` 的模式会匹配任意文件夹中的文件名。这是护栏,不是沙箱:shell 命令(`cat .env`)、脚本或 MCP 工具仍能访问该文件(见“限制”)。 | <a href="assets/features/protectedFiles.webp"><img src="assets/features/protectedFiles.webp" width="160" alt="截图:受保护的文件"></a> |
72
+ | **项目记忆** | <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> |
69
73
  | **本对话内允许** | <a id="feature-allowforchat"></a>当 Auto Review 询问你时,审批卡片上会多出 **本对话内允许**:从此以后,同一对话中的同一工具都会被允许,参数不限,直到时限结束(默认 1 小时;可在 **设置 → Composer Plus → 本对话内允许** 中选择)。之后代理会再次询问。标题栏中的标签会列出这些授权及其结束时间,也可以撤销它们。授权在重启后仍然有效。 | <a href="assets/features/allowForChat.webp"><img src="assets/features/allowForChat.webp" width="160" alt="截图:本对话内允许"></a> |
70
74
  | **项目状态** | <a id="feature-projectstatus"></a>侧边栏中的项目行会显示与其对话相同的加载图标 / 等待 / 完成标记。因此,即使项目已折叠,你也能知道其中有对话正在运行或需要你处理。等待你处理的对话优先显示,其次是你尚未打开的已完成对话(绿色圆点,即使另一个对话仍在运行也会显示),最后是加载图标。将鼠标悬停在上面可查看详情。在**按工作区树**中,父文件夹的行也会显示其中每个项目(例如 `.worktrees/` 中的每个分支文件夹)的对话状态,折叠时也一样。 | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="截图:项目状态"></a> |
71
- | **对话行显示 Git 分支** | <a id="feature-sessionbranch"></a>侧边栏中的每个对话行会显示一个小的灰色标签,内容是该对话最后一轮时项目文件夹所在的 git 分支(例如 `main` 或 `feature/login`;分离的 HEAD 会在括号中显示短提交 ID)。同一项目中位于不同分支的两个对话不再看起来一样,你也能立即发现自己是否要在错误的分支上继续对话。将鼠标悬停在标签上可查看完整名称。Host 部分会在每轮开始和结束时读取分支(`git branch --show-current`,只读);安装后还没有新一轮的对话,或不是 git 仓库的文件夹,不会显示标签。当对话上方的项目行与分支同名时(例如“每个对话一个分支”的文件夹),该对话行不显示分支标签,但“列表视图”中仍会显示。 | <a href="assets/features/sessionBranch.webp"><img src="assets/features/sessionBranch.webp" width="160" alt="截图:对话行显示 Git 分支"></a> |
75
+ | **对话行显示 Git 分支** | <a id="feature-sessionbranch"></a>侧边栏中的每个对话行会显示一个小的灰色标签,内容是该对话最后一轮时项目文件夹所在的 git 分支(例如 `main` 或 `feature/login`;分离的 HEAD 没有分支,不显示标签)。同一项目中位于不同分支的两个对话不再看起来一样,你也能立即发现自己是否要在错误的分支上继续对话。将鼠标悬停在标签上可查看完整名称。Host 部分会在每轮开始和结束时读取分支(`git branch --show-current`,只读);安装后还没有新一轮的对话,或不是 git 仓库的文件夹,不会显示标签。当对话上方的项目行与分支同名时(例如“每个对话一个分支”的文件夹),该对话行不显示分支标签,但“列表视图”中仍会显示。 | <a href="assets/features/sessionBranch.webp"><img src="assets/features/sessionBranch.webp" width="160" alt="截图:对话行显示 Git 分支"></a> |
72
76
  | **全部标为已读** | <a id="feature-markprojectread"></a>在侧边栏中,点击项目的 **…** 按钮 → **全部标为已读**。该项目中所有对话的绿色未读圆点会立即消失;其他项目的圆点保持不变。项目中没有未读对话时,此项显示为灰色(**没有未读对话**)。 | <a href="assets/features/markProjectRead.webp"><img src="assets/features/markProjectRead.webp" width="160" alt="截图:全部标为已读"></a> |
73
77
  | **活跃项目置顶** | <a id="feature-activeprojectsfirst"></a>当某个对话开始运行或需要你处理时,它所在的项目会移到侧边栏顶部,并使用 dsh 自带的行动画(与把它拖到那里的效果相同)。已完成的项目保持原位;你可以像往常一样把它们拖到任意位置。移动会保存到 dsh 的项目顺序中,因此关闭此功能后会保留当前顺序。 | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="截图:活跃项目置顶"></a> |
74
78
  | **近期项目筛选** | <a id="feature-recentprojects"></a>侧边栏 → 视图选项(滑块图标)→ **最近 2 小时内活跃**。选中后,侧边栏只显示最近 2 小时内有活跃对话的项目。活跃对话包括:这段时间内更新过的对话、正在运行或等待中的对话、当前打开的对话,以及你尚未打开的已完成对话(dsh 的绿色“完成”圆点),超过 2 小时后也一样。没有这类对话的项目会被隐藏,新建的空项目也会被隐藏。在 **按工作区树** 中,只要父文件夹中的某个项目处于活跃状态,父文件夹就会保持显示,最近 2 小时内不活跃的对话也会被隐藏,因此只显示最近的对话。再次选择该项即可显示所有项目。这个选择保存在本设备上。 | <a href="assets/features/recentProjects.webp"><img src="assets/features/recentProjects.webp" width="160" alt="截图:近期项目筛选"></a> |
75
79
  | **折叠全部项目** | <a id="feature-collapseprojects"></a>侧边栏中有项目展开时,视图选项(滑块图标)旁边会出现一个按钮。点击它可以一次折叠所有展开的项目,例如 5 个项目中展开的 3 个。没有展开的项目时,这个按钮会再次隐藏。 | <a href="assets/features/collapseProjects.webp"><img src="assets/features/collapseProjects.webp" width="160" alt="截图:折叠全部项目"></a> |
76
80
  | **按状态排序** | <a id="feature-statusorder"></a>侧边栏 → 视图选项 → **排序方式** → **按状态**(配合 **单列表** 使用)。已完成的对话排在最前(即带 dsh “完成”圆点的对话,以出错结束的回合也会显示这个圆点),然后是正在运行或等待中的对话,再然后是带有活跃自动化任务(Schedule)的对话,其余对话按 dsh 的顺序排列。打开已完成的对话后,它会往下移。只有视图会改变:选择 **手动排序** 或 **最近更新** 即可恢复。 | <a href="assets/features/statusOrder.webp"><img src="assets/features/statusOrder.webp" width="160" alt="截图:按状态排序"></a> |
77
81
  | **后台通知** | <a id="feature-notifications"></a>dsh 在后台时,如果回合完成(通知显示回复的第一行),或对话确实在等你处理,你都会收到通知。等你处理的情况包括:审批(显示工具名称)、回答(显示问题)或计划审阅。请求必须在 1.5 秒后仍未处理,才会发出通知,因此被自动处理的审批(Auto Review 授权、其他插件)不会发出通知;请求一旦得到处理,对应的通知也会立即撤回。程序坞/任务栏角标会显示等待中的对话数量。点击通知会打开对应的对话。 | <a href="assets/features/notifications.webp"><img src="assets/features/notifications.webp" width="160" alt="截图:后台通知"></a> |
78
- | **空闲时打开等待中的对话** | <a id="feature-idleswitch"></a>当某个对话提出问题,或等待审批或计划审阅(橙色圆点),而你 30 秒没有使用 dsh 时,dsh 会打开该对话。有多个对话在等待时,等待最久的先打开;下一个会在再次 30 秒没有使用后打开。按键、点击、移动鼠标、滚轮或触摸都会让 30 秒重新计时。有焦点的输入框中有文字、选中了文本,或打开了菜单或对话框时,也不会切换。等待中的对话正在屏幕上时,不会切换。如果你没有回答就离开了等待中的对话,再次 30 秒没有使用后,它会再次打开。dsh 在后台时也会生效,但 dsh 不会被带到前台。 | <a href="assets/features/idleSwitch.webp"><img src="assets/features/idleSwitch.webp" width="160" alt="截图:空闲时打开等待中的对话"></a> |
82
+ | **空闲时打开等待中的对话** | <a id="feature-idleswitch"></a>当某个对话提出问题,或等待审批或计划审阅(橙色圆点),或完成了你尚未查看的一轮(绿色圆点),而你 30 秒没有使用 dsh 时,dsh 会打开该对话。橙色对话先于绿色对话打开。同一组中,等待最久的先打开;下一个会在再次 30 秒没有使用后打开。按键、点击、移动鼠标、滚轮或触摸都会让 30 秒重新计时。有焦点的输入框中有文字、选中了文本,或打开了菜单或对话框时,也不会切换。等待中的对话正在屏幕上时,不会切换。如果你没有回答就离开了等待中的对话,再次 30 秒没有使用后,它会再次打开。绿色对话打开后,它的圆点会消失;下一个绿色对话要等你再次使用 dsh,之后又 30 秒没有使用时才会打开。dsh 在后台时也会生效,但 dsh 不会被带到前台。 | <a href="assets/features/idleSwitch.webp"><img src="assets/features/idleSwitch.webp" width="160" alt="截图:空闲时打开等待中的对话"></a> |
79
83
  | **应用语言** | <a id="feature-language"></a>设置 → Composer Plus → **应用语言** 可以把整个 dsh 界面切换为 Türkçe、Español、Português (Brasil)、Français、Deutsch、Русский、日本語、한국어、Bahasa Indonesia、Tiếng Việt 或 हिन्दी(见下文)。 | <a href="assets/features/language.webp"><img src="assets/features/language.webp" width="160" alt="截图:应用语言"></a> |
80
84
  | **手机连接(iPhone)** | <a id="feature-mobileconnect"></a>通过 [Tether](tether/) 应用在 iPhone 上使用 dsh,可以在同一 Wi-Fi 下使用,也可以通过 [Tailscale](https://tailscale.com) 使用。请在 **设置 → Composer Plus** 中开启它(默认关闭,因为它会在这台 Mac 上开放一个网络端口)。然后点击侧边栏左下角的 **手机连接**:用 iPhone 相机扫描二维码(轻点 **Open in Tether**),或用 Tether 中的 **Scan code** 扫描,轻点 **Connect**,然后点击 **Approve**。请先安装 Tether:没有它,相机无法打开这个二维码。手机可以显示你的对话、发送消息(可附照片:输入框的 **+** → Camera、Photos 或 Paste image)、回答审批和问题,以及切换模型和智能体。你可以配对任意多台 Mac:点击应用左上角的 Mac 名称即可在它们之间切换。**手机连接** 面板会列出已配对的 iPhone 及其上次连接时间:点击 **Remove** 可立即断开其中一部。“Tailscale only”会拒绝来自本地网络的连接(适用于共享 Wi-Fi),访问日志会显示谁尝试过连接。在 Tether 中,“Settings → Privacy”可以用 Face ID 锁定应用。 | <a href="assets/features/mobileConnect.webp"><img src="assets/features/mobileConnect.webp" width="160" alt="截图:手机连接(iPhone)"></a> |
81
85
  | **自动更新** | <a id="feature-autoupdate"></a>dsh 启动时,插件会检查 [最新的 GitHub release](https://github.com/furkancak1r/dsh-composer-plus/releases/latest)。如果它比当前版本新,并且已发布到 npm,插件会通过 dsh 自带的插件管理器(与 设置 → 插件 相同的途径)安装这个确切的版本,并通知你。重启 dsh 即可加载新版本。**设置 → Composer Plus → Composer Plus 更新** 会显示版本号,并提供 **检查更新** / **立即更新**。dsh 第一次以新版本启动时,会显示一次 **Composer Plus N 的新功能** 窗口,内容是该版本的发布说明(来自同一次更新检查,不会额外联网);点击 **关闭** 或按 `Esc` 关闭。 | <a href="assets/features/autoUpdate.webp"><img src="assets/features/autoUpdate.webp" width="160" alt="截图:自动更新"></a> |
@@ -160,7 +164,10 @@ English · 中文 · Türkçe · Español · Português (Brasil) · Français ·
160
164
  - **输入时补全:** 在你开启之前一直关闭。开启后,你每次输入停顿时,Host 端会把你目前已输入的文字,以及该对话中你自己的消息和智能体的文字回复(不含工具输出、隐藏上下文和推理内容;对话部分最多约 3,000 个字符),发送给在 **输入时补全** 下选择的模型(默认为 **下一条消息预测** 的模型)。新的停顿会停止较早的请求。对话中不会保存任何内容。开关保存在 `$DSH_HOME/storages/dsh-composer-plus/complete.json` 中(仅所有者可访问的文件)。
161
165
  - **优化提示词:** 在你点击魔法棒之前,什么都不会运行。点击后,Host 端会以一次请求的形式,把以下内容发送给在 **优化提示词** 下选择的模型(默认为对话自己的模型):你的草稿;该对话中你自己的消息和智能体的文字回复(不含工具输出、隐藏上下文、推理内容和已回退的消息;最多约 6,000 个字符,最新的部分);与 **功能创意** 相同的项目概要(文件规则也相同:不读取 `.env*` 或密钥文件,跳过指向文件夹外部的符号链接和 FIFO);`git status` 列为已更改的路径;以及最多 30 个名称与你的草稿有相同词语的已跟踪或未跟踪(未被忽略)路径。除这份概要外,不会发送任何文件内容。对话和项目中都不会写入任何内容:回答只会替换输入框中的草稿,是否发送由你决定。模型选择保存在 `$DSH_HOME/storages/dsh-composer-plus/improve.json` 中(仅所有者可访问的文件)。
162
166
  - **目标检查:** 只有当智能体在自动轮次中把 `/goal` 标记为完成时(或者你点击 **立即运行** 时)才会运行。Host 端在对话的文件夹中、按对话的沙箱模式运行测试命令(与 dsh 自己的 `bash` 工具相同:同样的文件访问策略;沙箱无法启动时,测试不会运行,检查判为失败)。为了找到命令,它只读取 `package.json`、`Makefile`、`Cargo.toml`、`go.mod`、`pyproject.toml` 和 `pytest.ini`,并且只读取文件夹内的普通文件(不跟随指向文件夹外部的符号链接,不读取 FIFO)。然后,它以一次不带工具的请求,把以下内容发送给在 **目标检查** 下选择的模型(默认为对话自己的模型):目标;从目标开始以来的对话(你的消息、智能体的回复、截断到 1,000 个字符的工具调用以及每个工具结果的最后 2,000 个字符;不含推理内容和已回退的步骤;最多约 60,000 个字符,最新的部分);`git status --short`;以及测试输出的末尾。工具输出可能包含智能体读取过的内容,因此这次请求可能包含你文件的一部分,与对话本身相同。对话和项目中都不会写入任何内容。你的测试命令、上限、上次结果(含其输出的末尾)和模型选择保存在 `$DSH_HOME/storages/dsh-composer-plus/goal-check.json` 中(仅所有者可访问的文件,最新的 500 个对话)。
163
- - **项目记忆:** 在你开启之前一直关闭。开启后,每个顶层对话的回合结束时,Host 部分会把该对话自上次整理以来的新消息(你的消息和智能体的文字回复;不含工具输出、推理、隐藏上下文和已回滚的消息;分叉对话中复制自父对话的部分不算在内;最多约 16,000 个字符)和已保存的笔记,作为一次不带工具的请求发给对话自己的模型。笔记是 `$DSH_HOME/storages/dsh-composer-plus/memory/` 下的 Markdown 文件(仅所有者可读写):每个项目文件夹对应 `projects/<id>/`(`<id>` 是文件夹真实路径的哈希;`project.json` 记录文件夹路径),另有 `global/`、`journal.jsonl`(每次改动及改动前后的那一行)和 `reviewed.json`(每个对话读到的位置)。项目文件夹中不会写入任何内容。看起来像密钥、令牌、密码或证件号码的笔记会被拒绝。项目的笔记会进入该文件夹中每个新对话的系统提示词,因此该对话的每次请求都会把它们发给模型。开关保存在同一位置的 `memory.json` 中。
167
+ - **在新对话中继续:** 在你点击之前,什么都不会运行。点击后,Host 端会把对话(与目标检查读取的方式相同:不含推理内容和已回退的步骤)发送给对话自己的模型,并显示交接说明;只有 **开始新对话** 才会创建新对话。项目中不会写入任何内容。
168
+ - **上下文明细:** 只在 Host 上读取对话日志;不调用模型,不读取项目文件。
169
+ - **受保护的文件:** 列表和开关保存在 `$DSH_HOME/storages/dsh-composer-plus/protected-files.json` 中(仅所有者可访问的文件)。检查只读取每次文件工具调用的路径(及其真实路径),从不读取文件本身。
170
+ - **项目记忆:** 在你开启之前一直关闭。开启后,每个顶层对话的回合结束时,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 通过同一路由读取和修改笔记。
164
171
  - **备份:** 任何数据都不会离开你的电脑。归档保存在 `~/Desktop/dsh-backups` 中(仅所有者可访问的文件)。机密不在归档中:凭据文件(`.credentials.yaml`、`.env`)、密钥文件(`.pem`、`.key`、`.p12`、`.pfx`)以及 yml 文件中 token、secret、password 和 API key 设置的值都会被遮蔽;它们的真实副本保存在同一文件夹的 `composer-plus-vault/<archive>/` 中(仅所有者可访问),只在这台电脑上。**用于另一台电脑** 不会复制 vault:请在那台电脑上重新输入这些机密。你的对话日志、设置和 dsh 主目录的其余内容按原样保存在归档中:请像对待 `$DSH_HOME` 本身一样,不要公开该文件夹。备份使用 `O_NOFOLLOW | O_NONBLOCK` 读取文件;符号链接按链接保存(从不跟随),FIFO 和设备文件会被跳过。自动备份的开关和设置保存在 `$DSH_HOME/storages/dsh-composer-plus/auto-backup.json` 中,救援控制台的开关保存在 `rescue-console.json` 中;dsh 运行期间,`running/host-<pid>.json` 标明每个 dsh 进程(救援控制台读取它们,以便拒绝恢复)。
165
172
  - **救援控制台:** 一个终端菜单;它不打开网络端口。恢复只写入 dsh 主目录旁边的一个新文件夹(文件使用 `O_EXCL | O_NOFOLLOW` 写入,符号链接最后写入且从不跟随),并拒绝以下归档:含有不安全名称(`..`、绝对路径)、设备文件或 FIFO、多于一个顶层文件夹,或位于链接之下的条目。
166
173
 
@@ -182,7 +189,7 @@ English · 中文 · Türkçe · Español · Português (Brasil) · Français ·
182
189
  - **对话行上没有分支标签:** 安装此版本后,该对话还没有新的一轮;或者它的文件夹不是 git 仓库;或者 **对话行显示 Git 分支** 已关闭。更新后,请重启 dsh(分支由 Host 端记录)。
183
190
  - **目标检查显示测试以代码 127 或 “not found” 退出:** 从 Finder 或程序坞启动的 dsh 的 PATH 可能比终端里的短,因此找不到 `npm`、`pnpm` 或 `cargo`。请从终端启动 dsh,或者在 **目标检查** → **编辑** 中用完整路径设置你自己的测试命令。**立即运行** 会马上显示结果。
184
191
  - **目标没有关闭,智能体一直在工作:** **目标检查** 发现了失败的测试或缺少的工作;目标下方的一行会显示原因(将鼠标悬停在结果上可查看详情)。请修正原因或测试命令,或者用 `/goal` 或目标栏自己完成目标(这不会被检查)。
185
- - **刚发布新版本时安装失败:** 请加上版本号(`dsh-composer-plus@1.16.1`),见上文的安装说明。
192
+ - **刚发布新版本时安装失败:** 请加上版本号(`dsh-composer-plus@1.17.0`),见上文的安装说明。
186
193
  - **立即备份显示“另一个备份操作正在进行”:** 另一个 dsh 窗口或救援控制台中正在运行一个操作(它们共用备份文件夹中的锁文件 `.composer-plus.lock`)。请等待它完成。如果没有操作在运行,下次点击时会接管已关闭进程留下的锁。
187
194
  - **救援控制台显示“dsh is running”:** 请先退出 dsh。如果 dsh 确实已关闭,消息中提到的文件是崩溃后留下的:删除它,然后重试。
188
195
  - **恢复后 dsh 无法启动或缺少插件:** 需要重新安装 profile 的插件包。恢复后,救援控制台会提供这一步;你也可以在它列出的 `$DSH_HOME/profiles/` 下的每个文件夹中运行 `pnpm install`。不在 vault 中的机密(另一台电脑)必须重新输入:控制台会列出它们。
@@ -205,6 +212,7 @@ English · 中文 · Türkçe · Español · Português (Brasil) · Français ·
205
212
  - **本对话内允许** 从授权的那一刻开始计算时限。新的时限会立即应用于仍在生效的授权,因此更短的时限可能会让它们立即结束。1.12 及更早版本的授权没有时间信息:更新后,代理会就这些工具再询问一次。
206
213
  - **保持输入框焦点** 只在发送 `/` 命令或技能后才会把焦点还给输入框。dsh 解析命令时,输入框会有几毫秒处于只读状态,因此这段时间内按下的键会丢失。如果 dsh 的 `/` 菜单仍然打开,`Enter` 会选择高亮的行,而不会发送。
207
214
  - **问题卡片适应窗口** 只改变 dsh 的问题卡片,不改变计划审阅卡片。它通过 dsh 的标记(`data-question-key`、`data-question-scroll`)找到卡片;如果 dsh 更新改变了这些标记,卡片会按 dsh 自己的样子显示。卡片高度跟随窗口,而不是对话:在较窄侧边面板中的对话里,较高的卡片仍可能超出对话上方。
215
+ - **对话标题栏适应窗口** 通过 dsh 生成的类名(`_titleRow`、`_titleCluster`、`_crumbs`、`_headerActions`、`_headerUtilities`)找到对话标题栏,因为 dsh 没有为它提供布局接口。如果 dsh 更新改了这些类名,标题栏按 dsh 原样显示。在很窄的对话栏中,标题栏可能占两到三行,所以消息上方的空间会变小。
208
216
  - **手机连接** 只适用于 macOS(它使用 `en0`、`openssl`、`swift` 和 `dns-sd`)。它使用固定端口 19390 和 19391,因此每台 Mac 上同一时间只能有一个 dsh 运行它(每台 Mac 是手机 Mac 列表中的一项)。只有在 Tether 打开或刚转入后台时,手机才能收到通知(没有推送服务)。在 Tether 中打开“Settings → Notifications → Send notifications”之前,Tether 不会发送通知。此开关默认关闭,打开时 iOS 会请求通知权限。iOS 应用尚未上架 App Store:请用 Xcode 从 `tether/ios` 构建它。“Tailscale only”仍然需要 Mac 有 Wi-Fi 或以太网地址(只有在有这样的地址时,网关才会启动)。访问日志按 Mac 分别保存,只保留最新的 200 次尝试;一分钟内重复的尝试不会新增一行,而是把同一行的次数加一。Tether 的应用锁不会隐藏 iPhone 锁定屏幕上的通知预览:请在 iOS 设置中关闭它们。Tether 的绿点跟随 Mac:在 dsh 中打开的对话,手机上的绿点也会消失。在 Tether 中打开的对话,只在手机上消失;Mac 上 dsh 自己的绿点会一直保留,直到你在 Mac 上打开该对话。
209
217
  - 会话链接在对话中有效;点击它不会打开对应的对话。用 **复制消息链接** 复制的链接,只在 dsh 0.2.1 及更高版本中、并且只从对话中的消息里才能打开对应的消息(dsh 0.2.0 没有用户文本规则,所以链接仍会被复制,但只显示为普通文本)。被回退移除的消息,或被压缩从 dsh 加载的历史中移除的消息,无法显示:此时链接会给出提示。🔗 按钮依附在 dsh 的消息行上;如果 dsh 更新改变了这部分标记,按钮就不会显示。
210
218
  - **全部标为已读** 通过 dsh 中一个不是公开 API 的部分(dsh 会话状态中的 `completionUnread` 列表)来更改 dsh 自己的未读圆点。如果 dsh 更新重命名了它,该菜单项就不会显示。该菜单项放在 dsh 项目的“…”菜单中,而这个菜单没有给插件的插槽;如果 dsh 修改了这个菜单,该菜单项也不会显示。
@@ -219,7 +227,7 @@ English · 中文 · Türkçe · Español · Português (Brasil) · Français ·
219
227
  - **每个对话一个分支**:当对话的分支文件夹(`<project>/.worktrees/<name>`)被删除时(例如对话自己的智能体移除了 worktree 并删除了分支),对话的下一步会把对话移出该文件夹。它的分支文件夹项目会从侧边栏消失,对话显示在“未分组”下并保持打开。在 dsh 0.2.1 及更高版本中,对话在主项目文件夹中继续,模型会收到一条关于新文件夹的说明。在 dsh 0.2.0 上,对话保留已删除的文件夹:在那里运行的命令会失败,直到你开始一个新对话。没有对话使用的已删除分支的项目也会从侧边栏消失:Composer Plus 在启动时和每 30 秒检查一次分支文件夹,不需要任何侧边栏筛选。对话移动期间,同一仓库中的**新分支**会回答“请重试”。关闭开关后,dsh 自己的错误会再次出现(“working-directory: directory does not exist”)。
220
228
  - **工作区树中的分支** 会在无需点击的情况下写入 git:移动对话时,它把项目文件夹切回原来的分支(`git switch`),并添加一个 worktree(`git worktree add`)。它从不删除分支、worktree 或文件。dsh 不能更改对话的文件夹,所以被移动的对话是一个副本(dsh 自己的分叉,带有新的 id),旧对话会被归档。副本会继续已停止的任务;分支出现时正在运行的工具调用会以拒绝结束,智能体会在新文件夹中再次运行它。旧对话的目标不会随之移动。只有文件夹是仓库主文件夹的对话会移动,而且只针对它在该轮中创建并切换到的分支(`git switch -c`、`git checkout -b`):只用 `git branch` 创建的分支、有未提交改动的文件夹、链接的 worktree 或子文件夹都不会移动。只有直接位于 `<project>/.worktrees/` 中且有分支的 worktree 会显示在树中;分离的 worktree 或位于其他位置的 worktree 不会显示。只有当原对话是正在打开的对话时,副本才会自动打开(插件通过 dsh 的侧边栏行判断);否则它在分支项目中。
221
229
  - **在对话中查找** 只搜索页面显示的内容:已加载的消息和回复(向上滚动或点击 **加载更早** 可查看更早的内容),不搜索已收起的工具步骤,也不搜索工具输出中被折叠的文本。它最多统计 2,000 个匹配项(之后显示“2000+”)。它使用浏览器的高亮 API(Chromium 105 及更高版本;桌面应用支持):在较旧的浏览器中,计数和跳转仍然可用,只是没有颜色。`Cmd+F`(Mac)或 `Ctrl+F`(Windows 和 Linux)只在屏幕上有对话时打开它;在其他地方,浏览器自带的查找照常工作。在 Mac 上,`Ctrl+F` 在文本框中仍保持 macOS 的用法(光标向前移动一个字符)。
222
- - **空闲时打开等待中的对话** 只知道 dsh 自己的窗口看到的操作:在其他应用中的操作不算,因此 dsh 在后台时,它会在 30 秒后打开等待中的对话。它不会把 dsh 带到前台。只阅读而不按键、不点击、不移动鼠标,也算空闲。它只看带有 dsh 橙色圆点的对话(问题、审批或计划审阅);子代理的请求显示在其父对话中。等待中的对话在屏幕上时,不会打开其他对话;你没有回答就离开的对话,在再次 30 秒没有使用后可能会再次打开。30 秒不能更改。
230
+ - **空闲时打开等待中的对话** 只知道 dsh 自己的窗口看到的操作:在其他应用中的操作不算,因此 dsh 在后台时,它会在 30 秒后打开等待中的对话。它不会把 dsh 带到前台。只阅读而不按键、不点击、不移动鼠标,也算空闲。它只看带有 dsh 橙色圆点(问题、审批或计划审阅)或绿色圆点(你尚未打开的已完成一轮)的对话;子代理的请求显示在其父对话中。橙色对话先打开。打开绿色对话会去掉它的圆点,所以下一个绿色对话要等你下一次按键、点击、移动鼠标、滚动滚轮或触摸后才开始计 30 秒:你回来时,其他绿色圆点仍在。等待中的对话在屏幕上时,不会打开其他对话;你没有回答就离开的对话,在再次 30 秒没有使用后可能会再次打开。30 秒不能更改。
223
231
  - 重启前发出的通知,点击后只会把 dsh 带到前台。
224
232
  - 活跃项目通过 dsh 保存的项目顺序来移动,因此新顺序在重启后依然保留。不属于任何项目的对话(“未分组”)无法移动;dsh 总是把它们列在最后。
225
233
  - dsh 在侧边栏的视图选项菜单中没有扩展点,所以近期项目选项被添加到 dsh 自己的菜单中。如果 dsh 更新修改了这个菜单,该选项将不会显示,所有项目都保持可见。筛选作用于项目行,因此 **单列表** 不会被筛选。在 **按工作区树** 中,只要父文件夹中的某个项目处于活跃状态,父文件夹就会保持显示,最近 2 小时内不活跃的对话行也会被隐藏;在 **按工作区** 中只筛选项目行。筛选会从 dsh 保存的视图设置(不是公开 API)读取 dsh 当前的视图;如果 dsh 更新改了它的名称,**按工作区树** 会按 **按工作区** 的方式筛选。项目状态也读取同一设置:在 **按工作区树** 中,父文件夹的行也会统计其中各项目的对话;如果 dsh 改了该设置的名称,每行只显示自己的对话。**按状态** 也有同类限制:dsh 没有排序插槽,因此该菜单项和行顺序依赖 dsh 的菜单和列表标记。
@@ -228,10 +236,13 @@ English · 中文 · Türkçe · Español · Português (Brasil) · Français ·
228
236
  - dsh 也没有决定 **新会话** 在何处打开的扩展点。**新会话的默认工作区** 包装了 dsh 的一个非公开 API 方法(dsh 工作区服务的 `startSession`)。如果 dsh 更新改了它的名字,**新会话** 会在 dsh 自己选择的位置打开(当前或最近的项目)。所有不指定项目的调用都使用默认值:侧边栏按钮、它的快捷键、徽标,以及 **自动化任务** 页面上的 **新建**。dsh 启动时仍会打开上一个对话。通用文件夹在首次使用时创建并加入你的项目;在 Windows 或 Linux 上,如果 Documents 文件夹被移动过,它可能与 dsh 自己的文件夹不同。
229
237
  - dsh 也没有输入框提示的扩展点,所以 **下一条消息预测** 的文字覆盖在 dsh 自己的占位文字(`[data-composer-placeholder]`)上。如果 dsh 更新修改了这部分标记,就不会显示预测。开启期间,每完成一个回合都会进行一次简短的模型调用。
230
238
  - **输入时补全** 通过 dsh 自己的输入框提示显示文字(即 dsh 用于斜杠命令参数提示的 `--dsh-composer-hint` 样式)。输入斜杠命令、消息中带有文件或符号标签,或光标不在消息末尾时,它不会运行。如果 dsh 更新修改了这个样式,就不会显示补全。你每次输入停顿都会进行一次模型调用。
231
- - **优化提示词** 只能看到简短的项目概要、已更改的路径以及名称与你的用词匹配的路径,看不到代码本身。因此它可能漏掉正确的文件,并且只会提到提供给它的路径。发送前请先阅读新文本。输入斜杠命令或消息中带有文件或符号标签时,它不会运行(新文本是纯文本,标签会丢失);一条消息最多 8,000 个字符。图片仍保留在附件中:只有文字会改变。每次点击都会进行一次模型调用;较强的模型可能需要一分钟(按 `Esc` 取消)。
232
- - **目标检查** 只检查智能体在自动目标轮次中做出的完成:你在对话中要求的完成、`/goal` 和目标栏都不会被检查。智能体可以自己修改测试或测试命令用到的文件;审核模型会阅读对话,可以看到这一点,但它在两个方向上都可能出错(错误的“尚未完成”会多花一轮;错误的“已完成”会关闭目标)。审核模型看到的是对话和 `git status`,而不是代码本身。只有当智能体最新的一步能更改文件的操作就是它自己在同一文件夹中成功运行完全相同命令的 `bash` 时,才会复用这次测试;带管道(`| tail`)或 `&&` 的命令不会被复用。预算在回合结束时计算,因此一个回合可能会超出预算。只计算对话自己的模型调用(不含其子智能体的调用)。检查运行期间 `update_goal` 会等待(测试最多 15 分钟,审核最多 3 分钟)。分支对话会得到新的对话 id,因此它开始时没有父对话自己的测试命令和上限。每次进入审核的完成都会花费一次模型调用。
239
+ - **优化提示词** 只能看到简短的项目概要、已更改的路径以及名称与你的用词匹配的路径,看不到代码本身。因此它可能漏掉正确的文件,并且只会提到提供给它的路径。发送前请先阅读新文本。输入除 `/goal <目标>` 以外的斜杠命令、`/goal` 控制词(`clear`、`pause`、`resume`),或消息中带有文件或符号标签时,它不会运行(新文本是纯文本,标签会丢失);一条消息最多 8,000 个字符。对于 `/goal` 目标,它只根据草稿和上下文写出条件;过于严格的条件可能会多花目标轮次,因此发送前请先阅读。图片仍保留在附件中:只有文字会改变。每次点击都会进行一次模型调用;较强的模型可能需要一分钟(按 `Esc` 取消)。
240
+ - **目标检查** 只检查智能体在自动目标轮次中做出的完成:你在对话中要求的完成、`/goal` 和目标栏都不会被检查。智能体可以自己修改测试或测试命令用到的文件;审核模型会阅读对话,可以看到这一点,但它在两个方向上都可能出错(错误的“尚未完成”会多花一轮;错误的“已完成”会关闭目标)。审核模型看到的是对话和 `git status`,而不是代码本身。只有当智能体最新的一步能更改文件的操作就是它自己在同一文件夹中成功运行完全相同命令的 `bash` 时,才会复用这次测试;带管道(`| tail`)或 `&&` 的命令不会被复用。预算在回合结束时计算,因此一个回合可能会超出预算。token 预算也会计算该对话的子智能体对话的调用(在每个回合结束时从它们保存的日志中读取,因此子智能体很多的对话检查起来会稍慢一些)。证据表来自审核模型自己对对话的阅读:它标为已验证的部分,在重要时仍需要你自己查看。检查运行期间 `update_goal` 会等待(测试最多 15 分钟,审核最多 3 分钟)。分支对话会得到新的对话 id,因此它开始时没有父对话自己的测试命令和上限。每次进入审核的完成都会花费一次模型调用。
241
+ - **受保护的文件** 是护栏,不是沙箱。它覆盖 dsh 自己的文件工具(`read`、`read_image`、对文件使用 `grep`、`write`、`edit`、`str_replace_editor`)。shell 命令(`cat .env`)、智能体编写的脚本、子智能体的 shell、MCP 工具、`glob` 列表以及对整个文件夹使用的 `grep` 仍能访问受保护的文件。如需真正的限制,请使用 dsh 的沙箱模式,或者不要把机密放在项目文件夹中。模式支持 `*`、`**` 和 `?`,不支持 `{a,b}` 或 `[ab]`,并且不区分大小写。
242
+ - **在新对话中继续** 会把对话(消息、工具调用以及每个工具结果的末尾,最多约 60,000 个字符,最新的部分)发送给对话自己的模型。交接说明可能漏掉某个决定或文件:开始前请先阅读。新对话只知道这份交接说明和链接的对话(dsh 会把旧对话作为只读上下文附加进来);它的模型上下文从很小开始,旧对话保持不变。每个对话同一时间只能进行一次写说明或开始操作。
243
+ - **上下文明细** 按 dsh 自己的规则显示估算值(每个 token 约 4 个字符),与 dsh 的上下文环使用相同的规则;模型自己的计数可能不同。工具定义取自最新的一次请求。它按对话日志中的样子显示上下文;正在运行的回合会在它的下一步之后出现。
233
244
  - **停止后发送的消息优先** 只在你停止对话后生效(或在某一轮失败后,或打开仍有队列的对话时):对话运行时发送的消息仍会排在队列末尾。它只会越过你自己的排队消息:如果队列中有目标轮次或问题回复,仍保持 dsh 自己的顺序。它会读取 dsh 中一个非公开 API 的部分(被停止的那一轮是否仍在结束中);如果 dsh 更新后改了它的名称,消息要等那一轮结束后才会被移到前面。子代理对话保持 dsh 自己的顺序。
234
- - **项目记忆** 属于对话的第一个文件夹(dsh 的项目文件夹):用 `cd` 更换文件夹的对话仍使用第一个项目的记忆;通过另一条路径打开的同一文件夹共用同一份记忆。对话开始时会冻结其记忆部分,所以之后保存的笔记从下一个对话开始显示(`memory_recall` 能立即找到)。整理只保留模型决定保留的内容:它可能漏掉某个事实,也可能保留错误的内容;请打开文件检查,并在 dsh 关闭时手动编辑或删除。每个包含你的消息的回合结束后都会调用一次模型;调用失败时,下一个回合后会再次读取同样的消息。子智能体对话不做整理。这个思路和文件格式来自 [DS Bot](https://github.com/Fei2411/DS-Bot)(Apache-2.0);Composer Plus 没有使用它的代码,也从不读取或写入 DS Bot 自己的记忆。
245
+ - **项目记忆** 属于对话的第一个文件夹(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 自己的记忆。
235
246
  - **备份** 只使用一个固定文件夹 `~/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 仍已安装,它就会把 Composer Plus 的归档计入自己的保留份数,并可能删除它们。
236
247
  - **恢复** 只在 dsh 关闭时于救援控制台中运行:它会替换整个 dsh 主目录。旧目录会以 `.dsh.pre-restore-<time>` 保留在旁边,直到你删除它,因此磁盘需要能容纳两者。对话保留其项目路径:在另一台电脑上,位于其他路径的项目会显示为缺失,直到你重新添加它。指向 dsh 主目录之外的符号链接(例如从其他文件夹链接的技能)会作为链接恢复;它们的目标必须存在于那台电脑上。
237
248
  - **会话日志检查** 按照 dsh 自己判断能否打开的规则读取每个对话的最新日志:不是 JSON 或顺序错乱的行,只有在其后还有回合结束时才算损坏(否则 dsh 会打开该对话,只是不含从该行起的各行,因此不会列出它)。它不会按照 dsh 自己的事件规则检查日志中的事件,因此被判为健康的日志在 dsh 升级后仍可能无法打开。修复会从一份备份中取回副本:该备份之后的消息会从该对话中丢失(损坏的文件保留在旁边)。在此 dsh 中打开的对话不会在设置中修复:dsh 正持有它。
@@ -264,7 +275,7 @@ English · 中文 · Türkçe · Español · Português (Brasil) · Français ·
264
275
 
265
276
  **能否让智能体不再自己宣布工作已完成,就像 loop engineering 中的审核循环那样?** 可以,使用 **目标检查**(默认开启):用 `/goal` 开始一个目标。当智能体说目标已完成时,会运行项目的测试,并由一次独立的模型调用对照对话检查目标;任一项失败时,目标保持进行中,智能体会看到原因。在目标下方的 **目标检查** 行中用 **编辑** 设置你自己的测试命令、时间上限或 token 上限。
266
277
 
267
- **智能体能像 DS Bot 的记忆那样,在不同对话之间记住我的偏好吗?** 可以,使用 **项目记忆**(默认关闭):在 **设置 → Composer Plus** 中开启。每个回合结束后,你长期的偏好和决定会作为简短笔记保存到该对话的项目中,该项目的每个新对话都会读取。让智能体记住某件事,它会立即保存。
278
+ **智能体能像 DS Bot 的记忆那样,在不同对话之间记住我的偏好吗?** 可以,使用 **项目记忆**(默认关闭):在 **设置 → Composer Plus** 中开启。每个回合结束后,你长期的偏好和决定会作为简短笔记保存到该对话的项目中,该项目的每个新对话都会读取。让智能体记住某件事,它会立即保存。要查看或修改笔记,请点同一行的 **打开记忆**,写下要修改的内容。
268
279
 
269
280
  **dsh 能像 dsh-backup 那样备份我的对话和设置吗?** 可以:**设置 → Composer Plus → 备份 → 立即备份**。它把相同格式的归档写入同一个文件夹(`~/Desktop/dsh-backups`),因此 dsh-backup 的归档也会显示并可以恢复,你可以卸载 dsh-backup。打开 **自动备份** 即可按计划备份。
270
281
 
@@ -304,7 +315,7 @@ English · 中文 · Türkçe · Español · Português (Brasil) · Français ·
304
315
 
305
316
  **dsh 任务完成或需要审批时,如何收到 macOS / Windows 通知?** 保持 **后台通知** 开启(默认开启),并在操作系统设置中允许 DeepSeek Harness 发送通知。
306
317
 
307
- **dsh 能自己打开向我提问的对话吗?** 可以,使用 **空闲时打开等待中的对话**(默认开启):当某个对话在等待回答、审批或计划审阅,而你 30 秒没有使用 dsh 时,dsh 会打开它。你在输入、滚动或移动鼠标时,它会等待。
318
+ **dsh 能自己打开向我提问的对话吗?** 可以,使用 **空闲时打开等待中的对话**(默认开启):当某个对话在等待回答、审批或计划审阅,而你 30 秒没有使用 dsh 时,dsh 会打开它。完成了你尚未查看的一轮的对话(绿色圆点)也会这样打开,在橙色对话之后。你在输入、滚动或移动鼠标时,它会等待。
308
319
 
309
320
  **如何把 DeepSeek Harness 界面切换为土耳其语、西班牙语、日语……?** 设置 → Composer Plus → **应用语言**。
310
321
 
@@ -343,6 +354,8 @@ PLAYWRIGHT=/path/to/playwright node test/browser-readme-anchors.mjs
343
354
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-keep-focus.mjs /path/to/dsh/lib/bin.js
344
355
  # Fit question card to window (fake model asks a long question at 1280 × 820): question, answers, Skip and Submit readable, height follows the window + its thumbnail
345
356
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-question-fit.mjs /path/to/dsh/lib/bin.js
357
+ # Fit chat header to window (fake model, subagent + background jobs, branch pill, grants chip): no overlap from 1280 to 320 px, wide header unchanged + its thumbnail
358
+ SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-header-fit.mjs /path/to/dsh/lib/bin.js
346
359
  # Mobile connect: switch on, QR popover, a fake iPhone pairs and calls dsh through the gateway, switch off + its thumbnail
347
360
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-mobile-connect.mjs /path/to/dsh/lib/bin.js
348
361
  # Resume after restart (fake slow model, real quit and start): a running chat and a goal continue, a stopped chat does not
Binary file
Binary file
Binary file