dsh-composer-plus 1.21.0 → 1.22.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/index.js CHANGED
@@ -709,6 +709,19 @@ export const shippedNotes = (text, version = PACKAGE.version) => {
709
709
  .map(([id, body]) => [id, releaseNotes(body)]).filter(([, body]) => body !== undefined));
710
710
  return Object.keys(notes).length === 0 ? undefined : notes;
711
711
  };
712
+ /** The notes that ship with this running copy, read once at start. A copy updated without a dsh restart runs this old Host
713
+ * next to a newer `release-notes.json` on disk; reading once keeps the running version's own notes (What's new). */
714
+ const SHIPPED_NOTES = (() => { try { return shippedNotes(readFileSync(new URL('./release-notes.json', import.meta.url), 'utf8')); } catch { return undefined; } })();
715
+ /** The version installed on disk (`package.json`), only when it is newer than the running copy: a copy updated without a
716
+ * dsh restart still runs the old Host, so the Settings row asks for a restart. undefined for an unreadable, broken or
717
+ * non-x.y.z file, a running version that is not x.y.z, or a disk version that is not newer. */
718
+ export const installedUpdate = (file = new URL('./package.json', import.meta.url), running = PACKAGE.version) => {
719
+ const now = parseVersion(running);
720
+ if (now === undefined) return undefined;
721
+ let version;
722
+ try { version = parseVersion(JSON.parse(readFileSync(file, 'utf8'))?.version); } catch { return undefined; }
723
+ return version !== undefined && newer(version, now) ? version.join('.') : undefined;
724
+ };
712
725
  /** Latest GitHub release vs this copy. `managed` is false for a renamed or linked local copy, which pnpm can't upgrade. */
