Actually you don't need to read our docs, just ask Clark questions

Thật ra bạn không cần đọc docs đâu, cứ hỏi Clark là được.

Hỏi ngay từ terminal:

clarkcant ask "how do I connect Cursor to you?"

Hiện CLI chạy từ một bản checkout của ClarkCant, nên nếu chưa đặt alias thì câu hỏi trên sẽ là:

# From a ClarkCant checkout (the CLI is not published to npm yet)
node apps/cli/src/main.ts ask "how do I connect Cursor to you?"

Hoặc, từ bất kỳ công cụ AI nào nói được MCP (Claude Desktop, Cursor, …), gọi tool ask_clark:

{ "jsonrpc": "2.0", "id": 1, "method": "tools/call",
  "params": { "name": "ask_clark", "arguments": { "text": "how do I connect Cursor to you?" } } }

Các trang còn lại dành cho lúc bạn cần chính xác route, frame và cờ dòng lệnh.

Xây trên chuẩn mở

ClarkCant là một cuộc trò chuyện với một Clark. Cùng một Clark đó có thể được gọi qua những giao diện mở, phổ biến, nên mọi ứng dụng bên thứ ba, script hay công cụ AI đều điều khiển được mà không cần SDK riêng:

Một token, một gateway, cùng một ngữ nghĩa ở mọi nơi. Mọi giao diện đều do cùng một runtime node phục vụ, cùng origin, cùng bearer token. Không có tầng xử lý nghiệp vụ thứ hai: một tool MCP, một request WebSocket hay một lệnh CLI đều đi tới cùng một handler của HTTP gateway, nên chúng hoạt động y hệt lệnh REST bên dưới.

Phê duyệt (approval) cố ý không có trên MCP. Quyết định phê duyệt là việc của con người. Một client AI không được phép tự phê duyệt hành động cần kiểm soát của chính nó, nên không có tool MCP nào cho việc này.

Hộp thư và thông báo

Mở hộp thư từ huy hiệu ở đầu ứng dụng, bằng bàn phím, hoặc yêu cầu Clark bằng chữ hay giọng nói: “mở hộp thư”. Hộp thư tập hợp yêu cầu duyệt lệnh, quyền của gói, yêu cầu duyệt do task đang chạy tạo ra, câu hỏi chưa trả lời và thông báo đã lưu về công việc nền, yêu cầu hết hạn và bản cập nhật. Công cụ control_app của Clark cũng mở cùng hộp thư này.

Duyệt yêu cầu của task đang chạy cho phép node chạy lại task; nếu node chưa nhận được lượt chạy, Clark nói rõ chưa có gì chạy và bạn có thể yêu cầu lại. Từ chối hoặc hết hạn sẽ kết thúc task. Quyết định đó thuộc về bạn; các giao diện máy từ chối thao tác này. Xem quyết định yêu cầu duyệt của task.

Cài đặt → Điều khiển có thông báo hệ điều hành trên desktop và Web Notifications trên trình duyệt, với công tắc theo nhóm và giờ yên tĩnh. Trình duyệt phải cấp quyền thông báo. Thông báo chỉ hiện khi ứng dụng bị ẩn, mất focus hoặc ở chế độ orb/thu gọn; nội dung đã che dữ liệu nhạy cảm và không bao giờ chứa dòng lệnh. Bấm thông báo sẽ mở đúng mục trong hộp thư; nếu mục đã được xử lý, ứng dụng nói rõ điều đó.

Nếu hệ điều hành từ chối hoặc không hiện được thông báo, trạng thái ngay cạnh công tắc thông báo hệ điều hành giải thích lý do và cho biết mục vẫn còn trong hộp thư. Trạng thái này biến mất khi một thông báo được hiện lại thành công. Kiểm tra cập nhật chỉ đề xuất phiên bản trình cài đặt chấp nhận trên máy của bạn và giữ im lặng khi node ngoại tuyến.

Cửa sổ ứng dụng desktop

Ứng dụng desktop mở lại cửa sổ hội thoại đúng nơi bạn để: cùng vị trí và kích thước, phóng to hoặc toàn màn hình nếu lúc đóng nó đang như vậy. Nếu màn hình đó không còn được kết nối, hoặc cửa sổ sẽ mở ra ở chỗ không với tới được, nó mở ở vị trí và kích thước mặc định. Cửa sổ được nhớ từ một màn hình lớn hơn sẽ được thu lại cho vừa.

Nhãn theo ngôn ngữ giao diện

Thẻ task ghi trạng thái và bằng chứng bằng ngôn ngữ giao diện, ví dụ “cần bạn quyết định” hay “chưa rõ kết quả”; trạng thái mà phiên bản này chưa biết được hiện đúng như được gửi. Trong thư viện widget, nguồn của mỗi widget (Có sẵn, Gói đã cài, Gói đang phát triển trên máy) và trạng thái (Ổn định, Thử nghiệm) cũng được ghi như vậy. Cài đặt → Tiện ích liệt kê mỗi công cụ theo việc nó làm, kèm tên bên cạnh, dưới “Của node này” và “Của agent (pi)”; chỉ dẫn mà model nhận được cho một công cụ nằm sau “Chỉ dẫn cho model”.

