diff --git a/crates/tui/src/prefix_cache.rs b/crates/tui/src/prefix_cache.rs index 8d631ffa..f7903125 100644 --- a/crates/tui/src/prefix_cache.rs +++ b/crates/tui/src/prefix_cache.rs @@ -199,9 +199,9 @@ impl PrefixStabilityManager { &mut self, system_text: &str, tools: Option<&[Tool]>, - ) -> Result { + ) -> Result> { let fp = PrefixFingerprint::compute(system_text, tools); - let old_fp = std::mem::replace(&mut self.current, Some(fp.clone())); + let old_fp = self.current.replace(fp.clone()); self.check_count += 1; let pinned = match &self.pinned { @@ -238,7 +238,7 @@ impl PrefixStabilityManager { // (avoid recomputing the hash — clone was for the change record). self.pinned = Some(fp); - Err(change) + Err(Box::new(change)) } } diff --git a/web/app/[locale]/contribute/page.tsx b/web/app/[locale]/contribute/page.tsx index a0c463c1..cbf5793e 100644 --- a/web/app/[locale]/contribute/page.tsx +++ b/web/app/[locale]/contribute/page.tsx @@ -38,7 +38,7 @@ const stepsEn = [ n: "④", title: "Open the PR", cn: "提交合并", - body: "PR description should explain WHY, not WHAT (the diff covers what). Link the issue. The maintainer reviews everything personally — usually within a day.", + body: "PR description should explain WHY, not WHAT (the diff covers what). Link the issue. The maintainer reviews everything personally — response times vary.", cta: { label: "PR template", href: "https://github.com/Hmbown/deepseek-tui/blob/main/.github/PULL_REQUEST_TEMPLATE.md" }, }, ]; @@ -69,7 +69,7 @@ const stepsZh = [ n: "④", title: "提交 PR", cn: "Open the PR", - body: "PR 描述应说明「为什么」而非「做了什么」(diff 已经展示了做了什么)。关联相关 issue。维护者亲自审查所有 PR——通常一天内完成。", + body: "PR 描述应说明「为什么」而非「做了什么」(diff 已经展示了做了什么)。关联相关 issue。维护者亲自审查所有 PR——响应时间视情况而定。", cta: { label: "PR 模板", href: "https://github.com/Hmbown/deepseek-tui/blob/main/.github/PULL_REQUEST_TEMPLATE.md" }, }, ]; diff --git a/web/app/[locale]/docs/page.tsx b/web/app/[locale]/docs/page.tsx index 7967a085..5312fe67 100644 --- a/web/app/[locale]/docs/page.tsx +++ b/web/app/[locale]/docs/page.tsx @@ -117,8 +117,8 @@ export default async function DocsPage({ params }: { params: Promise<{ locale: s { group: "搜索", tools: "grep_files · file_search · web_search · fetch_url" }, { group: "Shell", tools: "exec_shell · exec_shell_wait · exec_shell_interact" }, { group: "Git / 诊断 / 测试", tools: "git_status · git_diff · diagnostics · run_tests" }, - { group: "子 Agent", tools: "agent_spawn · agent_wait · agent_result · agent_cancel · agent_list · agent_send_input · resume_agent · agent_assign" }, - { group: "递归 LM", tools: "rlm——沙箱 Python REPL,内置 llm_query()/rlm_query() 用于长文本分块处理" }, + { group: "子 Agent", tools: "agent_open · agent_eval · agent_close —— 持久会话,并行执行,通过 var_handle 读取大结果" }, + { group: "递归 LM (RLM)", tools: "rlm_open · rlm_eval · rlm_configure · rlm_close —— 沙箱 Python REPL,内置 peek/search/chunk/sub_query_batch 等辅助函数" }, { group: "MCP", tools: "mcp__——从 ~/.deepseek/mcp.json 自动注册" }, ].map((row) => (
@@ -162,10 +162,9 @@ export default async function DocsPage({ params }: { params: Promise<{ locale: s
 {`# ~/.deepseek/config.toml
-[api]
-key = "sk-..."
+api_key = "sk-..."
 base_url = "https://api.deepseek.com"
-model = "${facts.defaultModel ?? "deepseek-v4-pro"}"      # 默认模型;deepseek-v4-flash 用于快速 / 子智能体
+default_text_model = "${facts.defaultModel ?? "deepseek-v4-pro"}"  # 默认模型;deepseek-v4-flash 用于快速 / 子智能体
 
 [ui]
 default_mode = "agent"                      # plan | agent | yolo
@@ -344,8 +343,8 @@ command = "~/.deepseek/hooks/pre.sh"        # / message_submit / mode_change / o
                     { group: "Search", tools: "grep_files · file_search · web_search · fetch_url" },
                     { group: "Shell", tools: "exec_shell · exec_shell_wait · exec_shell_interact" },
                     { group: "Git / diag / test", tools: "git_status · git_diff · diagnostics · run_tests" },
-                    { group: "Sub-agents", tools: "agent_spawn · agent_wait · agent_result · agent_cancel · agent_list · agent_send_input · resume_agent · agent_assign" },
-                    { group: "Recursive LM", tools: "rlm — sandboxed Python REPL with llm_query()/rlm_query() for chunked processing of long inputs" },
+                    { group: "Sub-agents", tools: "agent_open · agent_eval · agent_close — persistent sessions, parallel execution, bounded result retrieval via var_handle" },
+                    { group: "Recursive LM (RLM)", tools: "rlm_open · rlm_eval · rlm_configure · rlm_close — sandboxed Python REPL with peek/search/chunk/sub_query_batch helpers" },
                     { group: "MCP", tools: "mcp__ — auto-registered from ~/.deepseek/mcp.json" },
                   ].map((row) => (
                     
@@ -387,10 +386,9 @@ command = "~/.deepseek/hooks/pre.sh" # / message_submit / mode_change / o
 {`# ~/.deepseek/config.toml
-[api]
-key = "sk-..."
+api_key = "sk-..."
 base_url = "https://api.deepseek.com"
-model = "${facts.defaultModel ?? "deepseek-v4-pro"}"      # default; deepseek-v4-flash is the fast / sub-agent option
+default_text_model = "${facts.defaultModel ?? "deepseek-v4-pro"}"  # default; deepseek-v4-flash is the fast / sub-agent option
 
 [ui]
 default_mode = "agent"                      # plan | agent | yolo
diff --git a/web/app/[locale]/page.tsx b/web/app/[locale]/page.tsx
index 65ffe610..0ab032ef 100644
--- a/web/app/[locale]/page.tsx
+++ b/web/app/[locale]/page.tsx
@@ -107,7 +107,7 @@ export default async function HomePage({ params }: { params: Promise<{ locale: s
                 href={isZh ? "/zh/install" : "/install"}
                 className="flex-1 sm:flex-none text-center px-5 py-3 bg-ink text-paper font-mono text-sm uppercase tracking-wider hover:bg-indigo transition-colors"
               >
-                {isZh ? "30 秒完成安装 →" : "Install in 30 seconds →"}
+                {isZh ? "立即安装 →" : "Install →"}
               
               
             
- {isZh ? "最快安装 · 一行搞定" : "quickest path · 一行安装"} + {isZh ? "开始使用 · 一行安装" : "get started · 开始使用"}
                 {isZh ? (
@@ -205,16 +205,16 @@ export default async function HomePage({ params }: { params: Promise<{ locale: s
           

- {dispatch.headline} + {isZh && dispatch.headlineZh ? dispatch.headlineZh : dispatch.headline}

- {dispatch.summary} + {isZh && dispatch.summaryZh ? dispatch.summaryZh : dispatch.summary}

{isZh ? "要点" : "Highlights · 要点"}
    - {dispatch.highlights.map((h, i) => ( + {(isZh && dispatch.highlightsZh ? dispatch.highlightsZh : dispatch.highlights).map((h, i) => (
  • {h.tag} @@ -230,11 +230,11 @@ export default async function HomePage({ params }: { params: Promise<{ locale: s
- {dispatch.movers.length > 0 && ( + {(isZh && dispatch.moversZh ? dispatch.moversZh : dispatch.movers).length > 0 && (
{isZh ? "进展" : "Movers · 进展"}
    - {dispatch.movers.map((m) => ( + {(isZh && dispatch.moversZh ? dispatch.moversZh : dispatch.movers).map((m) => (
  • #{m.number} {m.title} @@ -295,7 +295,7 @@ export default async function HomePage({ params }: { params: Promise<{ locale: s
    02 · 沙箱保护

    三种模式,一套审批

    - Plan 只读,Agent 询问,YOLO 自动。沙箱:{facts.sandboxBackends.join("、")}。 + Plan 只读调查,Agent 按需审批,YOLO 自动批准。沙箱:seatbelt (macOS)、landlock (Linux);Windows 受限令牌。

@@ -319,7 +319,7 @@ export default async function HomePage({ params }: { params: Promise<{ locale: s
02 · 沙箱保护

Three modes, one approval system

- Plan reads, Agent asks, YOLO doesn't. Sandboxed via {facts.sandboxBackends.join(", ")}. + Plan reads, Agent requests approval for risky ops, YOLO auto-approves. Sandboxed via seatbelt (macOS), landlock (Linux); Windows restricted tokens.

@@ -395,8 +395,8 @@ export default async function HomePage({ params }: { params: Promise<{ locale: s

{isZh - ? "无 CLA,无赞助商锁定。维护者亲自阅读每一条内容——通常在一天内回复。议题在公开环境下分类。版本从 main 分支发布。" - : "No CLA. No sponsor lockouts. The maintainer reads everything personally — usually within a day. Issues triaged in the open. Releases cut from main."} + ? "无 CLA,无赞助商锁定。维护者亲自阅读每一条内容。议题在公开环境下分类。版本从 main 分支发布。" + : "No CLA. No sponsor lockouts. The maintainer reads everything personally. Issues triaged in the open. Releases cut from main."}

diff --git a/web/app/[locale]/roadmap/page.tsx b/web/app/[locale]/roadmap/page.tsx index ad3e545e..28ff672f 100644 --- a/web/app/[locale]/roadmap/page.tsx +++ b/web/app/[locale]/roadmap/page.tsx @@ -22,11 +22,11 @@ const tracksEn = [ cn: "已完成", color: "jade", items: [ - { title: "Curated 61-tool surface", note: "read, write, edit, patch, grep, shell, git, web search — plus sub-agents, RLM, and MCP" }, - { title: "Sub-agent parallel execution", note: "spawn up to 10 concurrent agents; wait, resume, assign, cancel; results are self-reports" }, - { title: "RLM batched processing", note: "Sandboxed Python REPL with 1–16 cheap parallel children for long-input analysis" }, + { title: "Typed tool surface", note: "read, write, edit, patch, grep, shell, git, web search — plus sub-agents, RLM, and MCP" }, + { title: "Sub-agent parallel execution", note: "agent_open / agent_eval / agent_close; up to 10 concurrent sessions with bounded result handles" }, + { title: "RLM batched processing", note: "Persistent sandboxed Python REPL with 1–16 cheap parallel children for long-input analysis" }, { title: "Three operating modes", note: "Plan (read-only), Agent (default), YOLO (auto-approved); orthogonal suggest / auto / never approval" }, - { title: "Per-platform sandbox", note: "seatbelt (macOS), landlock (Linux), AppContainer (Windows) with workspace boundary" }, + { title: "Per-platform sandbox", note: "seatbelt (macOS), landlock (Linux); Windows containment via restricted tokens (limited)" }, { title: "Durable sessions + tasks", note: "Save, resume, rollback; background task queue with replayable timelines under ~/.deepseek/tasks/" }, { title: "Bidirectional MCP", note: "Consume tools from external servers; expose as server via `deepseek mcp`; ~/.deepseek/mcp.json" }, { title: "Skills + unified slash palette", note: "~/.deepseek/skills/ auto-loading; /help, /mode, /status, /config, /trust, /feedback" }, @@ -73,11 +73,11 @@ const tracksZh = [ cn: "Shipped", color: "jade", items: [ - { title: "61 个精选工具", note: "文件读写、编辑、补丁、搜索、Shell、Git、子 Agent、RLM、MCP——覆盖日常开发全流程" }, - { title: "子 Agent 并行执行", note: "最多 10 个并发;等待、恢复、分配、取消;结果标注为自述不可盲信" }, - { title: "RLM 批量处理", note: "沙箱 Python REPL,支持 1–16 路廉价并行子调用,处理长文本分析" }, + { title: "类型化工具集", note: "文件读写、编辑、补丁、搜索、Shell、Git、子 Agent、RLM、MCP——覆盖日常开发全流程" }, + { title: "子 Agent 并行执行", note: "agent_open / agent_eval / agent_close;最多 10 个并发会话,通过 var_handle 有界读取结果" }, + { title: "RLM 批量处理", note: "持久沙箱 Python REPL,支持 1–16 路廉价并行子调用,处理长文本分析" }, { title: "三种运行模式", note: "Plan(只读)、Agent(默认)、YOLO(自动批准);审批模式正交(建议/自动/拒绝)" }, - { title: "跨平台沙箱", note: "seatbelt(macOS)、landlock(Linux)、AppContainer(Windows),含工作区边界" }, + { title: "跨平台沙箱", note: "seatbelt(macOS)、landlock(Linux);Windows 通过受限令牌实现基础隔离(功能有限)" }, { title: "持久化会话 + 后台任务", note: "保存、恢复、回滚;后台任务队列,可回放时间线,位于 ~/.deepseek/tasks/" }, { title: "双向 MCP 协议", note: "消费外部服务器工具;通过 `deepseek mcp` 暴露为服务器;~/.deepseek/mcp.json" }, { title: "技能 + 统一命令面板", note: "~/.deepseek/skills/ 自动加载;/help、/mode、/status、/config、/trust、/feedback" }, diff --git a/web/components/footer.tsx b/web/components/footer.tsx index ba5f6af5..858b6b13 100644 --- a/web/components/footer.tsx +++ b/web/components/footer.tsx @@ -80,7 +80,7 @@ export function Footer({ locale = "en" }: { locale?: Locale }) {
DeepSeek TUI
- {isZh ? "深度求索 · 终端智能体" : "深度求索 · 终端代理"} + {isZh ? "深度求索 · 终端智能体" : "深度求索 · 终端智能体"}
diff --git a/web/components/nav.tsx b/web/components/nav.tsx index ff41c72a..0b829f93 100644 --- a/web/components/nav.tsx +++ b/web/components/nav.tsx @@ -54,7 +54,7 @@ export function Nav({ locale = "en" }: { locale?: Locale }) {
- {isZh ? "深度求索 · 终端智能体" : "深度求索 · 终端代理"} + {isZh ? "深度求索 · 终端智能体" : "深度求索 · 终端智能体"}
@@ -86,7 +86,7 @@ export function Nav({ locale = "en" }: { locale?: Locale }) { ({ href: l.href, label: l.label, diff --git a/web/lib/deepseek.ts b/web/lib/deepseek.ts index b110f66f..fe27d6c7 100644 --- a/web/lib/deepseek.ts +++ b/web/lib/deepseek.ts @@ -54,13 +54,21 @@ You receive: repo stats and a list of recently updated issues, PRs, and releases Output a single JSON object — no prose around it — matching this exact shape: { - "headline": "string — one short editorial headline summarising the project's pulse this period (max ~70 chars)", - "summary": "string — 2-3 sentences in a calm, factual editorial voice. No marketing fluff. No emoji.", + "headline": "string — English editorial headline (max ~70 chars)", + "summary": "string — 2-3 English sentences, calm factual editorial voice", "highlights": [ { "title": "string", "href": "string", "tag": "shipped|merged|opened|discussion|release", "blurb": "one sentence, max ~120 chars" } ], "movers": [ - { "number": 123, "title": "string", "href": "string", "reason": "one short clause explaining why it matters" } + { "number": 123, "title": "string", "href": "string", "reason": "one short clause" } + ], + "headlineZh": "string — Chinese (zh-CN) editorial headline, rewritten natively, not translated", + "summaryZh": "string — 2-3 Chinese sentences, native zh-CN prose", + "highlightsZh": [ + { "title": "string — zh-CN native", "href": "string", "tag": "shipped|merged|opened|discussion|release", "blurb": "zh-CN one sentence" } + ], + "moversZh": [ + { "number": 123, "title": "string — zh-CN", "href": "string", "reason": "zh-CN clause" } ] } @@ -68,8 +76,10 @@ Rules: - Pick 3-5 highlights and 3-5 movers from the actual provided items. Never invent. - Prefer items with discussion, merged PRs, recent releases, or labelled "good first issue". - Tone: like a small-paper editor — measured, specific, never breathless. -- Never use words like "exciting", "amazing", "powerful", "revolutionary". -- href must be the html_url provided.`; +- Never use words like "exciting", "amazing", "powerful", "revolutionary" (or Chinese equivalents like 令人兴奋, 强大无比, 革命性). +- href must be the html_url provided. +- The zh-CN fields must be native Chinese prose — not a direct translation of the English fields. Write them as a Chinese-speaking maintainer would. +- zh-CN uses full-width punctuation in CJK sentences (。,、).`; export async function curate( apiKey: string, @@ -127,5 +137,7 @@ function sanitizeDispatch(d: Omit): Omit ({ ...h, href: safeHref(h.href) })), movers: (d.movers ?? []).map((m) => ({ ...m, href: safeHref(m.href) })), + highlightsZh: (d.highlightsZh ?? []).map((h) => ({ ...h, href: safeHref(h.href) })), + moversZh: (d.moversZh ?? []).map((m) => ({ ...m, href: safeHref(m.href) })), }; } diff --git a/web/lib/facts.generated.ts b/web/lib/facts.generated.ts index 4ff0eca1..8d538409 100644 --- a/web/lib/facts.generated.ts +++ b/web/lib/facts.generated.ts @@ -18,7 +18,7 @@ export interface RepoFacts { } export const FACTS: RepoFacts = { - "generatedAt": "2026-05-12T22:56:03.599Z", + "generatedAt": "2026-05-13T06:15:45.167Z", "version": "0.8.34", "crates": [ "agent", diff --git a/web/lib/types.ts b/web/lib/types.ts index 0dcae6ab..2c97ecfe 100644 --- a/web/lib/types.ts +++ b/web/lib/types.ts @@ -27,8 +27,14 @@ export interface RepoStats { export interface CuratedDispatch { generatedAt: string; + /** English — always present (backward compat). */ headline: string; summary: string; highlights: { title: string; href: string; tag: string; blurb: string }[]; movers: { number: number; title: string; href: string; reason: string }[]; + /** zh-CN — populated by cron curate since ~May 2026. Falls back to English fields when absent. */ + headlineZh?: string; + summaryZh?: string; + highlightsZh?: { title: string; href: string; tag: string; blurb: string }[]; + moversZh?: { number: number; title: string; href: string; reason: string }[]; }