713
726
  export async function checkUpdate(fetchImpl = fetch, pkg = PACKAGE, signal) {
714
727
  const current = parseVersion(pkg.version);
@@ -842,7 +855,7 @@ export function unreadStore(file) {
842
855
 
843
856
  /** Mobile connect: one gateway at a time. Start and stop calls run in order, so a fast toggle never leaves two gateways or a
844
857
  * half-closed one. `upstreamUrl` gives dsh's authenticated loopback URL; it is asked again at each DSH login. */
845
- export function mobileGateway({ upstreamUrl, dir, make = createGateway, retryMs = 300 }) {
858
+ export function mobileGateway({ upstreamUrl, dir, about, make = createGateway, retryMs = 300 }) {
846
859
  let gateway, admin, error, closed = false, queue = Promise.resolve();
847
860
  const run = (fn) => (queue = queue.then(fn, fn));
848
861
  // A plugin reload starts the new gateway while the old one still closes its pairing page: wait for the port (about 3 s).
@@ -864,7 +877,7 @@ export function mobileGateway({ upstreamUrl, dir, make = createGateway, retryMs
864
877
  if (gateway !== undefined || closed) return;
865
878
  error = undefined;
866
879
  try {
867
- gateway = make({ dir, upstreamUrl });
880
+ gateway = make({ dir, upstreamUrl, about });
868
881
  admin = `http://127.0.0.1:${await listenAdmin(gateway)}/`;
869
882
  await gateway.start();
870
883
  } catch (e) { error = String(e?.message ?? e); if (admin === undefined) await stop(); }
@@ -874,6 +887,8 @@ export function mobileGateway({ upstreamUrl, dir, make = createGateway, retryMs
874
887
  close: () => { closed = true; return run(stop); },
875
888
  /** An event for the connected phones (`$events`); nothing while no gateway runs. */
876
889
  emit: (event, args) => { gateway?.emit?.(event, args); },
890
+ /** A push notification (APNs) for the phones that want one; nothing while no gateway runs. */
891
+ push: (title, detail, sessionId) => { gateway?.push?.(title, detail, sessionId); },
877
892
  state: () => {
878
893
  const running = gateway?.state().running === true;
879
894
  // The gateway retries by itself (for example when Wi-Fi comes back): a running gateway has no error to show.
@@ -2170,13 +2185,17 @@ export function apply(ctx) {
2170
2185
  ctx.connection.fetch.register({
2171
2186
  path: UPDATE_PATH, methods: ['GET'], requestBody: 'buffered',
2172
2187
  fetch: async (request) => {
2173
- // `?current=1`: the version that this Host runs and its shipped release notes (What's new after an update); no
2188
+ // `?current=1`: the version that this Host runs and its shipped release notes (What's new), read at start; no
2174
2189
  // network call. A missing or broken notes file leaves `notes` out.
2175
2190
  if (new URL(request.url).searchParams.get('current') === '1') {
2176
- const notes = await readFile(new URL('./release-notes.json', import.meta.url), 'utf8').then(shippedNotes, () => undefined);
2177
- return json(notes === undefined ? { current: PACKAGE.version } : { current: PACKAGE.version, notes });
2191
+ return json(SHIPPED_NOTES === undefined ? { current: PACKAGE.version } : { current: PACKAGE.version, notes: SHIPPED_NOTES });
2178
2192
  }
2179
- try { return json(await checkUpdate(fetch, PACKAGE, request.signal)); } catch (error) { return json({ error: String(error?.message ?? error) }, 502); }
2193
+ // `installed`: a newer version on disk than the one that runs (updated without a restart).
2194
+ try {
2195
+ const info = await checkUpdate(fetch, PACKAGE, request.signal);
2196
+ const installed = installedUpdate();
2197
+ return json(installed === undefined ? info : { ...info, installed });
2198
+ } catch (error) { return json({ error: String(error?.message ?? error) }, 502); }
2180
2199
  },
2181
2200
  });
2182
2201
  // Allow for this chat. `GET` answers the old shape (`{sessionId: [tool]}`, only grants that still run: the gateway and an
@@ -2208,10 +2227,25 @@ export function apply(ctx) {
2208
2227
  let mobileOn; // the user's choice; the saved value applies only until the user changes it
2209
2228
  const mobileRead = mobileSaved.read().then((on) => { mobileOn ??= on; });
2210
2229
  let mobileQueue = Promise.resolve(); // one switch change at a time: save, then start or stop
2230
+ const serviceOf = (name) => { try { return ctx.get?.(name); } catch { return undefined; } };
2231
+ /** The words of a Tether push about a chat: its title and its project (dsh's project title, else the folder name; a
2232
+ * branch folder `<repo>/.worktrees/<name>` gives its repository's name). Empty for a chat that is not loaded. */
2233
+ const chatAbout = (sessionId) => {
2234
+ const session = serviceOf('agents')?.get?.(sessionId)?.session;
2235
+ if (session === undefined) return {};
2236
+ let chat, cwd, project;
2237
+ try { chat = ctx.sessionProjections?.snapshot?.(session, ['title'])?.values?.title; } catch { /* no title */ }
2238
+ try { cwd = serviceOf('workingDirectory')?.get?.(session); } catch { /* dsh 0.2.0 has none */ }
2239
+ if (!isText(cwd, 4096)) cwd = session.header?.cwd;
2240
+ let list;
2241
+ try { list = serviceOf('workspaceRegistry')?.list?.(); } catch { /* not ready */ }
2242
+ return { chat: isText(chat, 4096) ? chat : undefined, project: projectOf(cwd, list) };
2243
+ };
2211
2244
  ctx.inject?.(['webServer'], (webCtx) => {
2212
2245
  const gateway = mobileGateway({
2213
2246
  dir: process.env.DSH_MOBILE_DIR || join(home, 'storages', 'dsh-composer-plus', 'mobile'),
2214
2247
  upstreamUrl: () => ctx.connection.authenticatedUrl(`http://127.0.0.1:${webCtx.webServer.port}`),
2248
+ about: chatAbout,
2215
2249
  });
2216
2250
  mobile = gateway;
2217
2251
  webCtx.effect(() => {
@@ -2282,7 +2316,14 @@ export function apply(ctx) {
2282
2316
  ctx.on('agent/status', ({ agent, status }) => {
2283
2317
  if (agent?.session?.header?.origin === 'subagent') return; // the parent chat shows its subagents' work
2284
2318
  if (status === 'running') { busy.add(agent.id); if (mobileOn === true) changeUnread([], [agent.id]); }
2285
- else if (busy.delete(agent.id) && mobileOn === true) changeUnread([agent.id], []);
2319
+ else if (busy.delete(agent.id) && mobileOn === true) {
2320
+ changeUnread([agent.id], []);
2321
+ // Tether's "Turn finished" also while Tether is closed (APNs, when the gateway has a key): the agent's reply, under
2322
+ // the Mac, the project and the chat's title (chatAbout).
2323
+ let reply = '';
2324
+ try { reply = lastReply(agent.session?.snapshotEvents?.() ?? []); } catch { /* no log */ }
2325
+ mobile?.push('Turn finished', reply, agent.id);
2326
+ }
2286
2327
  });
2287
2328
  ctx.connection.fetch.register({
2288
2329
  path: UNREAD_PATH, methods: ['GET', 'POST'], requestBody: 'buffered',
@@ -3064,6 +3105,26 @@ export const predictStore = (file) => settingsStore(file, (v) => ({ on: v?.on !=
3064
3105
 
3065
3106
  /** Text blocks of a message content, joined. */
3066
3107
  const textBlocks = (content) => (Array.isArray(content) ? content.filter((b) => b?.type === 'text' && typeof b.text === 'string').map((b) => b.text).join('') : '');
3108
+ /** A chat folder's project name in a Tether push: a branch folder `<repo>/.worktrees/<name>` gives its repository's
3109
+ * name, else dsh's project title (`workspaces`: `workspaceRegistry.list()`), else the folder name. */
3110
+ export function projectOf(cwd, workspaces) {
3111
+ if (!isText(cwd, 4096) || !isAbsolute(cwd)) return undefined;
3112
+ const folder = cwd.replace(/(.)[\\/]+$/, '$1');
3113
+ if (basename(dirname(folder)) === '.worktrees') return basename(dirname(dirname(folder))) || undefined;
3114
+ const w = Array.isArray(workspaces) ? workspaces.find((x) => x?.path === folder) : undefined;
3115
+ return isText(w?.title, 512) ? w.title : basename(folder) || undefined;
3116
+ }
3117
+ /** The agent's last reply text in the chat's last turn (Tether's Turn finished push), or '' when that turn has none.
3118
+ * A reply that a rollback withdrew does not count. */
3119
+ export function lastReply(events) {
3120
+ const start = events.findLastIndex((e) => e.type === 'turn/start');
3121
+ const gone = withdrawn(events);
3122
+ for (let i = events.length - 1; i > start; i--) {
3123
+ const text = events[i].type === 'assistant/message' && !gone(events[i].seq) ? textBlocks(events[i].data?.message?.content).trim() : '';
3124
+ if (text !== '') return text;
3125
+ }
3126
+ return '';
3127
+ }
3067
3128
  /** The recent conversation for the prediction: the user's own messages and the agent's replies (no tools, no hidden
3068
3129
  * context), oldest first, the newest kept when it is long. `undefined` when the chat has no reply after its last message. */
3069
3130
  export function predictTranscript(events) {
@@ -5735,7 +5796,8 @@ function installDefaultWorkspace(ctx, home) {
5735
5796
  * <dir>/journal.jsonl every change, with the line before and after
5736
5797
  * <dir>/reviewed.json how far the review read each chat (event seq)
5737
5798
  * Off by default: the review makes a model call after each finished turn. The Host keeps the switch (`memory.json`). */
5738
- export const MEMORY_LIMITS = { entry: 300, main: 4000, topic: 16000, topics: 40 };
5799
+ // 2026-11-05 (owner): MEMORY.md 4000 → 8000 characters; each MEMORY.md goes into every chat's system prompt.
5800
+ export const MEMORY_LIMITS = { entry: 300, main: 8000, topic: 16000, topics: 40 };
5739
5801
  export const MEMORY_TOOLS = ['memory_remember', 'memory_forget', 'memory_recall'];
5740
5802
  const MEMORY_MAIN = 'MEMORY.md';
5741
5803
  const MEMORY_EMPTY = '# Memory\n\n## Index\n';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-composer-plus",
3
- "version": "1.21.0",
3
+ "version": "1.22.0",
4
4
  "description": "DeepSeek Harness helpers: 11 extra UI languages (Türkçe, Español, Français, Deutsch, 日本語…), Changes panel, swipe-card feature ideas, sidebar search in message text, turn rollback with git file restore, delete chats to the Trash, input history, Shift+Tab /plan, one-click Continue, resume running chats after a restart, queue drag-and-drop, deeplinks, Auto Review allow-for-chat, notifications, iPhone access with the Tether app, automatic updates",
5
5
  "icon": "./assets/icon.svg",
6
6
  "license": "MIT",
@@ -79,7 +79,7 @@
79
79
  "assets/features/*.webp"
80
80
  ],
81
81
  "scripts": {
82
- "test": "node scripts/build-locales.mjs --check && node scripts/build-docs.mjs --check && node test/locale.test.mjs && node test/continue.test.mjs && node test/continue-host.test.mjs && node test/resume-restart.test.mjs && node test/content-search.test.mjs && node test/turn-rollback.test.mjs && node test/turn-rollback-client.test.mjs && node test/delete-chat.test.mjs && node test/export-chat.test.mjs && node test/project-name.test.mjs && node test/queue-drag.test.mjs && node test/queue-move.test.mjs && node test/queue-edit.test.mjs && node test/send-first.test.mjs && node test/message-link.test.mjs && node test/mark-read.test.mjs && node test/plan-toggle.test.mjs && node test/keep-focus.test.mjs && node test/question-fit.test.mjs && node test/header-fit.test.mjs && node test/mobile-connect.test.mjs && node test/unread.test.mjs && node test/unread-client.test.mjs && node test/tether-gateway.test.mjs && node test/tether-parity.test.mjs && node test/tether-notify-per-mac.test.mjs && node test/deeplink.test.mjs && node test/chat-grant.test.mjs && node test/reject-note.test.mjs && node test/grant-ttl.test.mjs && node test/notify.test.mjs && node test/idle-switch.test.mjs && node test/next-waiting.test.mjs && node test/option-picks.test.mjs && node test/option-picks-ui.test.mjs && node test/changes.test.mjs && node test/chat-changes.test.mjs && node test/changes-tree.test.mjs && node test/file-chats.test.mjs && node test/file-chats-client.test.mjs && node test/feature-ideas.test.mjs && node test/feature-ideas-client.test.mjs && node test/github-issue.test.mjs && node test/project-status.test.mjs && node test/session-branch.test.mjs && node test/recent-projects.test.mjs && node test/project-tools.test.mjs && node test/has-selectors.test.mjs && node test/project-picker.test.mjs && node test/worktree-chats.test.mjs && node test/worktree-chats-client.test.mjs && node test/branch-tree.test.mjs && node test/branch-tree-client.test.mjs && node test/default-workspace.test.mjs && node test/default-workspace-client.test.mjs && node test/find-in-chat.test.mjs && node test/predict.test.mjs && node test/predict-client.test.mjs && node test/complete.test.mjs && node test/complete-client.test.mjs && node test/prompt-improve.test.mjs && node test/prompt-improve-client.test.mjs && node test/goal-check.test.mjs && node test/goal-check-client.test.mjs && node test/backup.test.mjs && node test/backup-host.test.mjs && node test/backup-client.test.mjs && node test/project-memory.test.mjs && node test/memory-editor.test.mjs && node test/memory-base.test.mjs && node test/memory-history.test.mjs && node test/memory-export.test.mjs && node test/memory-source.test.mjs && node test/memory-copy.test.mjs && node test/memory-stale.test.mjs && node test/memory-per-chat.test.mjs && node test/memory-suggest.test.mjs && node test/status-order.test.mjs && node test/toggles.test.mjs && node test/update.test.mjs && node test/release-notes.test.mjs && node test/active-count.test.mjs && node test/meta.test.mjs && node test/shots.test.mjs && node test/readme.test.mjs && node test/readme-labels.test.mjs && node test/feature-docs.test.mjs && node test/routes.test.mjs && node test/protected-files.test.mjs && node test/blocked-commands.test.mjs && node test/blocked-commands-client.test.mjs && node test/handoff.test.mjs && node test/context-breakdown.test.mjs && node test/task-board.test.mjs && node test/task-board-client.test.mjs && node test/planned-steps.test.mjs && node --test --test-timeout=120000 test/computers.test.mjs test/computers-host.test.mjs && node test/computers-client.test.mjs && node test/secret-input.test.mjs && node test/secret-input-client.test.mjs && node test/quote-reply.test.mjs && node test/side-chat.test.mjs && node test/diff-comments.test.mjs",
82
+ "test": "node scripts/build-locales.mjs --check && node scripts/build-docs.mjs --check && node test/locale.test.mjs && node test/continue.test.mjs && node test/continue-host.test.mjs && node test/resume-restart.test.mjs && node test/content-search.test.mjs && node test/turn-rollback.test.mjs && node test/turn-rollback-client.test.mjs && node test/delete-chat.test.mjs && node test/export-chat.test.mjs && node test/project-name.test.mjs && node test/queue-drag.test.mjs && node test/queue-move.test.mjs && node test/queue-edit.test.mjs && node test/send-first.test.mjs && node test/message-link.test.mjs && node test/mark-read.test.mjs && node test/plan-toggle.test.mjs && node test/keep-focus.test.mjs && node test/question-fit.test.mjs && node test/header-fit.test.mjs && node test/mobile-connect.test.mjs && node test/unread.test.mjs && node test/unread-client.test.mjs && node test/tether-gateway.test.mjs && node test/tether-parity.test.mjs && node test/tether-notify-per-mac.test.mjs && node test/tether-push-words.test.mjs && node test/deeplink.test.mjs && node test/chat-grant.test.mjs && node test/reject-note.test.mjs && node test/grant-ttl.test.mjs && node test/notify.test.mjs && node test/idle-switch.test.mjs && node test/next-waiting.test.mjs && node test/option-picks.test.mjs && node test/option-picks-ui.test.mjs && node test/changes.test.mjs && node test/chat-changes.test.mjs && node test/changes-tree.test.mjs && node test/file-chats.test.mjs && node test/file-chats-client.test.mjs && node test/feature-ideas.test.mjs && node test/feature-ideas-client.test.mjs && node test/github-issue.test.mjs && node test/project-status.test.mjs && node test/session-branch.test.mjs && node test/recent-projects.test.mjs && node test/project-tools.test.mjs && node test/has-selectors.test.mjs && node test/project-picker.test.mjs && node test/worktree-chats.test.mjs && node test/worktree-chats-client.test.mjs && node test/branch-tree.test.mjs && node test/branch-tree-client.test.mjs && node test/default-workspace.test.mjs && node test/default-workspace-client.test.mjs && node test/find-in-chat.test.mjs && node test/predict.test.mjs && node test/predict-client.test.mjs && node test/complete.test.mjs && node test/complete-client.test.mjs && node test/prompt-improve.test.mjs && node test/prompt-improve-client.test.mjs && node test/goal-check.test.mjs && node test/goal-check-client.test.mjs && node test/backup.test.mjs && node test/backup-host.test.mjs && node test/backup-client.test.mjs && node test/project-memory.test.mjs && node test/memory-editor.test.mjs && node test/memory-base.test.mjs && node test/memory-history.test.mjs && node test/memory-export.test.mjs && node test/memory-source.test.mjs && node test/memory-copy.test.mjs && node test/memory-stale.test.mjs && node test/memory-per-chat.test.mjs && node test/memory-suggest.test.mjs && node test/status-order.test.mjs && node test/toggles.test.mjs && node test/update.test.mjs && node test/whats-new-current.test.mjs && node test/release-notes.test.mjs && node test/active-count.test.mjs && node test/meta.test.mjs && node test/shots.test.mjs && node test/readme.test.mjs && node test/readme-labels.test.mjs && node test/feature-docs.test.mjs && node test/routes.test.mjs && node test/protected-files.test.mjs && node test/blocked-commands.test.mjs && node test/blocked-commands-client.test.mjs && node test/handoff.test.mjs && node test/context-breakdown.test.mjs && node test/task-board.test.mjs && node test/task-board-client.test.mjs && node test/planned-steps.test.mjs && node --test --test-timeout=120000 test/computers.test.mjs test/computers-host.test.mjs && node test/computers-client.test.mjs && node test/secret-input.test.mjs && node test/secret-input-client.test.mjs && node test/quote-reply.test.mjs && node test/side-chat.test.mjs && node test/diff-comments.test.mjs",
83
83
  "build:locales": "node scripts/build-locales.mjs",
84
84
  "build:readme": "node scripts/build-docs.mjs",
85
85
  "prepublishOnly": "npm test"
@@ -1,18 +1,18 @@
1
1
  {
2
- "version": "1.21.0",
2
+ "version": "1.22.0",
3
3
  "notes": {
4
- "en": "## New\n\n- **Next waiting chat**: a button in the sidebar header shows how many other chats wait for you and opens the next one (Cmd+Shift+E, Ctrl+Shift+E on Windows and Linux).\n- **Option buttons**: when an answer ends with a list of options, click an option to send it. On a question card of the agent, the keys 1–9 pick an option.\n- **Reject with note**: on an approval card, write why or what to do instead. The agent reads the rejection and your note in the same turn.\n- **Secret input**: the agent can ask you for a password or a token on a private card. The agent gets only the path of a file, not the value, and the file is deleted when the turn ends.\n- **Quote in reply**: select a part of an answer and click **Quote** to put it into the composer as a quote.\n- **Side chat**: ask a side question in a read-only copy of the chat while the chat goes on working. **Bring back** puts the answer into the chat's composer.\n- **Diff notes**: in the **Changes panel**, add a note to a line of a diff, then send all notes to the composer.\n- **Project memory**: seven new features. **Memory version history**, **Export memory to AGENTS.md**, **Memory note source link**, **Copy memory to another project**, **Find stale memory notes**, **Do not use memory in this chat** and **Suggest memory notes from a chat**.\n- **Remote computers**: open the dsh of your other Macs over Tailscale and continue their chats here. Off by default, because it opens network ports.\n\n## Changes\n\n- **Task board**: the projects are in a list in the header (**Search projects**). Cmd+Shift+K (Ctrl+Shift+K) opens the board. A card that you read leaves **Done**. **Recently finished** shows the cards that you read.\n- **Task board**: **Clear all** asks first and keeps the unread cards. **Undo** and **Removed** bring cards back. No chat is deleted.\n- **Project status**: the **Ungrouped** row of the sidebar also shows the status of its chats, for example the spinner while a chat runs.\n- Tether: the notification settings are kept for each paired Mac. A Mac that you pair later starts with notifications off.\n- Once a day, each copy asks GitHub for the small `active.txt` file of its release, so the owner can count the copies of each version. The request has no id, cookie or data about you.",
5
- "zh": "## 新功能\n\n- **下一个等待中的对话**:侧边栏标题栏中的按钮显示还有多少其他对话在等你,点击即可打开下一个(Cmd+Shift+E,Windows 和 Linux 上为 Ctrl+Shift+E)。\n- **选项按钮**:当回答以选项列表结尾时,点击一个选项即可发送它。在智能体的提问卡片上,按 1–9 键即可选择选项。\n- **拒绝并附言**:在审批卡片上写下原因或应改做什么。智能体会在同一轮中读到拒绝和你的附言。\n- **密钥输入**:智能体可以在一张私密卡片上向你索要密码或令牌。智能体只拿到一个文件的路径,拿不到值本身,这一轮结束时文件会被删除。\n- **引用回复**:选中回答中的一段文字,点击 **引用**,即可把它作为引用放进输入框。\n- **旁支对话**:在对话的只读副本中提一个旁支问题,原对话继续工作。**带回** 会把回答放进原对话的输入框。\n- **差异批注**:在 **改动面板** 中给差异的某一行添加批注,然后把所有批注发送到输入框。\n- **项目记忆**:七项新功能。**记忆版本历史**、**把记忆导出到 AGENTS.md**、**记忆笔记来源链接**、**把记忆复制到其他项目**、**查找过时的记忆笔记**、**此对话不使用记忆** 和 **从对话中建议记忆笔记**。\n- **远程电脑**:通过 Tailscale 打开你其他 Mac 上的 dsh,并在这里继续它们的对话。此功能默认关闭,因为它会打开网络端口。\n\n## 变更\n\n- **任务看板**:项目列表移到了顶栏中(**搜索项目**)。Cmd+Shift+K(Ctrl+Shift+K)可打开看板。你读过的卡片会离开 **已完成**。**最近完成** 显示你读过的卡片。\n- **任务看板**:**全部清除** 会先询问,并保留未读的卡片。**撤销** 和 **已移除** 可以找回卡片。不会删除任何对话。\n- **项目状态**:侧边栏的 **未分组** 行也会显示其中对话的状态,例如对话运行时的加载图标。\n- Tether:通知设置按每台已配对的 Mac 分别保存。之后配对的 Mac 开始时通知为关闭状态。\n- 每份副本每天向 GitHub 请求一次其版本的小文件 `active.txt`,这样作者就能统计每个版本的副本数量。该请求不含 ID、Cookie 或任何关于你的数据。",
6
- "tr": "## Yeni\n\n- **Sıradaki bekleyen sohbet**: kenar çubuğunun başlığındaki bir düğme, sizi bekleyen diğer sohbetlerin sayısını gösterir ve sıradakini açar (Cmd+Shift+E; Windows ve Linux’ta Ctrl+Shift+E).\n- **Seçenek düğmeleri**: bir yanıt bir seçenek listesiyle bittiğinde, bir seçeneği göndermek için ona tıklayın. Ajanın soru kartında 1–9 tuşları bir seçenek seçer.\n- **Not ile reddet**: bir onay kartında nedenini ya da bunun yerine ne yapılacağını yazın. Ajan reddi ve notunuzu aynı turda okur.\n- **Gizli değer girişi**: ajan sizden özel bir kartta bir parola ya da token isteyebilir. Ajan değeri değil, yalnız bir dosyanın yolunu alır. Dosya, tur bitince silinir.\n- **Yanıtta alıntıla**: bir yanıtın bir bölümünü seçin ve onu alıntı olarak mesaj alanına koymak için **Alıntıla** düğmesine tıklayın.\n- **Yan sohbet**: sohbet çalışmaya devam ederken sohbetin salt okunur bir kopyasında bir yan soru sorun. **Geri getir**, yanıtı sohbetin mesaj alanına koyar.\n- **Diff notları**: **Değişiklikler paneli** içinde bir diff’in bir satırına not ekleyin, sonra tüm notları mesaj alanına gönderin.\n- **Proje hafızası**: yedi yeni özellik. **Hafıza sürüm geçmişi**, **Hafızayı AGENTS.md dosyasına aktar**, **Hafıza girdisinin kaynak bağlantısı**, **Hafızayı başka projeye kopyala**, **Eskimiş hafıza girdilerini bul**, **Bu sohbette hafızayı kullanma** ve **Sohbetten hafıza önerileri çıkar**.\n- **Uzak bilgisayarlar**: diğer Mac’lerinizdeki dsh’yi Tailscale üzerinden açın ve sohbetlerine burada devam edin. Ağ portları açtığı için varsayılan olarak kapalıdır.\n\n## Değişiklikler\n\n- **Görev panosu**: projeler artık başlıktaki bir listededir (**Projelerde ara**). Cmd+Shift+K (Ctrl+Shift+K) panoyu açar. Okuduğunuz bir kart **Bitti** sütunundan çıkar. **Son bitenler**, okuduğunuz kartları gösterir.\n- **Görev panosu**: **Tümünü temizle** önce sorar ve okunmamış kartları tutar. **Geri al** ve **Kaldırılanlar** kartları geri getirir. Hiçbir sohbet silinmez.\n- **Proje durumu**: kenar çubuğundaki **Gruplanmamış** satırı da sohbetlerinin durumunu gösterir; örneğin bir sohbet çalışırken dönen simgeyi.\n- Tether: bildirim ayarları, eşleştirilen her Mac için ayrı tutulur. Sonradan eşleştirdiğiniz bir Mac’te bildirimler kapalı başlar.\n- Her kopya, günde bir kez kendi sürümünün küçük `active.txt` dosyasını GitHub’dan ister. Böylece proje sahibi her sürümün kaç kopyası olduğunu sayabilir. İstekte kimlik, çerez ya da sizinle ilgili bir veri yoktur.",
7
- "es": "## Novedades\n\n- **Siguiente chat en espera**: un botón en la cabecera de la barra lateral muestra cuántos otros chats te esperan y abre el siguiente (Cmd+Shift+E; Ctrl+Shift+E en Windows y Linux).\n- **Botones de opciones**: cuando una respuesta termina con una lista de opciones, haz clic en una opción para enviarla. En una tarjeta de pregunta del agente, las teclas 1–9 eligen una opción.\n- **Rechazar con nota**: en una tarjeta de aprobación, escribe el motivo o qué hacer en su lugar. El agente lee el rechazo y tu nota en el mismo turno.\n- **Entrada secreta**: el agente puede pedirte una contraseña o un token en una tarjeta privada. El agente solo recibe la ruta de un archivo, no el valor, y el archivo se borra cuando termina el turno.\n- **Citar en la respuesta**: selecciona una parte de una respuesta y haz clic en **Citar** para ponerla en el editor como cita.\n- **Chat lateral**: haz una pregunta lateral en una copia de solo lectura del chat mientras el chat sigue trabajando. **Traer de vuelta** pone la respuesta en el editor del chat.\n- **Notas del diff**: en el **Panel de cambios**, añade una nota a una línea de un diff y después envía todas las notas al editor.\n- **Memoria del proyecto**: siete funciones nuevas. **Historial de versiones de la memoria**, **Exportar la memoria a AGENTS.md**, **Enlace de origen de las notas de memoria**, **Copiar la memoria a otro proyecto**, **Buscar notas de memoria obsoletas**, **No usar la memoria en este chat** y **Sugerir notas de memoria desde un chat**.\n- **Equipos remotos**: abre el dsh de tus otros Mac a través de Tailscale y continúa sus chats aquí. La función viene desactivada de forma predeterminada, porque abre puertos de red.\n\n## Cambios\n\n- **Tablero de tareas**: los proyectos están en una lista en la cabecera (**Buscar proyectos**). Cmd+Shift+K (Ctrl+Shift+K) abre el tablero. Una tarjeta que ya leíste sale de **Hecho**. **Terminados hace poco** muestra las tarjetas que leíste.\n- **Tablero de tareas**: **Limpiar todo** pregunta primero y conserva las tarjetas sin leer. **Deshacer** y **Quitadas** devuelven las tarjetas. No se borra ningún chat.\n- **Estado del proyecto**: la fila **Sin agrupar** de la barra lateral también muestra el estado de sus chats, por ejemplo el indicador de carga mientras un chat se ejecuta.\n- Tether: los ajustes de notificaciones se guardan para cada Mac emparejado. Un Mac que emparejes más tarde empieza con las notificaciones desactivadas.\n- Una vez al día, cada copia pide a GitHub el pequeño archivo `active.txt` de su versión, para que el autor pueda contar las copias de cada versión. La solicitud no lleva ningún id, cookie ni dato sobre ti.",
8
- "pt-BR": "## Novidades\n\n- **Próximo chat em espera**: um botão no cabeçalho da barra lateral mostra quantos outros chats estão esperando por você e abre o próximo (Cmd+Shift+E; Ctrl+Shift+E no Windows e no Linux).\n- **Botões de opções**: quando uma resposta termina com uma lista de opções, clique em uma opção para enviá-la. Em um cartão de pergunta do agente, as teclas 1–9 escolhem uma opção.\n- **Rejeitar com nota**: em um cartão de aprovação, escreva o motivo ou o que fazer no lugar. O agente lê a rejeição e a sua nota no mesmo turno.\n- **Entrada secreta**: o agente pode pedir a você uma senha ou um token em um cartão privado. O agente recebe só o caminho de um arquivo, não o valor, e o arquivo é apagado quando o turno termina.\n- **Citar na resposta**: selecione uma parte de uma resposta e clique em **Citar** para colocá-la no editor de mensagens como citação.\n- **Chat paralelo**: faça uma pergunta paralela em uma cópia somente leitura do chat enquanto o chat continua trabalhando. **Trazer de volta** coloca a resposta no editor de mensagens do chat.\n- **Notas no diff**: no **Painel de alterações**, adicione uma nota a uma linha de um diff e depois envie todas as notas para o editor de mensagens.\n- **Memória do projeto**: sete recursos novos. **Histórico de versões da memória**, **Exportar a memória para AGENTS.md**, **Link de origem das notas da memória**, **Copiar a memória para outro projeto**, **Encontrar notas de memória desatualizadas**, **Não usar a memória neste chat** e **Sugerir notas de memória a partir de um chat**.\n- **Computadores remotos**: abra o dsh dos seus outros Macs pelo Tailscale e continue os chats deles aqui. O recurso vem desativado por padrão, porque abre portas de rede.\n\n## Alterações\n\n- **Quadro de tarefas**: os projetos ficam em uma lista no cabeçalho (**Buscar projetos**). Cmd+Shift+K (Ctrl+Shift+K) abre o quadro. Um cartão que você leu sai de **Concluído**. **Concluídos recentemente** mostra os cartões que você leu.\n- **Quadro de tarefas**: **Limpar tudo** pergunta antes e mantém os cartões não lidos. **Desfazer** e **Retirados** trazem os cartões de volta. Nenhum chat é apagado.\n- **Status do projeto**: a linha **Sem grupo** da barra lateral também mostra o status dos chats dela, por exemplo o indicador de carregamento enquanto um chat está em execução.\n- Tether: as configurações de notificação ficam guardadas para cada Mac pareado. Um Mac que você parear depois começa com as notificações desativadas.\n- Uma vez por dia, cada cópia pede ao GitHub o pequeno arquivo `active.txt` da sua versão, para que o autor possa contar as cópias de cada versão. A solicitação não tem id, cookie nem dados sobre você.",
9
- "fr": "## Nouveautés\n\n- **Discussion en attente suivante** : un bouton dans l’en-tête de la barre latérale indique combien d’autres discussions vous attendent et ouvre la suivante (Cmd+Shift+E, Ctrl+Shift+E sous Windows et Linux).\n- **Boutons d’options** : quand une réponse se termine par une liste d’options, cliquez sur une option pour l’envoyer. Sur une carte de question de l’agent, les touches 1–9 choisissent une option.\n- **Refuser avec une note** : sur une carte d’approbation, écrivez la raison ou ce qu’il faut faire à la place. L’agent lit le refus et votre note dans le même tour.\n- **Saisie secrète** : l’agent peut vous demander un mot de passe ou un jeton sur une carte privée. L’agent reçoit seulement le chemin d’un fichier, pas la valeur, et le fichier est supprimé à la fin du tour.\n- **Citer dans la réponse** : sélectionnez une partie d’une réponse et cliquez sur **Citer** pour la placer dans la zone de saisie comme citation.\n- **Discussion annexe** : posez une question annexe dans une copie en lecture seule de la discussion pendant que la discussion continue son travail. **Rapporter** place la réponse dans la zone de saisie de la discussion.\n- **Notes de diff** : dans le **Panneau des modifications**, ajoutez une note à une ligne d’un diff, puis envoyez toutes les notes vers la zone de saisie.\n- **Mémoire du projet** : sept nouvelles fonctions. **Historique des versions de la mémoire**, **Exporter la mémoire vers AGENTS.md**, **Lien vers l’origine des notes de mémoire**, **Copier la mémoire vers un autre projet**, **Trouver les notes de mémoire obsolètes**, **Ne pas utiliser la mémoire dans cette discussion** et **Suggérer des notes de mémoire depuis une discussion**.\n- **Ordinateurs distants** : ouvrez le dsh de vos autres Mac via Tailscale et poursuivez leurs discussions ici. La fonction est désactivée par défaut, car elle ouvre des ports réseau.\n\n## Modifications\n\n- **Tableau des tâches** : les projets sont dans une liste dans l’en-tête (**Rechercher des projets**). Cmd+Shift+K (Ctrl+Shift+K) ouvre le tableau. Une carte que vous avez lue quitte **Terminé**. **Terminées récemment** affiche les cartes que vous avez lues.\n- **Tableau des tâches** : **Tout retirer** demande d’abord une confirmation et garde les cartes non lues. **Annuler** et **Retirées** ramènent les cartes. Aucune discussion n’est supprimée.\n- **Statut du projet** : la ligne **Sans groupe** de la barre latérale affiche aussi l’état de ses discussions, par exemple l’indicateur de chargement pendant qu’une discussion s’exécute.\n- Tether : les réglages des notifications sont conservés pour chaque Mac appairé. Un Mac que vous appairez plus tard commence avec les notifications désactivées.\n- Une fois par jour, chaque copie demande à GitHub le petit fichier `active.txt` de sa version, afin que l’auteur puisse compter les copies de chaque version. La requête ne contient ni identifiant, ni cookie, ni donnée sur vous.",
10
- "de": "## Neu\n\n- **Nächster wartender Chat**: Eine Schaltfläche in der Kopfzeile der Seitenleiste zeigt, wie viele andere Chats auf dich warten, und öffnet den nächsten (Cmd+Shift+E, unter Windows und Linux Ctrl+Shift+E).\n- **Options-Schaltflächen**: Wenn eine Antwort mit einer Liste von Optionen endet, klicke auf eine Option, um sie zu senden. Auf einer Fragekarte des Agenten wählen die Tasten 1–9 eine Option.\n- **Mit Notiz ablehnen**: Schreibe auf einer Genehmigungskarte, warum, oder was stattdessen zu tun ist. Der Agent liest die Ablehnung und deine Notiz im selben Durchgang.\n- **Geheime Eingabe**: Der Agent kann dich auf einer privaten Karte nach einem Passwort oder einem Token fragen. Der Agent bekommt nur den Pfad einer Datei, nicht den Wert, und die Datei wird am Ende des Durchgangs gelöscht.\n- **In Antwort zitieren**: Markiere einen Teil einer Antwort und klicke auf **Zitieren**, um ihn als Zitat ins Eingabefeld zu setzen.\n- **Nebenchat**: Stelle eine Nebenfrage in einer schreibgeschützten Kopie des Chats, während der Chat weiterarbeitet. **Zurückholen** setzt die Antwort ins Eingabefeld des Chats.\n- **Diff-Notizen**: Füge im **Änderungsbereich** einer Zeile eines Diffs eine Notiz hinzu und sende dann alle Notizen ins Eingabefeld.\n- **Projektgedächtnis**: sieben neue Funktionen. **Versionsverlauf des Gedächtnisses**, **Gedächtnis nach AGENTS.md exportieren**, **Quellenlink für Gedächtnisnotizen**, **Gedächtnis in ein anderes Projekt kopieren**, **Veraltete Gedächtnisnotizen finden**, **Gedächtnis in diesem Chat nicht nutzen** und **Gedächtnisnotizen aus einem Chat vorschlagen**.\n- **Remote-Computer**: Öffne dsh auf deinen anderen Macs über Tailscale und setze ihre Chats hier fort. Die Funktion ist standardmäßig aus, weil sie Netzwerkports öffnet.\n\n## Änderungen\n\n- **Aufgabentafel**: Die Projekte stehen in einer Liste in der Kopfleiste (**Projekte durchsuchen**). Cmd+Shift+K (Ctrl+Shift+K) öffnet die Tafel. Eine Karte, die du gelesen hast, verlässt **Fertig**. **Kürzlich beendet** zeigt die Karten, die du gelesen hast.\n- **Aufgabentafel**: **Alle entfernen** fragt zuerst nach und behält die ungelesenen Karten. **Rückgängig** und **Entfernt** holen Karten zurück. Kein Chat wird gelöscht.\n- **Projektstatus**: Die Zeile **Ohne Gruppe** in der Seitenleiste zeigt auch den Status ihrer Chats, zum Beispiel den Spinner, während ein Chat läuft.\n- Tether: Die Benachrichtigungseinstellungen gelten für jeden gekoppelten Mac einzeln. Ein Mac, den du später koppelst, startet mit ausgeschalteten Benachrichtigungen.\n- Einmal am Tag fragt jede Kopie bei GitHub die kleine Datei `active.txt` ihres Releases ab, damit der Autor die Kopien jeder Version zählen kann. Die Anfrage enthält keine ID, kein Cookie und keine Daten über dich.",
11
- "ru": "## Новое\n\n- **Следующий ожидающий чат**: кнопка в заголовке боковой панели показывает, сколько других чатов ждут вас, и открывает следующий (Cmd+Shift+E, в Windows и Linux — Ctrl+Shift+E).\n- **Кнопки вариантов**: когда ответ заканчивается списком вариантов, нажмите на вариант, чтобы отправить его. На карточке вопроса агента клавиши 1–9 выбирают вариант.\n- **Отклонить с примечанием**: на карточке подтверждения напишите причину или что сделать вместо этого. Агент читает отказ и ваше примечание в том же ходе.\n- **Ввод секрета**: агент может попросить у вас пароль или токен на закрытой карточке. Агент получает только путь к файлу, а не само значение, и файл удаляется, когда ход заканчивается.\n- **Цитата в ответе**: выделите часть ответа и нажмите **Цитировать**, чтобы вставить её в поле ввода как цитату.\n- **Побочный чат**: задайте побочный вопрос в копии чата только для чтения, пока сам чат продолжает работу. Кнопка **Вернуть** вставляет ответ в поле ввода чата.\n- **Заметки к diff**: в разделе **Панель изменений** добавьте заметку к строке diff, затем отправьте все заметки в поле ввода.\n- **Память проекта**: семь новых функций. **История версий памяти**, **Экспорт памяти в AGENTS.md**, **Ссылка на источник заметки памяти**, **Копировать память в другой проект**, **Поиск устаревших заметок памяти**, **Не использовать память в этом чате** и **Предложить заметки памяти из чата**.\n- **Удалённые компьютеры**: открывайте dsh на других ваших Mac через Tailscale и продолжайте их чаты здесь. По умолчанию функция выключена, потому что она открывает сетевые порты.\n\n## Изменения\n\n- **Доска задач**: проекты теперь в списке в шапке (**Поиск проектов**). Cmd+Shift+K (Ctrl+Shift+K) открывает доску. Прочитанная карточка уходит из **Готово**. Раздел **Недавно завершённые** показывает прочитанные карточки.\n- **Доска задач**: кнопка **Очистить всё** сначала спрашивает подтверждение и оставляет непрочитанные карточки. **Отменить** и **Убранные** возвращают карточки. Ни один чат не удаляется.\n- **Статус проекта**: строка **Без группы** на боковой панели тоже показывает состояние своих чатов, например индикатор выполнения, пока чат работает.\n- Tether: настройки уведомлений хранятся отдельно для каждого сопряжённого Mac. Mac, сопряжённый позже, начинает работу с выключенными уведомлениями.\n- Раз в день каждая копия запрашивает у GitHub маленький файл `active.txt` своего выпуска, чтобы автор мог посчитать копии каждой версии. Запрос не содержит ни идентификатора, ни cookie, ни данных о вас.",
12
- "ja": "## 新機能\n\n- **次の待機中のチャット**:サイドバーのヘッダーにあるボタンに、あなたを待っているほかのチャットの数が表示され、クリックすると次のチャットが開きます(Cmd+Shift+E、Windows と Linux では Ctrl+Shift+E)。\n- **選択肢ボタン**:回答が選択肢のリストで終わると、選択肢をクリックしてそのまま送信できます。エージェントの質問カードでは、1~9 キーで選択肢を選べます。\n- **メモを付けて拒否**:承認カードに、拒否の理由や代わりにしてほしいことを書けます。エージェントは同じターンで拒否とメモを読みます。\n- **シークレット入力**:エージェントは、非公開のカードでパスワードやトークンを求めることができます。エージェントが受け取るのはファイルのパスだけで、値そのものは受け取りません。ファイルはターンの終了時に削除されます。\n- **返信で引用**:回答の一部を選択して **引用** をクリックすると、その部分が引用として入力欄に入ります。\n- **サイドチャット**:チャットが作業を続けている間に、チャットの読み取り専用のコピーでサイドの質問ができます。**持ち帰る** を押すと、回答がチャットの入力欄に入ります。\n- **差分メモ**:**変更パネル** で差分の行にメモを付け、すべてのメモをまとめて入力欄に送れます。\n- **プロジェクトメモリー**:7 つの新機能です。**メモリーのバージョン履歴**、**メモリーを AGENTS.md に書き出す**、**メモリーのメモの出典リンク**、**メモリーを別のプロジェクトにコピー**、**古くなったメモリーのメモを探す**、**このチャットではメモリーを使わない**、**チャットからメモリーのメモを提案**。\n- **リモートコンピュータ**:Tailscale 経由でほかの Mac の dsh を開き、そのチャットをここで続けられます。ネットワークポートを開くため、既定ではオフです。\n\n## 変更点\n\n- **タスクボード**:プロジェクトはヘッダーのリストに移りました(**プロジェクトを検索**)。Cmd+Shift+K(Ctrl+Shift+K)でボードが開きます。読んだカードは **完了** から外れます。**最近完了** には読んだカードが表示されます。\n- **タスクボード**:**すべてクリア** は先に確認し、未読のカードは残します。**元に戻す** と **外したカード** でカードを戻せます。チャットは削除されません。\n- **プロジェクトの状態**:サイドバーの **グループなし** の行にも、そのチャットの状態が表示されます。たとえば、チャットの実行中はスピナーが表示されます。\n- Tether:通知の設定は、ペアリングした Mac ごとに保存されます。後からペアリングした Mac では、通知はオフの状態で始まります。\n- 1 日に 1 回、各コピーは自分のリリースの小さなファイル `active.txt` を GitHub に要求します。これにより、作者はバージョンごとのコピー数を数えられます。このリクエストには、ID、Cookie、あなたに関するデータは含まれません。",
13
- "ko": "## 새 기능\n\n- **다음 대기 중인 채팅**: 사이드바 헤더의 버튼이 나를 기다리는 다른 채팅 수를 보여 주고, 다음 채팅을 엽니다(Cmd+Shift+E, Windows와 Linux에서는 Ctrl+Shift+E).\n- **선택지 버튼**: 답변이 선택지 목록으로 끝나면 선택지를 클릭해 바로 보낼 수 있습니다. 에이전트의 질문 카드에서는 1–9 키로 선택지를 고릅니다.\n- **메모와 함께 거부**: 승인 카드에 거부하는 이유나 대신 할 일을 씁니다. 에이전트는 같은 턴에서 거부와 메모를 함께 읽습니다.\n- **비밀 값 입력**: 에이전트가 비공개 카드로 비밀번호나 토큰을 요청할 수 있습니다. 에이전트는 값이 아니라 파일 경로만 받으며, 파일은 턴이 끝나면 삭제됩니다.\n- **답장에 인용**: 답변의 일부를 선택하고 **인용**을 클릭하면 그 부분이 인용으로 입력란에 들어갑니다.\n- **사이드 채팅**: 채팅이 계속 작업하는 동안 채팅의 읽기 전용 복사본에서 사이드 질문을 할 수 있습니다. **가져오기**를 누르면 답변이 원래 채팅의 입력란에 들어갑니다.\n- **diff 메모**: **변경 사항 패널**에서 diff의 줄에 메모를 달고, 모든 메모를 입력란으로 보냅니다.\n- **프로젝트 메모리**: 새 기능 일곱 가지입니다. **메모리 버전 기록**, **메모리를 AGENTS.md로 내보내기**, **메모리 메모 출처 링크**, **메모리를 다른 프로젝트로 복사**, **오래된 메모리 메모 찾기**, **이 채팅에서는 메모리 사용 안 함**, **채팅에서 메모리 메모 제안**.\n- **원격 컴퓨터**: Tailscale을 통해 다른 Mac의 dsh를 열고, 그 채팅을 여기서 이어 갑니다. 네트워크 포트를 열기 때문에 기본적으로 꺼져 있습니다.\n\n## 변경 사항\n\n- **작업 보드**: 프로젝트가 헤더의 목록으로 옮겨졌습니다(**프로젝트 검색**). Cmd+Shift+K(Ctrl+Shift+K)로 보드를 엽니다. 읽은 카드는 **완료**에서 빠집니다. **최근 완료**에는 읽은 카드가 표시됩니다.\n- **작업 보드**: **모두 빼기**는 먼저 확인하고, 읽지 않은 카드는 남겨 둡니다. **실행 취소**와 **뺀 카드**로 카드를 되돌릴 수 있습니다. 채팅은 삭제되지 않습니다.\n- **프로젝트 상태**: 사이드바의 **그룹 없음** 행에도 그 안의 채팅 상태가 표시됩니다. 예를 들어 채팅이 실행 중이면 스피너가 표시됩니다.\n- Tether: 알림 설정이 페어링된 Mac마다 따로 저장됩니다. 나중에 페어링한 Mac은 알림이 꺼진 상태로 시작합니다.\n- 각 사본은 하루에 한 번 GitHub에 자기 릴리스의 작은 `active.txt` 파일을 요청합니다. 그래서 제작자가 버전별 사본 수를 셀 수 있습니다. 이 요청에는 ID, 쿠키, 사용자에 관한 데이터가 없습니다.",
14
- "id": "## Baru\n\n- **Obrolan menunggu berikutnya**: tombol di kepala bilah samping menunjukkan berapa banyak obrolan lain yang menunggu Anda dan membuka obrolan berikutnya (Cmd+Shift+E, Ctrl+Shift+E di Windows dan Linux).\n- **Tombol opsi**: saat jawaban diakhiri daftar opsi, klik sebuah opsi untuk mengirimnya. Di kartu pertanyaan agen, tombol 1–9 di keyboard memilih opsi.\n- **Tolak dengan catatan**: di kartu persetujuan, tulis alasannya atau apa yang harus dilakukan sebagai gantinya. Agen membaca penolakan dan catatan Anda di giliran yang sama.\n- **Input rahasia**: agen dapat meminta kata sandi atau token kepada Anda di kartu pribadi. Agen hanya menerima path sebuah file, bukan nilainya, dan file itu dihapus saat giliran berakhir.\n- **Kutip dalam balasan**: pilih sebagian jawaban dan klik **Kutip** untuk memasukkannya ke kotak pesan sebagai kutipan.\n- **Obrolan samping**: ajukan pertanyaan samping di salinan obrolan yang hanya bisa dibaca, sementara obrolan terus bekerja. **Bawa kembali** memasukkan jawabannya ke kotak pesan obrolan.\n- **Catatan diff**: di **Panel perubahan**, tambahkan catatan ke sebuah baris diff, lalu kirim semua catatan ke kotak pesan.\n- **Memori proyek**: tujuh fitur baru. **Riwayat versi memori**, **Ekspor memori ke AGENTS.md**, **Tautan sumber catatan memori**, **Salin memori ke proyek lain**, **Temukan catatan memori yang usang**, **Jangan gunakan memori di chat ini**, dan **Sarankan catatan memori dari chat**.\n- **Komputer jarak jauh**: buka dsh di Mac Anda yang lain melalui Tailscale dan lanjutkan obrolannya di sini. Fitur ini nonaktif secara default karena membuka port jaringan.\n\n## Perubahan\n\n- **Papan tugas**: proyek kini ada di daftar pada header (**Cari proyek**). Cmd+Shift+K (Ctrl+Shift+K) membuka papan. Kartu yang sudah Anda baca keluar dari **Selesai**. **Baru selesai** menampilkan kartu yang sudah Anda baca.\n- **Papan tugas**: **Bersihkan semua** bertanya dulu dan menyimpan kartu yang belum dibaca. **Urungkan** dan **Dikeluarkan** mengembalikan kartu. Tidak ada obrolan yang dihapus.\n- **Status proyek**: baris **Tanpa grup** di bilah samping juga menampilkan status obrolannya, misalnya spinner saat obrolan berjalan.\n- Tether: pengaturan notifikasi disimpan untuk setiap Mac yang dipasangkan. Mac yang Anda pasangkan nanti dimulai dengan notifikasi nonaktif.\n- Sekali sehari, setiap salinan meminta file kecil `active.txt` dari rilisnya ke GitHub, agar pembuatnya dapat menghitung salinan setiap versi. Permintaan ini tidak berisi id, cookie, atau data tentang Anda.",
15
- "vi": "## Mới\n\n- **Cuộc trò chuyện đang chờ tiếp theo**: một nút ở đầu thanh bên cho biết còn bao nhiêu cuộc trò chuyện khác đang chờ bạn và mở cuộc tiếp theo (Cmd+Shift+E, Ctrl+Shift+E trên Windows và Linux).\n- **Nút lựa chọn**: khi câu trả lời kết thúc bằng một danh sách lựa chọn, nhấp vào một lựa chọn để gửi nó. Trên thẻ câu hỏi của tác tử, các phím 1–9 chọn một lựa chọn.\n- **Từ chối kèm ghi chú**: trên thẻ phê duyệt, viết lý do hoặc việc cần làm thay vào đó. Tác tử đọc lời từ chối và ghi chú của bạn trong cùng một lượt.\n- **Nhập giá trị bí mật**: tác tử có thể xin bạn mật khẩu hoặc token trên một thẻ riêng tư. Tác tử chỉ nhận đường dẫn của một tệp, không nhận giá trị, và tệp bị xóa khi lượt kết thúc.\n- **Trích dẫn khi trả lời**: chọn một phần của câu trả lời rồi nhấp **Trích dẫn** để đưa phần đó vào khung soạn thảo dưới dạng trích dẫn.\n- **Trò chuyện phụ**: đặt một câu hỏi phụ trong bản sao chỉ đọc của cuộc trò chuyện, trong khi cuộc trò chuyện vẫn tiếp tục làm việc. **Mang về** đưa câu trả lời vào khung soạn thảo của cuộc trò chuyện.\n- **Ghi chú diff**: trong **Bảng thay đổi**, thêm ghi chú vào một dòng của diff, rồi gửi tất cả ghi chú vào khung soạn thảo.\n- **Bộ nhớ dự án**: bảy tính năng mới. **Lịch sử phiên bản bộ nhớ**, **Xuất bộ nhớ ra AGENTS.md**, **Liên kết nguồn của ghi chú bộ nhớ**, **Sao chép bộ nhớ sang dự án khác**, **Tìm ghi chú bộ nhớ đã lỗi thời**, **Không dùng bộ nhớ trong cuộc trò chuyện này** và **Gợi ý ghi chú bộ nhớ từ một cuộc trò chuyện**.\n- **Máy tính từ xa**: mở dsh của các máy Mac khác của bạn qua Tailscale và tiếp tục các cuộc trò chuyện của chúng tại đây. Tính năng này mặc định tắt, vì nó mở các cổng mạng.\n\n## Thay đổi\n\n- **Bảng tác vụ**: các dự án nằm trong một danh sách ở phần đầu bảng (**Tìm dự án**). Cmd+Shift+K (Ctrl+Shift+K) mở bảng. Thẻ mà bạn đã đọc sẽ rời khỏi **Xong**. **Vừa xong** hiện các thẻ mà bạn đã đọc.\n- **Bảng tác vụ**: **Gỡ tất cả** hỏi trước và giữ lại các thẻ chưa đọc. **Hoàn tác** và **Đã gỡ** đưa thẻ trở lại. Không cuộc trò chuyện nào bị xóa.\n- **Trạng thái dự án**: hàng **Chưa nhóm** trên thanh bên cũng hiện trạng thái của các cuộc trò chuyện trong đó, ví dụ biểu tượng xoay khi một cuộc trò chuyện đang chạy.\n- Tether: cài đặt thông báo được lưu riêng cho từng máy Mac đã ghép nối. Máy Mac mà bạn ghép nối sau sẽ bắt đầu với thông báo tắt.\n- Mỗi ngày một lần, mỗi bản sao hỏi GitHub tệp nhỏ `active.txt` của bản phát hành của nó, để chủ dự án có thể đếm số bản sao của mỗi phiên bản. Yêu cầu này không có id, cookie hay dữ liệu nào về bạn.",
16
- "hi": "## नया\n\n- **अगली इंतज़ार कर रही चैट**: साइडबार के हेडर में एक बटन दिखाता है कि कितनी दूसरी चैट आपका इंतज़ार कर रही हैं, और अगली चैट खोलता है (Cmd+Shift+E, Windows और Linux पर Ctrl+Shift+E)।\n- **विकल्प बटन**: जब कोई जवाब विकल्पों की सूची पर खत्म होता है, तो किसी विकल्प को भेजने के लिए उस पर क्लिक करें। एजेंट के सवाल वाले कार्ड पर 1–9 कुंजियां एक विकल्प चुनती हैं।\n- **नोट के साथ अस्वीकार करें**: मंज़ूरी वाले कार्ड पर लिखें कि क्यों, या उसकी जगह क्या करना है। एजेंट उसी टर्न में अस्वीकृति और आपका नोट पढ़ता है।\n- **सीक्रेट इनपुट**: एजेंट एक निजी कार्ड पर आपसे पासवर्ड या टोकन मांग सकता है। एजेंट को सिर्फ़ एक फ़ाइल का पाथ मिलता है, मान नहीं, और टर्न खत्म होने पर फ़ाइल हटा दी जाती है।\n- **जवाब में उद्धरण**: किसी जवाब का एक हिस्सा चुनें और उसे उद्धरण के रूप में कंपोज़र में डालने के लिए **उद्धरण दें** पर क्लिक करें।\n- **साइड चैट**: चैट की सिर्फ़-पढ़ने वाली कॉपी में एक साइड सवाल पूछें, जबकि चैट काम करती रहती है। **वापस लाएं** जवाब को चैट के कंपोज़र में डालता है।\n- **डिफ़ नोट**: **बदलाव पैनल** में डिफ़ की किसी पंक्ति पर नोट जोड़ें, फिर सभी नोट कंपोज़र में भेजें।\n- **प्रोजेक्ट मेमोरी**: सात नई सुविधाएं। **मेमोरी वर्शन इतिहास**, **मेमोरी को AGENTS.md में एक्सपोर्ट करें**, **मेमोरी नोट का स्रोत लिंक**, **मेमोरी को दूसरे प्रोजेक्ट में कॉपी करें**, **पुराने मेमोरी नोट्स खोजें**, **इस चैट में मेमोरी का उपयोग न करें** और **चैट से मेमोरी नोट्स सुझाएँ**।\n- **रिमोट कंप्यूटर**: Tailscale के ज़रिए अपने दूसरे Mac का dsh खोलें और उनकी चैट यहीं जारी रखें। यह डिफ़ॉल्ट रूप से बंद रहता है, क्योंकि यह नेटवर्क पोर्ट खोलता है।\n\n## बदलाव\n\n- **टास्क बोर्ड**: प्रोजेक्ट अब हेडर की एक सूची में हैं (**प्रोजेक्ट खोजें**)। Cmd+Shift+K (Ctrl+Shift+K) बोर्ड खोलता है। जो कार्ड आप पढ़ लेते हैं, वह **पूरा हुआ** से हट जाता है। **हाल में पूरे हुए** उन कार्ड को दिखाता है जिन्हें आपने पढ़ा है।\n- **टास्क बोर्ड**: **सब हटाएं** पहले पूछता है और बिना पढ़े कार्ड रखता है। **पहले जैसा करें** और **हटाए गए** कार्ड वापस लाते हैं। कोई चैट डिलीट नहीं होती।\n- **प्रोजेक्ट की स्थिति**: साइडबार की **बिना समूह** वाली पंक्ति भी अपनी चैट की स्थिति दिखाती है, जैसे चैट चलते समय स्पिनर।\n- Tether: सूचना सेटिंग हर पेयर किए गए Mac के लिए अलग से सेव होती हैं। बाद में पेयर किया गया Mac सूचनाएं बंद रखकर शुरू होता है।\n- दिन में एक बार, हर कॉपी GitHub से अपनी रिलीज़ की छोटी `active.txt` फ़ाइल मांगती है, ताकि मालिक हर वर्शन की कॉपी गिन सके। इस अनुरोध में कोई id, कुकी या आपके बारे में कोई डेटा नहीं होता।"
4
+ "en": "## New\n\n- **Mobile connect (iPhone)**: Tether notifications can come also while Tether is closed. Put an APNs key in `apns.json` on the Mac (see `tether/README.md`). The Mac then sends the approval, question, error and Turn finished notifications through Apple’s push service. The Mac must be awake with dsh open. Each notification shows the Mac and the chat’s project (`Studio Mac · recipe-box`) and the chat’s title. Turn finished shows the agent’s last reply. This needs a Tether build from this version.\n\n## Fixes\n\n- **Secret input**: the card of a secret request no longer stays inside a closed step group. In the desktop view, the card opens its group, so you see it at once.\n- In a narrow chat, the approval card with **Allow for this chat** and **Reject with note…** puts its buttons on more lines. Each label stays on one line in its button.",
5
+ "zh": "## 新功能\n\n- **手机连接(iPhone)**:Tether 关闭时也能收到 Tether 通知。在 Mac 上把 APNs 密钥放入 `apns.json`(见 `tether/README.md`)。之后 Mac 通过 Apple 推送服务发送审批、提问、错误和 Turn finished 通知。Mac 必须处于唤醒状态并打开 dsh。每条通知显示 Mac 和对话的项目(`Studio Mac · recipe-box`)以及对话标题。Turn finished 显示代理的最后一条回复。这需要此版本的 Tether 构建。\n\n## 修复\n\n- **密钥输入**:密钥请求的卡片不再停留在折叠的步骤组中。在桌面视图中,卡片会展开它所在的组,让你立即看到它。\n- 在较窄的对话中,带有 **本对话内允许** 和 **拒绝并附言…** 的审批卡片会把按钮分成多行。每个按钮的文字保持在一行内。",
6
+ "tr": "## Yeni\n\n- **Mobil bağlantı (iPhone)**: Tether bildirimleri Tether kapalıyken de gelebilir. Mac’te `apns.json` dosyasına bir APNs anahtarı koyun (bkz. `tether/README.md`). Mac bundan sonra onay, soru, hata ve Turn finished bildirimlerini Apple’ın push hizmetiyle gönderir. Mac uyanık ve dsh açık olmalıdır. Her bildirim Mac’i ve sohbetin projesini (`Studio Mac · recipe-box`) ve sohbetin başlığını gösterir. Turn finished, ajanın son yanıtını gösterir. Bunun için bu sürümden bir Tether derlemesi gerekir.\n\n## Düzeltmeler\n\n- **Gizli değer girişi**: gizli değer isteğinin kartı artık kapalı bir adım grubunun içinde kalmaz. Masaüstü görünümünde kart kendi grubunu açar; böylece kartı hemen görürsünüz.\n- Dar bir sohbette, **Bu sohbet boyunca izin ver** ve **Not ile reddet…** düğmelerinin olduğu onay kartı düğmelerini birden çok satıra dizer. Her düğmenin yazısı tek satırda kalır.",
7
+ "es": "## Novedades\n\n- **Conexión móvil (iPhone)**: las notificaciones de Tether pueden llegar también con Tether cerrado. Pon una clave de APNs en `apns.json` en el Mac (consulta `tether/README.md`). Entonces el Mac envía las notificaciones de aprobación, pregunta, error y Turn finished mediante el servicio de notificaciones push de Apple. El Mac debe estar activo y con dsh abierto. Cada notificación muestra el Mac y el proyecto del chat (`Studio Mac · recipe-box`) y el título del chat. Turn finished muestra la última respuesta del agente. Hace falta una compilación de Tether de esta versión.\n\n## Correcciones\n\n- **Entrada secreta**: la tarjeta de una solicitud de secreto ya no se queda dentro de un grupo de pasos cerrado. En la vista de escritorio, la tarjeta abre su grupo, así que la ves enseguida.\n- En un chat estrecho, la tarjeta de aprobación con **Permitir en este chat** y **Rechazar con nota…** reparte sus botones en varias líneas. Cada texto queda en una sola línea dentro de su botón.",
8
+ "pt-BR": "## Novidades\n\n- **Conexão móvel (iPhone)**: as notificações do Tether podem chegar também com o Tether fechado. Coloque uma chave de APNs em `apns.json` no Mac (veja `tether/README.md`). Então o Mac envia as notificações de aprovação, pergunta, erro e Turn finished pelo serviço de notificações push da Apple. O Mac precisa estar ativo e com o dsh aberto. Cada notificação mostra o Mac e o projeto do chat (`Studio Mac · recipe-box`) e o título do chat. Turn finished mostra a última resposta do agente. É preciso uma build do Tether desta versão.\n\n## Correções\n\n- **Entrada secreta**: o cartão de um pedido de segredo não fica mais dentro de um grupo de etapas fechado. Na visualização do desktop, o cartão abre o grupo dele, então você o vê na hora.\n- Em um chat estreito, o cartão de aprovação com **Permitir neste chat** e **Rejeitar com nota…** distribui os botões em mais linhas. Cada texto fica em uma linha dentro do botão.",
9
+ "fr": "## Nouveautés\n\n- **Connexion mobile (iPhone)** : les notifications de Tether peuvent arriver aussi quand Tether est fermé. Placez une clé APNs dans `apns.json` sur le Mac (voir `tether/README.md`). Le Mac envoie alors les notifications d’approbation, de question, d’erreur et Turn finished par le service de notifications push d’Apple. Le Mac doit être éveillé, avec dsh ouvert. Chaque notification indique le Mac et le projet de la discussion (`Studio Mac · recipe-box`) ainsi que le titre de la discussion. Turn finished affiche la dernière réponse de l’agent. Il faut une version de Tether compilée à partir de cette version.\n\n## Corrections\n\n- **Saisie secrète** : la carte d’une demande de secret ne reste plus dans un groupe d’étapes fermé. Dans la vue bureau, la carte ouvre son groupe, vous la voyez donc tout de suite.\n- Dans une discussion étroite, la carte d’approbation avec **Autoriser pour cette discussion** et **Refuser avec une note…** répartit ses boutons sur plusieurs lignes. Chaque libellé reste sur une ligne dans son bouton.",
10
+ "de": "## Neu\n\n- **Mobile Verbindung (iPhone)**: Tether-Benachrichtigungen kommen jetzt auch, wenn Tether geschlossen ist. Lege auf dem Mac einen APNs-Schlüssel in `apns.json` ab (siehe `tether/README.md`). Der Mac sendet dann die Benachrichtigungen zu Freigabe, Frage, Fehler und Turn finished über Apples Push-Dienst. Der Mac muss wach sein und dsh offen haben. Jede Benachrichtigung zeigt den Mac und das Projekt des Chats (`Studio Mac · recipe-box`) sowie den Titel des Chats. Turn finished zeigt die letzte Antwort des Agenten. Dafür ist ein Tether-Build aus dieser Version nötig.\n\n## Korrekturen\n\n- **Geheime Eingabe**: Die Karte einer Geheimnis-Anfrage bleibt nicht mehr in einer geschlossenen Schrittgruppe. In der Desktop-Ansicht öffnet die Karte ihre Gruppe, sodass du sie sofort siehst.\n- In einem schmalen Chat verteilt die Freigabekarte mit **Für diesen Chat zulassen** und **Mit Notiz ablehnen…** ihre Schaltflächen auf mehrere Zeilen. Jede Beschriftung bleibt einzeilig in ihrer Schaltfläche.",
11
+ "ru": "## Новое\n\n- **Мобильное подключение (iPhone)**: уведомления Tether приходят и тогда, когда Tether закрыт. Положите ключ APNs в `apns.json` на Mac (см. `tether/README.md`). После этого Mac отправляет уведомления об одобрении, вопросе, ошибке и Turn finished через push-сервис Apple. Mac должен быть активен, а dsh открыт. Каждое уведомление показывает Mac и проект чата (`Studio Mac · recipe-box`), а также название чата. Turn finished показывает последний ответ агента. Для этого нужна сборка Tether из этой версии.\n\n## Исправления\n\n- **Ввод секрета**: карточка запроса секрета больше не остаётся внутри свёрнутой группы шагов. В режиме настольного приложения карточка раскрывает свою группу, и вы сразу её видите.\n- В узком чате карточка одобрения с кнопками **Разрешить для этого чата** и **Отклонить с примечанием…** располагает кнопки в несколько строк. Надпись каждой кнопки остаётся в одной строке внутри кнопки.",
12
+ "ja": "## 新機能\n\n- **モバイル接続(iPhone)**:Tether を閉じていても Tether の通知が届くようになりました。Mac の `apns.json` に APNs キーを置いてください(`tether/README.md` を参照)。すると Mac は、承認、質問、エラー、Turn finished の通知を Apple のプッシュサービスで送ります。Mac はスリープしておらず、dsh が開いている必要があります。各通知には Mac とチャットのプロジェクト(`Studio Mac · recipe-box`)、チャットのタイトルが表示されます。Turn finished にはエージェントの最後の返信が表示されます。このバージョンからビルドした Tether が必要です。\n\n## 修正\n\n- **シークレット入力**:シークレット要求のカードが、閉じたステップグループの中に隠れたままになることはなくなりました。デスクトップ表示では、カードが自分のグループを開くので、すぐに見えます。\n- 狭いチャットでは、**このチャットで許可** と **メモを付けて拒否…** がある承認カードのボタンが複数行に並びます。各ボタンの文字はボタンの中で 1 行に収まります。",
13
+ "ko": "## 새 기능\n\n- **모바일 연결(iPhone)**: Tether를 닫아 두어도 Tether 알림을 받을 수 있습니다. Mac의 `apns.json`에 APNs 키를 넣으세요(`tether/README.md` 참고). 그러면 Mac이 승인, 질문, 오류, Turn finished 알림을 Apple 푸시 서비스로 보냅니다. Mac은 깨어 있고 dsh가 열려 있어야 합니다. 각 알림에는 Mac과 채팅의 프로젝트(`Studio Mac · recipe-box`), 채팅 제목이 표시됩니다. Turn finished에는 에이전트의 마지막 답변이 표시됩니다. 이 버전으로 빌드한 Tether가 필요합니다.\n\n## 수정 사항\n\n- **비밀 값 입력**: 비밀 값 요청 카드가 더 이상 닫힌 단계 그룹 안에 남아 있지 않습니다. 데스크톱 보기에서 카드가 자기 그룹을 열어 바로 보입니다.\n- 좁은 채팅에서 **이 채팅에서 허용**과 **메모와 함께 거부…**가 있는 승인 카드는 버튼을 여러 줄에 배치합니다. 각 버튼의 글자는 버튼 안에서 한 줄로 유지됩니다.",
14
+ "id": "## Baru\n\n- **Koneksi seluler (iPhone)**: notifikasi Tether kini bisa datang juga saat Tether tertutup. Taruh kunci APNs di `apns.json` pada Mac (lihat `tether/README.md`). Lalu Mac mengirim notifikasi persetujuan, pertanyaan, galat, dan Turn finished lewat layanan push Apple. Mac harus menyala (tidak tidur) dengan dsh terbuka. Setiap notifikasi menampilkan Mac dan proyek obrolan (`Studio Mac · recipe-box`) serta judul obrolan. Turn finished menampilkan balasan terakhir agen. Ini memerlukan build Tether dari versi ini.\n\n## Perbaikan\n\n- **Input rahasia**: kartu permintaan rahasia tidak lagi tetap berada di dalam grup langkah yang tertutup. Di tampilan desktop, kartu membuka grupnya sendiri sehingga Anda langsung melihatnya.\n- Di obrolan yang sempit, kartu persetujuan dengan **Izinkan untuk obrolan ini** dan **Tolak dengan catatan…** menyusun tombolnya dalam beberapa baris. Teks setiap tombol tetap satu baris di dalam tombolnya.",
15
+ "vi": "## Mới\n\n- **Kết nối di động (iPhone)**: thông báo của Tether giờ có thể đến cả khi Tether đã đóng. Đặt một khóa APNs vào `apns.json` trên Mac (xem `tether/README.md`). Khi đó Mac gửi các thông báo phê duyệt, câu hỏi, lỗi và Turn finished qua dịch vụ push của Apple. Mac phải đang thức và dsh phải đang mở. Mỗi thông báo hiển thị Mac và dự án của cuộc trò chuyện (`Studio Mac · recipe-box`) cùng tiêu đề cuộc trò chuyện. Turn finished hiển thị câu trả lời cuối cùng của agent. Cần một bản build Tether từ phiên bản này.\n\n## Sửa lỗi\n\n- **Nhập giá trị bí mật**: thẻ của một yêu cầu bí mật không còn nằm trong một nhóm bước đã thu gọn. Ở chế độ xem desktop, thẻ tự mở nhóm của nó nên bạn thấy thẻ ngay.\n- Trong một cuộc trò chuyện hẹp, thẻ phê duyệt có **Cho phép trong cuộc trò chuyện này** và **Từ chối kèm ghi chú…** xếp các nút thành nhiều dòng. Chữ của mỗi nút nằm trên một dòng trong nút của nó.",
16
+ "hi": "## नया\n\n- **मोबाइल कनेक्ट (iPhone)**: Tether बंद होने पर भी अब Tether सूचनाएँ आ सकती हैं। Mac पर `apns.json` में एक APNs कुंजी रखें (`tether/README.md` देखें)। इसके बाद Mac अनुमति, प्रश्न, त्रुटि और Turn finished सूचनाएँ Apple की पुश सेवा से भेजता है। Mac जागा हुआ होना चाहिए और dsh खुला होना चाहिए। हर सूचना Mac और चैट का प्रोजेक्ट (`Studio Mac · recipe-box`) और चैट का शीर्षक दिखाती है। Turn finished एजेंट का आखिरी जवाब दिखाता है। इसके लिए इस वर्शन से बना Tether बिल्ड चाहिए।\n\n## सुधार\n\n- **सीक्रेट इनपुट**: सीक्रेट अनुरोध का कार्ड अब किसी बंद स्टेप समूह के अंदर नहीं रहता। डेस्कटॉप व्यू में कार्ड अपना समूह खोल देता है, इसलिए आप उसे तुरंत देखते हैं।\n- संकरी चैट में, **इस चैट के लिए अनुमति दें** और **नोट के साथ अस्वीकार करें…** वाला अनुमति कार्ड अपने बटन कई पंक्तियों में रखता है। हर बटन का लेबल बटन के अंदर एक ही पंक्ति में रहता है।"
17
17
  }
18
18
  }