Terminal trong hội thoại

Yêu cầu Clark bằng chữ hoặc giọng nói “mở terminal trong thư mục dự án” để mở shell thật ngay trong hội thoại. Các chương trình toàn màn hình như vim và htop hoạt động tại đây. Lệnh Clark đề xuất đi qua chính sách thực thi của bạn; khi cần bạn duyệt, lệnh chỉ được điền sẵn và chạy khi bạn nhấn Enter. Clark không ghi đè dòng bạn đang nhập. Nhấn F6 để chuyển focus ra khỏi terminal.

Gửi vùng chọn, kết quả lệnh đã kết thúc gần nhất hoặc màn hình về hội thoại; nút nói rõ nội dung nào sẽ được gửi, và chuỗi giống thông tin xác thực được che trước khi model nhìn thấy. Mỗi terminal chỉ có một bên điều khiển: thẻ khác theo dõi và có thao tác “Điều khiển tại đây”. Bảng Tiến độ liệt kê terminal khác, lượt chạy lệnh và công việc nền. Thẻ báo đúng trạng thái đang kết nối, mất kết nối kèm kết nối lại, đã kết thúc kèm mã thoát, không còn trên node hoặc không dùng được vì node không có PTY.

Cài đặt → Widget → Duyệt liệt kê Terminal trong Thẻ hệ thống, với mô tả, hình minh họa tĩnh được ghi rõ là minh họa và gợi ý yêu cầu Clark mở. Không có xem trước trực tiếp hay nút mở. Tìm kiếm có hoặc không có dấu tiếng Việt đều được; chọn nhóm khác Tất cả sẽ ẩn Thẻ hệ thống. Socket /terminal thuộc về thẻ này của ứng dụng.

Bảng Kanban trong hội thoại

Khi câu trả lời có bảng, bạn có thể di chuyển thẻ bằng chuột, cảm ứng hoặc bàn phím. Bảng có sẵn hiển thị công việc Clark đã biết; bản thân nó không kết nối tới dịch vụ quản lý dự án. Nếu bảng được gắn action để đổi dữ liệu ở nơi khác, yêu cầu đó đi qua luồng action và policy thông thường của Clark. Xem tiêu chuẩn phát triển widget (§8.10).

Cây phân cấp

Khi Clark đã có sẵn thông tin phân cấp, thông tin đó có thể hiện thành outline lồng nhau bằng canvas.tree@1. Mỗi mục có id ổn định và nhãn, cùng chữ phụ, icon thuộc một nhóm cố định và các mục con tùy chọn. Đây là cách xem thông tin đã biết, không phải trình duyệt tệp: cây không đọc service, còn việc đổi lựa chọn hay mở nhánh không sửa dữ liệu nguồn. Lựa chọn và các nhánh đang mở được lưu cùng widget và khôi phục theo pin; ID đã lưu nhưng không còn trong cây mới sẽ bị bỏ qua.

Phím mũi tên di chuyển giữa các mục đang hiện và mở hoặc đóng nhánh; Home và End tới hai đầu, gõ chữ để tìm nhãn, Enter hoặc Space để chọn mục. Trình đọc màn hình nhận được cấp, vị trí, số mục trong nhóm, trạng thái chọn và trạng thái mở của mỗi mục. Node kiểm tra giới hạn cây trước khi hiển thị. Xem hợp đồng và giới hạn của cây cùng hướng dẫn phát triển widget nội bộ.

Sơ đồ và đồ thị

Khi Clark có một luồng, một đồ thị phụ thuộc hay một cây nhỏ cần hiển thị, Clark có thể vẽ bằng canvas.diagram@1. Ứng dụng tự dựng SVG và không có gì trong đó được thực thi: nhãn là chữ, hình và đường là các con số từ một bố cục dùng chung, và không có HTML, foreignObject, liên kết, ảnh, style hay handler nào mà một nhãn có thể gọi tới.

Sơ đồ có tối đa 60 node và 120 cạnh. ID node dài tối đa 64 ký tự gồm chữ cái ASCII, chữ số, _ và -. Nhãn là một dòng tối đa 80 ký tự, nhãn cạnh tối đa 40, tên nhóm tối đa 40 và tiêu đề tối đa 200. Hình của node là box, round, diamond hoặc circle. Hướng của cạnh là forward, both hoặc none, và cạnh có thể mang nhãn. Nhóm chỉ có một cấp. Node từ chối ID node bị lặp, cạnh trỏ tới node không tồn tại, cạnh từ một node về chính nó, cùng một cạnh hai lần, quá nhiều node hoặc cạnh, trường lạ và ký tự ẩn, và mỗi lần từ chối đều nói lý do bằng câu của chính host.

layout là layered (mặc định) hoặc tree, còn direction là TB (từ trên xuống) hoặc LR (từ trái sang phải). Bố cục phân lớp phá vòng, chia node thành lớp theo đường dài nhất và bẻ các cạnh dài qua những lớp chúng đi ngang. Bố cục cây đặt node con cân giữa dưới node cha và từ chối đồ thị không phải là rừng. Khoảng trống chứa nhãn cạnh được nới rộng cho vừa nhãn, và các cạnh nối cùng hai node được vẽ tách nhau. Bố cục là tất định: cùng props luôn cho cùng một hình vẽ trên node và trên mọi client, và đồ thị lớn nhất được chấp nhận được dàn trong thời gian có giới hạn.

Lưu đồ Mermaid

Clark cũng có thể đưa cho show_view một lưu đồ Mermaid: { "mermaid": "flowchart LR ...", "title"?, "layout"? }. Node tự đọc một tập con được tài liệu hóa của cú pháp flowchart và chỉ giữ lại mô hình sơ đồ thu được. Node không bao giờ lưu mã nguồn Mermaid và không bao giờ tải renderer của Mermaid. Tập con gồm:

Mã nguồn nêu quá 60 node hoặc 120 liên kết bị từ chối ngay khi vượt giới hạn. Mọi thứ cấu hình hoặc mở rộng renderer của Mermaid đều bị từ chối theo dòng, kèm lý do: click, href, call, style, classDef, class, :::, linkStyle, directive %%{init}%%, front matter, HTML hoặc mã entity trong nhãn, chuỗi Markdown, icon fa:, các hình node khác, các kiểu liên kết khác, chuỗi &, subgraph lồng nhau và các loại sơ đồ khác.

Chọn node và bàn phím

Chọn một node sẽ gửi diagram.select với { selectedId }. Node kiểm tra giá trị này với sơ đồ hiện tại và giữ nó trong trạng thái widget, nên lựa chọn vẫn còn sau khi tải lại; ID đã khôi phục mà sơ đồ không còn chứa sẽ bị bỏ qua.

Mỗi node là một nút, và chỉ một node nằm trong thứ tự tab. Phím theo chiều luồng (Xuống với TB, Phải với LR) đi theo một cạnh về phía trước, còn phím ngược lại đi theo cạnh quay về. Các phím ngang đi trong cùng một lớp, Home và End tới node đầu và node cuối. Enter hoặc Space chọn node đang có tiêu điểm, hoặc bỏ chọn nếu node đó đã được chọn, còn Escape bỏ chọn. Tên truy cập của node nói rõ nhãn, hình và nhóm, cùng các node nó dẫn tới, đến từ và nối với, mỗi node kèm nhãn của cạnh nối chúng (“dẫn tới Ship (yes)”). Node được chọn làm nổi các cạnh và node kề bằng độ dày nét và nét đứt chứ không chỉ bằng màu, và một vùng live thông báo thay đổi. Hình vẽ rộng giữ nguyên kích thước và cuộn bên trong thẻ, nên trang không bao giờ cuộn ngang. Sơ đồ không tự tạo chuyển động và theo cả hai theme.

Tài liệu semantic báo số node và cạnh, bố cục và hướng, cùng node được chọn với các node kề và nhãn cạnh của chúng. Phần thay thế dạng chữ, cũng hiện dưới hình vẽ, liệt kê mọi node cùng các cạnh đi ra của nó. Xem bộ đọc tập con Mermaid và tiêu chuẩn phát triển widget (§8.12).

Giới hạn hiện tại. Khi hai cạnh có nhãn cùng rời một node vào cùng một khoảng trống, các nhãn có thể nằm sát nhau; nhãn luôn tránh xa các node. Giống cây phân cấp, sơ đồ chưa thể được đặt làm một phần của giao diện Clark dựng sẵn.

Bản đồ

Khi Clark có những địa điểm cần cho bạn xem, nó có thể vẽ chúng trên bản đồ bằng canvas.map@1: các điểm có nhãn, các đường như lộ trình, và các vùng. Bản đồ được vẽ trên một bản đồ nền ngoại tuyến đi kèm ứng dụng, nên với thiết lập mặc định, bản đồ không gửi yêu cầu nào ra ngoài node của bạn và không ai biết bạn đang xem phần nào của thế giới.

Bản đồ nền là lớp đất liền tỷ lệ 1:110m của Natural Earth, phiên bản 5.1.2, thuộc phạm vi công cộng. Nó được tạo bởi một script build ghim SHA-256 của tệp nguồn, và bản đồ ghi công Natural Earth dưới mọi hình vẽ.

Bản đồ chứa những gì

Vị trí là [kinh độ, vĩ độ] theo WGS84, trong một tập con chặt của hình học GeoJSON: Point, LineString và Polygon, tức một đường bao với tối đa 15 lỗ, mỗi vòng đều khép kín. Một bản đồ chứa tối đa 200 đối tượng và tổng cộng 5.000 vị trí. ID dài tối đa 120 ký tự, nhãn 120, mô tả 300 và tiêu đề 200. Bản đồ tự khớp với các đối tượng của nó, hoặc một view tùy chọn dạng { center, zoom }, với mức zoom nguyên từ 0 đến 18, sẽ thay cho khung nhìn đã khớp. Mã hóa địa lý, tìm đường, vị trí thiết bị của bạn, vector tile, 3D, gom cụm và chỉnh sửa không thuộc widget này, và bản đồ không bao giờ hỏi vị trí của bạn.

Node từ chối một bản đồ trước khi nó được hiển thị, và nói rõ lý do: tọa độ nằm ngoài địa cầu, loại hình học không xác định, quá nhiều đối tượng hoặc vị trí, văn bản quá dài hoặc lặp lại, ký tự ẩn, và bất kỳ URL nào. Một khóa mang tên đường dẫn (url, href, src, tile, endpoint và những khóa tương tự) hoặc một giá trị là đường dẫn (https://, //, data:, javascript:, blob:) đều bị từ chối, nên props của bản đồ không bao giờ có thể nêu tên một máy chủ. Những địa điểm Clark đặt lên bản đồ là phát biểu của Clark, và bản đồ không mang huy hiệu “trực tiếp” nào.

Ô bản đồ, chỉ khi bạn chọn một nhà cung cấp

Ô bản đồ. Bản đồ luôn có nền ngoại tuyến và hoạt động đầy đủ mà không cần ô bản đồ, vốn tắt theo mặc định. Để thêm ô từ nhà cung cấp, mở Cài đặt → Tiện ích → Ô bản đồ và nhập origin, đường dẫn ô, ghi công và mức phóng to tối đa của nhà cung cấp. Việc này đặt chính sách ô bản đồ của node, tức preference maps.tilePolicy, nêu tên một nhà cung cấp. Nếu nhà cung cấp cần khóa, nhập khóa cùng header hoặc tham số truy vấn chứa nó. Khóa được gắn với origin bạn nhập nó cho: ClarkCant chỉ gửi khóa tới origin đó và không bao giờ hiển thị lại. Bạn cũng có thể nhờ Clark bật hoặc tắt ô bản đồ. Clark làm theo execution policy của bạn: ở chế độ Tự chủ, thay đổi diễn ra ngay và có thể hoàn tác trong Cài đặt; ở chế độ Hỏi mỗi lần, bạn duyệt trên một thẻ. Ở chế độ Có rào, việc đặt nhà cung cấp hỏi bạn trên một thẻ còn việc tắt ô bản đồ diễn ra ngay, và Từ chối tất cả từ chối cả hai. Clark không bao giờ chuyển được khóa của bạn. Nếu Clark đặt một nhà cung cấp cần khóa ở origin khác, bản đồ chỉ dùng nền ngoại tuyến cho tới khi bạn nhập lại khóa cho nhà cung cấp đó. GET /map-tiles cho biết lý do bản đồ chỉ dùng nền ngoại tuyến trong trường offline: no-provider, key-unavailable (chưa lưu khóa dùng được) hoặc key-origin-mismatch (khóa đã lưu thuộc origin khác).

Các AI client qua MCP, relay WebSocket và clarkcant api không thể ghi trực tiếp chính sách hay khóa: các route đó trả về 403 PERSON_ONLY, và client nào muốn đổi ô bản đồ thì nhờ Clark. Các route được liệt kê trong API của node.

Lựa chọn, bàn phím và bảng

Chọn một đối tượng sẽ gửi map.select với { selectedId }, để trống để bỏ chọn, và di chuyển bản đồ sẽ gửi map.view với { center, zoom }. Node kiểm tra cả hai với bản đồ hiện tại và giữ chúng trong trạng thái widget, nên lựa chọn và khung nhìn vẫn còn sau khi tải lại. Một lần kéo được lưu 400 ms sau khi dừng, nên một loạt phím bấm chỉ là một lần ghi. Trong giao diện Clark dựng sẵn, map.select cũng là một sự kiện có trường selectedId mà các phần khác có thể theo.

Bản đồ có thể nhận tiêu điểm và dùng được bằng bàn phím:

Kéo bằng con trỏ cũng di chuyển bản đồ. Trên màn hình cảm ứng, vuốt qua một bản đồ bạn chưa chạm vào sẽ cuộn cuộc trò chuyện; khi bạn đã chạm vào bản đồ, kéo sẽ di chuyển nó. Các nút phóng to, thu nhỏ và đặt lại có kích thước 44 px. Một vùng live thông báo khung nhìn khi nó dừng lại, và cả lựa chọn. Bản đồ chỉ trượt khi chuyển động được cho phép; khi giảm chuyển động, khung nhìn đổi ngay lập tức. Bản đồ theo cả hai theme, và bản đồ hẹp chuyển các nút điều khiển xuống dưới hình và vẽ nhãn lớn hơn, không tràn ngang ở 390 px.

Dưới bản đồ, một bảng liệt kê mọi đối tượng cùng loại và vị trí của nó. Nút Chọn của bảng chọn đối tượng trên bản đồ và đưa nó vào khung nhìn, còn chọn trên bản đồ sẽ làm nổi hàng tương ứng. Bảng đó cũng là phần thay thế dạng chữ của bản đồ.

Tài liệu semantic báo số đối tượng và số lượng từng loại, ranh giới và mức zoom đang hiển thị, nhãn và tọa độ của đối tượng được chọn, và ô bản đồ đang ngoại tuyến hay đến từ origin của chính sách. Xem hợp đồng bản đồ và các giới hạn và tiêu chuẩn phát triển widget (§8.13).

Giới hạn hiện tại. Bản đồ là một thế giới duy nhất không lặp lại: khung nhìn dừng ở kinh tuyến đổi ngày, và bản đồ không cuộn vòng qua kinh tuyến 180°. Bản đồ nền, các đối tượng và ô bản đồ đều được vẽ một lần, nên chúng luôn khớp nhau.

Trình phát âm thanh và xem trước tài liệu

Clark có thể phát một âm thanh bằng canvas.audio@1 và hiển thị văn bản của một tệp PDF hoặc tệp văn bản bằng canvas.document@1. Trang không bao giờ tự tải gì cho cả hai widget này. Clark nêu tên một nguồn, còn node của bạn đọc nó, kiểm tra nó theo chính sách nội dung media và chỉ lưu những gì đã được kiểm tra.

Âm thanh đến từ đâu

Clark nêu đúng một nguồn, một tiêu đề và, nếu có, một bản chép lời dài tối đa 4.000 ký tự:

Node của bạn tự điền tham chiếu mà trang phát, loại tệp, độ dài và kích thước, và với tệp được tải về thì cả origin nguồn. Clark không thể tự cung cấp những giá trị này, nên trình phát không bao giờ khai một loại tệp hay một độ dài mà không ai kiểm tra. Trang chỉ thấy tham chiếu đến một tệp do node của bạn giữ, không bao giờ thấy URL bên ngoài. Các bước kiểm tra loại tệp, kích thước và độ dài cũng áp dụng cho tệp âm thanh bạn đã có sẵn.

Phát âm thanh

Trình phát dùng các nút điều khiển sẵn có của trình duyệt, kể cả bàn phím: đưa tiêu điểm vào nó rồi nhấn Space để phát hoặc tạm dừng. Nó không bao giờ tự phát, kể cả khi mới xuất hiện hay khi được khôi phục. Nó giữ lại trạng thái đang phát hay không, vị trí đang nghe và độ dài, được ghi theo cùng cách như video, nên sau khi tải lại trang nó mở ở trạng thái tạm dừng đúng chỗ bạn đã dừng. Bản chép lời, nếu có, là văn bản thuần trong một mục bạn có thể mở bằng bàn phím, và ký tự ẩn trong đó được vẽ thành một dấu hiệu nhìn thấy được. Giọng nói, ghi chú thêm vào lượt hỏi kế tiếp và inspect_ui biết tiêu đề, trạng thái phát, vị trí và độ dài, và có bản chép lời hay không.

Xem trước tài liệu

Clark nêu tên một tệp PDF hoặc tệp văn bản trong cuộc hội thoại này (văn bản thuần, Markdown, CSV, giá trị phân tách bằng tab hoặc JSON), theo ID artifact hoặc ID tệp đính kèm. Node của bạn đọc văn bản của nó, với PDF thì qua bộ đọc riêng của node, và giữ tối đa 20.000 ký tự trong tối đa 10 trang, mỗi trang tối đa 2.000 ký tự, ngắt ở cuối dòng hoặc ở một khoảng trắng. Một thông báo cho biết khi bản xem trước bị cắt bớt và đang hiển thị bao nhiêu. Bản xem trước chỉ là văn bản: hình ảnh và bố cục không được hiển thị, và không gì trong tệp được coi là markup hay được chạy. Ký tự ẩn được vẽ thành dấu hiệu, kèm cảnh báo.

Văn bản của trang nằm trong một vùng mà bàn phím có thể tới. Tab chuyển tới các nút Trước và Sau, còn Enter lật trang. Ở trang đầu hoặc trang cuối, nút vẫn giữ tiêu điểm và được thông báo là không khả dụng, trang mới mở từ đầu, và số trang trên tổng số trang được thông báo một cách nhẹ nhàng. Trang bạn đang xem được lưu cùng widget, nên vẫn mở sau khi tải lại, và giọng nói, ghi chú cho lượt hỏi kế tiếp và inspect_ui đều biết nó. Tệp WAV không phải tài liệu, và bản xem trước từ chối nó.

Cả hai widget theo cả hai theme và vừa khít ở 390 px. Khi giảm chuyển động, chúng không thêm hiệu ứng động hay chuyển tiếp nào. Hiện chưa widget nào có thể được đặt làm một phần của giao diện Clark dựng sẵn: mỗi widget được hiển thị riêng, nơi node của bạn kiểm tra nguồn của nó. Thư viện Widget hiển thị các thẻ mẫu; thẻ âm thanh mẫu nói rằng nó không phát được thay vì giả vờ.

Chính sách nội dung media

Node của bạn chỉ tải âm thanh từ web về từ những origin bạn liệt kê trong CC_MEDIA_ORIGINS, một danh sách các origin https trần phân tách bằng dấu phẩy, tối đa 32 mục. Danh sách này mặc định để trống, nên node của bạn không tải gì cho tới khi bạn nêu tên một origin. Một danh sách có bất kỳ mục nào không phải origin https trần sẽ bị bỏ qua toàn bộ: node của bạn không cho phép gì và nói lý do một lần khi khởi động. Mỗi lần tải tuân theo các quy tắc sau:

Mỗi lần từ chối kết thúc bằng quy tắc bị vi phạm, dạng (media policy rule: <rule>), để Clark có thể nói cho bạn biết cần đổi gì. Tệp vượt qua kiểm tra được tính vào dung lượng lưu trữ của bạn. Chính sách nội dung của trang không đổi. Xem tên các quy tắc, hợp đồng nội dung media và tiêu chuẩn phát triển widget (§8.14 và §14.5).

Giới hạn hiện tại. Khi một cuộc hội thoại được tải, trang đọc toàn bộ tệp của mọi trình phát đã đặt, dù nó không phát gì cho tới khi bạn nhấn phát; việc chỉ đọc khi cần được theo dõi ở #403. Mỗi lần lưu vị trí phát là một lần ghi trọn trạng thái widget, chi phí này được theo dõi ở #380.

Ảnh và video trong hội thoại

Gallery hoặc carousel giữ lại ảnh bạn đã chọn. Lựa chọn được lưu cùng widget, nên vẫn còn sau khi tải lại trang hoặc khôi phục pin. Video cục bộ giữ lại trạng thái đang phát hay không, vị trí đang xem và độ dài. Khi mở lại, video dừng ở đúng vị trí đó và không bao giờ tự phát.

Clark biết bạn đang xem gì. Giọng nói, ghi chú thêm vào lượt hỏi kế tiếp và công cụ inspect_ui của Clark mô tả ảnh đang chọn (ảnh thứ mấy trên tổng số, kèm văn bản thay thế) hoặc trạng thái phát của video. Khi video đang phát, vị trí được lưu tối đa ba giây một lần, và lưu ngay khi bạn tạm dừng, tua hoặc video kết thúc. Việc lưu khi bạn rời trang chỉ là cố gắng tốt nhất, nên trạng thái “đang phát” cũ hơn tám giây được báo là đã dừng tại vị trí lưu gần nhất. Nếu máy của bạn từ chối một lần lưu, widget nói lý do ngay bên cạnh: gallery hoặc carousel hiện lại ảnh đã lưu, còn video giữ nguyên vị trí.

Giao diện Clark dựng cho bạn có thể chứa gallery hoặc carousel gồm chính các ảnh bạn đã nhập, mới nhất trước. Clark chỉ chọn widget và cách nối nó; ảnh Clark tự nêu sẽ bị bỏ qua. Chọn một ảnh sẽ gửi media.select với { selectedIndex }, đếm từ 0, nên phần khác của giao diện nối cùng giá trị đó sẽ đi theo và trạng thái của giao diện báo lại giá trị này.

Chính sách của trang và cửa sổ desktop cho phép media-src 'self' blob:, chỉ để video phát được từ object URL mà ứng dụng tạo ra từ dữ liệu đã tải bằng token của node. Không cho phép nguồn media từ xa và không cho phép media data:.

Giới hạn hiện tại. Node chưa nhập được tệp video, nên video cục bộ chỉ phát từ tham chiếu mà node đã phục vụ sẵn. Gallery hoặc carousel trong giao diện dựng sẵn giữ các ảnh có mặt lúc giao diện được dựng; ảnh nhập sau chỉ xuất hiện trong giao diện dựng mới. Mỗi lần lưu vị trí phát vẫn là một action đầy đủ của widget; việc giảm chi phí này được theo dõi ở #380. Xem tiêu chuẩn phát triển widget (§8.11).

Bắt đầu nhanh

  1. Chạy một node. Trình cài đặt sẽ dựng sẵn; từ bản checkout thì chạy node apps/runtime/src/main.ts. Node nghe ở http://127.0.0.1:8765, mặc định chỉ trên loopback.
  2. Lấy token: trường localToken trong <data-dir>/identity.json. Thư mục dữ liệu mặc định là ~/.clarkcant; với Docker thư mục dữ liệu là /data (token trong /data/identity.json).
  3. Kiểm tra node và khám phá các giao diện của nó. Ba route này không cần token:
export CLARKCANT_URL="http://127.0.0.1:8765"
export CLARKCANT_TOKEN="<token>"   # localToken from <data-dir>/identity.json
# Public: no token needed
curl -s "$CLARKCANT_URL/health"
curl -s "$CLARKCANT_URL/.well-known/clarkcant.json"
curl -s "$CLARKCANT_URL/openapi.json"

/health báo node còn sống, nền tảng runtime và giao thức đã thương lượng, không kèm danh tính node. /.well-known/clarkcant.json liệt kê mọi giao diện (api, mcp, websocket, cli) và endpoint của chúng. /openapi.json mô tả phần REST ổn định.

Rồi gửi cho Clark tin nhắn đầu tiên:

# 1. Create a conversation → 201 { "conversationId": "…", "homeNodeId": "…" }
curl -s -X POST "$CLARKCANT_URL/conversations" \
  -H "Authorization: Bearer $CLARKCANT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "title": "From my app" }'

# 2. Talk to Clark in it
curl -s -X POST "$CLARKCANT_URL/conversations/<conversationId>/messages" \
  -H "Authorization: Bearer $CLARKCANT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "text": "What can you do on this machine?" }'

Xác thực và lỗi

{ "code": "UNAUTHENTICATED", "message": "…" }

Giữ kín token. Token cho toàn quyền với Clark của bạn. Mặc định node chỉ lắng nghe trên loopback; --allow-public-bind mở nó ra ngoài và cần TLS đứng trước. Chưa có đăng nhập OAuth: bearer token là thông tin xác thực duy nhất.

Clark chọn ngữ cảnh thế nào

Các biến môi trường sau trên node chọn ngữ cảnh mà Clark gửi cho model cùng mỗi tin nhắn:

Nội dung gửi tới provider của Jev (chỉ khi CLARKCANT_CONTEXT_DECIDER=jev và chỉ khi Jev được hỏi): tin đang được trả lời, đã che thông tin nhạy cảm, tối đa 300 ký tự (400 ký tự khi chọn nhóm tool), cùng từng ghi nhớ hay tin cũ hơn là ứng viên, đã che, tối đa 200 ký tự. Không có gì khác rời khỏi node, và Jev không cấp quyền gì.

Model được nhận những gì

Mỗi khối node của bạn thêm vào ngữ cảnh của một model được gắn nhãn public, internal, confidential hoặc secret, chỉ từ chính văn bản của nó và trước khi bất cứ thứ gì được xếp hạng hay gửi đi:

Một model profile có thể nêu nó được nhận gì bằng trustClass (local, first-party, approved-third-party hoặc untrusted) và allowedDataClasses. Theo trust class, local được nhận mọi thứ, kể cả secret; first-party và approved-third-party tới confidential; untrusted chỉ public. Có cả hai thì profile chỉ nhận những gì cả hai cho phép. Một danh sách không kèm trust class được lấy đúng như đã viết, nên nó có thể thêm secret cho một profile chưa gắn nhãn. Profile không có cả hai được nhận mọi thứ trừ secret, và một model được nhiều profile nêu chỉ nhận những gì tất cả cho phép.

Khi CLARKCANT_CONTEXT_PLANNER bật, khối vượt trần của model đang trả lời bị bỏ khỏi phần tóm tắt, bản ghi nhớ, các tin cũ hơn, ngữ cảnh mà việc chạy nền hay task worker truy xuất (kể cả các lần đọc read_context), hướng dẫn dự án và kết quả của search_history, mỗi kết quả được xét trên toàn bộ mục đã lưu, không chỉ đoạn trích hiển thị. Mỗi chỗ chỉ báo số khối bị giữ lại, không bao giờ báo nội dung, và phần tóm tắt không chỉ tới công cụ nào để đọc lại chúng. Jev chỉ được đưa ứng viên public và internal.

Việc chạy nền bỏ qua model profile không được nhận mức dữ liệu của công việc (mức của yêu cầu hoặc mục tiêu task), dù planner bật hay tắt. Khi không profile nào đạt, công việc vẫn chạy trên model đã cấu hình của node: chính văn bản yêu cầu hoặc mục tiêu được gửi tới model đó bất kể mức của nó, và chỉ ngữ cảnh đã truy xuất bị thu hẹp về những gì model đó được nhận. Khi chính mức dữ liệu làm mọi profile bị loại, node ghi một dòng JSON trên stderr (model-route, chỉ gồm mức dữ liệu và số đếm), và bản ghi audit của task nói rằng công việc chạy trên model của node vì không model nào trong nhóm được nhận mức dữ liệu đó; bản ghi nêu tên mức dữ liệu, không bao giờ nêu mục tiêu. Khi chính việc định tuyến thất bại, công việc cũng chạy trên model đã cấu hình, kèm một dòng model-route đánh dấu route-failed không chứa nội dung lỗi.

Phạm vi. Trần này chỉ áp dụng cho ngữ cảnh do node của bạn thêm vào. Nó không áp dụng cho kết quả công cụ mà model tự đọc (một tệp, đầu ra của lệnh, một trang web), tệp đính kèm người dùng gửi, hay những gì một session đang tiếp tục đã giữ từ các lượt trước; nó không phải ranh giới đối với những thứ đó, và một model không bao giờ được thấy một mức dữ liệu nào đó thì không nên được giao công cụ có thể đọc nó. CLARKCANT_CONTEXT_PLANNER=off tắt việc giữ lại, kể cả với search_history, nên văn bản dạng bí mật trong phần tóm tắt, bộ nhớ và lịch sử tới được bất cứ model nào trả lời; định tuyến theo mức dữ liệu vẫn áp dụng khi planner tắt.

Hướng dẫn dự án

Một dự án có thể giữ hướng dẫn chỉ áp dụng cho một phần của nó. Node của bạn chỉ đọc chúng từ một dự án nằm trong thư mục bạn đã cấp quyền: .clarkcant/instructions.json chứa tối đa 32 rule, và mỗi tên được include là tệp .clarkcant/instructions/<name>.md.

{
  "version": 1,
  "rules": [
    {
      "when": { "path": "src/payments/**", "operation": "write" },
      "include": ["payments"],
      "pin": false
    }
  ]
}

Hướng dẫn đến với model dưới dạng dữ liệu của dự án: một tiêu đề nói rằng chúng đến từ tệp .clarkcant của dự án, không phải lời của bạn hay của node, và không cấp quyền gì. Mỗi hướng dẫn được bọc trong một thẻ mang một mã node của bạn tạo một lần cho mỗi session (session được dựng lại hoặc được bàn giao sẽ có mã mới) và nêu một lần, trong chính lời hướng dẫn của node ở đầu session đó, như mã duy nhất đánh dấu hướng dẫn dự án; brief của task worker tự nêu mã của nó. Một hướng dẫn không thể tự đóng khối của nó, và một khối bị chép vào tệp hay đầu ra của công cụ mang mã mà node không nêu cho session đó, trừ khi chính session đã lặp lại mã. Đây là tín hiệu để model đọc, không phải ranh giới được cưỡng chế: chính sách thực thi quyết định một hành động được phép làm gì, và hướng dẫn không cấp quyền gì trong mọi trường hợp. Không có bước bật riêng: hướng dẫn của dự án áp dụng vì bạn đã cấp quyền thư mục của nó, và mọi tác động vẫn đi qua chính sách thực thi. Hướng dẫn được gắn nhãn như mọi khối khác và bị giữ lại khi vượt trần của model. Giới hạn: 8 tên mỗi rule, 4.000 ký tự mỗi hướng dẫn, 6.000 mỗi lượt và tệp rule 64 KB. Tệp mà node không dùng được sẽ được báo một lần trên stderr (instructions-invalid, gồm tên thư mục và lý do: too-large, not-json, shape hoặc unknown-version) và không thay đổi gì. CLARKCANT_CONDITIONAL_INSTRUCTIONS=off (mặc định bật) tắt tính năng này.

Khi nào hội thoại được session mới

Một hội thoại giữ một session model cho tới khi nó lỗi, bị dọn hoặc đổi model. CLARKCANT_SESSION_POLICY (mặc định off) quyết định ở mỗi lượt có giữ nó hay không:

Dựng lại tạo một session mới được brief bằng phần tóm tắt đã lập, nêu lại hướng dẫn và tool, và không đụng tới chính hội thoại. Nếu không tạo được session mới, hoặc bước policy bị lỗi, lượt tiếp tục trên session cũ. Tin nhắn gửi trong lúc dựng lại sẽ chờ việc dựng lại xong và vào session mới, và Stop trong lúc dựng lại sẽ bỏ session mới và không gửi gì. Giá trị khác là off. Các ngưỡng là phán đoán từ một mô phỏng chi phí có kịch bản, không phải số đo thực tế.

Khi bạn đổi model

Đổi model không bao giờ cắt ngang câu trả lời Clark đang viết: thay đổi có hiệu lực từ tin nhắn tiếp theo của bạn, tin nhắn đó bắt đầu một session mới trên model mới, được brief bằng phần tóm tắt cuộc trò chuyện. Clark không bao giờ trả lời bằng model cũ thay vào đó. Nếu đổi model thất bại, lượt đó báo lỗi bằng ngôn ngữ của bạn và cuộc trò chuyện được giữ nguyên, ví dụ: “Không chuyển được cuộc trò chuyện này sang {provider/model}: {lý do}. Tin nhắn của bạn đã được lưu và cuộc trò chuyện vẫn giữ nguyên. Hãy thử lại, hoặc chọn model khác.” Đường dẫn tệp cục bộ được xoá khỏi lý do. Nếu việc chuẩn bị trả lời lâu hơn thời gian cho phép của lượt, lượt đó dừng với “Không chuẩn bị xong để trả lời trong {N} giây, nên lượt này đã dừng. Tin nhắn của bạn đã được lưu. Hãy thử lại, hoặc chọn model khác nếu lỗi này lặp lại.”

Đọc tiếp