feat(tasks-ui): readability pass, height-budget fix and leftover sweep
The native port is finished off with the readability work the earlier rounds left open, plus the cleanup of everything the shadcn era or the older canvas left behind. - Geometry: node height is now composed from named parts (chrome, two title lines, meta row) and per-node extras, so a teammate card that carries a task line no longer gets clipped by the old fixed 68px budget; the layout spec follows the new model and GRAPH_ROW_STRIDE stays exported for it. - Readability: row rhythm (28-32px), three ink levels for title/meta/owner, truncation with title hints, current-row and hover expressed as an accent bar plus a hover fill (no shadows), phase frames and edges back on the l1/l2 hairlines, control cluster uniformly 28px, drawer durations on tabular figures, kill action revealed on hover/focus without shifting the row, no horizontal overflow at 360px. - Task window: the markdown body is pulled onto the page scale (12px body, 12/13px headings, tightened list indent and paragraph spacing) while the shared MarkdownText/markdownTextProps contract is untouched. - Cleanup: dead stylesheet rules, unused TSX exports and helpers, stale comments that still described the retired Variant-D canvas, zero-reference i18n keys across the dictionaries, and the Tailwind/shadcn/Variant-D narrative in the design doc, AGENTS.md and the plugin guide (kept as one short "why it was rolled back" section). Verified here: typecheck and lint clean; 133 files / 1413 tests; build with no radix-ui or --tw- strings in lib/client.js (988.9 KiB); the 70-assertion real-browser contract at 70/70 with the 20 reference screenshots regenerated; mount e2e 7/7.
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
## 背景与目标
|
||||
|
||||
DSH 0.1.5-rc.2 引入两个新的可观测面:**workflow**(`dsh-tool-workflow` 的 run/agent 生命周期事件)与 **Agent Teams**(实验层,`ctx.agentTeams` 的共享任务板)。任务管理页(原「子代理拓扑」)系统性地接纳两者,并按用户确认的「简洁后现代主义」方向重构为 **Variant D 工作流图**:分层节点 + 贝塞尔连线、拖拽平移、滚轮缩放、右下角控制条、已完成节点折叠聚合、点击浮窗取代页内 dock。
|
||||
DSH 0.1.5-rc.2 引入两个新的可观测面:**workflow**(`dsh-tool-workflow` 的 run/agent 生命周期事件)与 **Agent Teams**(实验层,`ctx.agentTeams` 的共享任务板)。任务管理页(原「子代理拓扑」)系统性地接纳两者,并按用户确认的「简洁后现代主义」方向重构为**工作流图**:分层节点 + 贝塞尔连线、拖拽平移、滚轮缩放、右下角控制条、已完成节点折叠聚合、点击浮窗取代页内 dock。
|
||||
|
||||
用户确认的关键交互决策(问答摘要):
|
||||
|
||||
@@ -12,7 +12,7 @@ DSH 0.1.5-rc.2 引入两个新的可观测面:**workflow**(`dsh-tool-workflo
|
||||
2. 节点点击 = 跳转转录;ⓘ = 详情浮窗。
|
||||
3. 后台任务输出 = 锚定浮窗(替换页内底部 dock)。
|
||||
4. 自动折叠**只**作用于后台任务抽屉,阈值 8 个代理;图节点的折叠是「已完成」语义的折叠聚合,点击展开、控制条可再折叠。
|
||||
5. 图/树切换按钮在**两种模式下都可用**(mockup 的 toggle 藏在画布容器内、树模式下无法切回——真实实现把控制条移出滚动面)。
|
||||
5. 图/树切换按钮在**两种模式下都可用**(早期设计稿把 toggle 藏在画布容器内、树模式下无法切回——真实实现把控制条移出滚动面)。
|
||||
6. 默认视图由设置 select 决定(默认工作流图),页内切换为临时态。
|
||||
7. 任务板 v1 只做基础操作(完成/重开/删除/改派/新建/编辑,CAS)。
|
||||
|
||||
@@ -69,7 +69,7 @@ client 半(src/client/)
|
||||
- **workflow 无事件 = 空列表不是错误**:旧会话/无 workflow 会话静默为空(jobs 镜像同款语义)。
|
||||
- **fold 规则**:per-parent 的「已完成/出错的**叶子** agent」折叠为一个聚合节点;当前会话、teammate、有子节点的、run 节点**永不折叠**(折叠父节点会藏住活跃分支)。
|
||||
- **树/图同一模型**:fold 状态、团队富化、run 重挂两种模式共享——不会视觉漂移。
|
||||
- **控制条移出滚动面**:图模式的缩放按钮与图/树切换都在视图容器级(绝对定位右下),树模式下缩放按钮不渲染但切换在(mockup bug 的教训,有测试守护)。
|
||||
- **控制条移出滚动面**:图模式的缩放按钮与图/树切换都在视图容器级(绝对定位右下),树模式下缩放按钮不渲染但切换在(早期实现把它放进滚动面、树模式下切不回去——有测试守护)。
|
||||
- **页内视图切换是临时态**,默认视图走 `tasksViewMode` pref(schemastery `z.union([z.const('graph'), z.const('tree')])`——schemastery 无 `z.enum`)。
|
||||
- **AnchoredPopover 不复用 primitives 的 HoverCard**:浮窗需要持久交互(任务板表单、输出滚动),HoverCard 是悬停语义;关闭契约(外部 mousedown / Escape / anchor 离屏的 IntersectionObserver)沿用 selection-popup 已验证的模式。
|
||||
- **主题硬阴影用 `color-mix(in srgb, var(--dsw-alias-border-l1) 55%, transparent)`**:后现代硬投影但颜色全部出自令牌(theme.spec 只守 `color:`,皮肤契约的精神照旧满足)。
|
||||
@@ -90,17 +90,17 @@ client 半(src/client/)
|
||||
|
||||
| 反馈 | 根因 | 修法 |
|
||||
|---|---|---|
|
||||
| 「按钮和文本的颜色不对,不够后现代」 | 新 CSS **17 处裸用 `var(--dsw-alias-accent)`——该令牌在 DSH 主题里不存在**(旧文件的用法都带 fallback 才没暴露),声明被浏览器整条丢弃;容器边框用的 `border-l1` 只有 4% 黑,几乎不可见 | accent → `--dsw-alias-state-business-primary`;容器边 → `--dsw-alias-border-l4`(16%);整体改回 mockup 语言:ink 边框、3px 硬投影、mono 微型字 + 字距大写标签、点阵画布、横向缩放条 |
|
||||
| 「按钮和文本的颜色不对,不够后现代」 | 新 CSS **17 处裸用 `var(--dsw-alias-accent)`——该令牌在 DSH 主题里不存在**(旧文件的用法都带 fallback 才没暴露),声明被浏览器整条丢弃;容器边框用的 `border-l1` 只有 4% 黑,几乎不可见 | accent → `--dsw-alias-state-business-primary`;容器边 → `--dsw-alias-border-l4`(16%);整体回到设计稿语言:ink 边框、3px 硬投影、mono 微型字 + 字距大写标签、点阵画布、横向缩放条 |
|
||||
| 「点 ⓘ 没反应 / 图里点不动(树能点)」 | 画布 `pointerdown` 里对容器 `setPointerCapture`,捕获把派生 click 重定向到容器,节点永远收不到点击(jsdom 不模拟捕获语义,所以单测全绿——**只有真实浏览器能暴露**) | 去掉 capture,pan 仅从背景起手(`closest('[data-graph-node]'/'[data-graph-controls]')` 直接返回),监听挂 window |
|
||||
| 「图很小 / 不在中间 / 任务板没显示」 | fit 在容器为 0 尺寸时静默放弃且不再重试;只居中横轴、上限 1.0;窄面板里 5 个兄弟节点挤成 770px 宽 → 缩到 35% | ResizeObserver + 首次非零尺寸补 fit、双轴居中、`FIT_MIN_SCALE=0.78` 可读性下限;**按容器宽度求解排布**(`layoutTasksGraphForWidth`:先取仍满足可读性预算的最宽排布,只有窄到 ≤1 列才允许 20% 横向溢出);任务板改为**常驻可见条**(不再藏在 chip 后) |
|
||||
| 「卡片信息过多过杂,都被省略看不见」 | 卡片同时塞 displayTitle + 模式 + 状态 + 模型 + live 文本,132px 宽(窄面板的目标宽度)下全部省略号 | 卡片只留三层:标题(1 行)/ mono 元信息(模式或模型 · 状态)/ live 行(仅运行中);其余(会话标题、team 角色、模型全名、最新文本、跳转)进 ⓘ 浮窗 |
|
||||
| 「非常窄,非常挤」 | 设计按宽画布做,未以原生右侧栏窄宽为目标 | 度量全部改按 mockup 的 360×660 基准(卡片 132×46、行距 112);行高/间距/字号显式声明(宿主 body 行高曾把行撑高);`user-select: none` 防拖拽选中文本 |
|
||||
| 「非常窄,非常挤」 | 设计按宽画布做,未以原生右侧栏窄宽为目标 | 度量全部改按窄栏基准(卡片 132×46、行距 112);行高/间距/字号显式声明(宿主 body 行高曾把行撑高);`user-select: none` 防拖拽选中文本 |
|
||||
|
||||
回归面:`tests/tasks-page.spec.tsx` 增 3 例(背景 pointerdown 后节点仍可激活、节点上的手势绝不启动 pan、团队任务板无需点击即常驻可见);`tests/tasks-graph-layout.spec.ts` 重写 9 例(band 换行、换行 band 不得压到兄弟子树行、宽度求解两段式、运行时预留 live 行)。
|
||||
|
||||
### 本地可视化自检 harness(未入库,`tmp-visual/`,git-excluded)
|
||||
|
||||
真实浏览器里的组件级回归无法靠 jsdom 覆盖(点击捕获、fit/居中、主题令牌解析都是浏览器行为)。harness 用 esbuild 把**真实组件** + mockup 形状的 fixture(走 `buildTasksModel`,因此折叠/重挂/富化都真实生效)打包进一个页面,注入从 `dsh-client-ui-theme` 抽出的令牌 CSS,`@deepseek-ai/dsh-client-ui-primitives` 别名到轻量桩(避免把 katex/shiki 资源拖进截图包),再由 Playwright 在 360px / 720px 两档宽度截图并断言:节点点击回调、ⓘ 回调、背景拖拽平移量。本次返工的四条反馈里有三条正是它先复现、修完再确认的。
|
||||
真实浏览器里的组件级回归无法靠 jsdom 覆盖(点击捕获、fit/居中、主题令牌解析都是浏览器行为)。harness 用 esbuild 把**真实组件** + 与 `buildTasksModel` 同形状的 fixture(走同一个模型,因此折叠/重挂/富化都真实生效)打包进一个页面,注入从 `dsh-client-ui-theme` 抽出的令牌 CSS,`@deepseek-ai/dsh-client-ui-primitives` 别名到轻量桩(避免把 katex/shiki 资源拖进截图包),再由 Playwright 在 360px / 720px 两档宽度截图并断言:节点点击回调、ⓘ 回调、背景拖拽平移量。本次返工的四条反馈里有三条正是它先复现、修完再确认的。
|
||||
|
||||
## 第二轮返工(2026-09-14 深夜,13 条反馈)
|
||||
|
||||
@@ -132,9 +132,10 @@ i18n:本轮新增 19 条文案,zh/en/ja + 18 份第三语言词典同步(`
|
||||
|---|---|
|
||||
| `TaskPopover` | 任务板行、节点任务行、节点详情任务清单、新建按钮(4 处) |
|
||||
| `MultilineField` | 任务描述编辑(宿主 primitives 无多行输入,故自建) |
|
||||
| `TaskCreateButton` | 任务板 / 其它入口共用同一外观 |
|
||||
| `AgentGlyph` / `WorkflowGlyph` / `FoldGlyph` / `TaskLine` | 图与树两种模式共用 |
|
||||
|
||||
> **回退后修订**:上表与上一行提到的 `TaskCreateButton` 已删除——它唯一的调用方就是任务板,包一层没有收益;任务板的「新建」现在直接是宿主 outline `Button` + `IconPlusOutline16`(同一文案键 `teamTaskCreate`)。`TaskWindow` / `TaskPopover` / `MultilineField` / `OwnerPicker` 不变。
|
||||
|
||||
## 验证结果(2026-09-14)
|
||||
|
||||
PR:[#680](https://github.com/omdsh-dev/DSH-better-sidebar/pull/680)(分支 `feat/tasks-graph-workflow-teams`)。
|
||||
@@ -147,264 +148,13 @@ PR:[#680](https://github.com/omdsh-dev/DSH-better-sidebar/pull/680)(分支 `
|
||||
|
||||
未在本机自动化验证、留给用户实机确认的一项:3384 桌面应用**重启后**的 UI 级复看(新 bundle 已装进 `~/.dsh/profiles/web`,与仓库构建产物 SHA-256 一致)。
|
||||
|
||||
## shadcn/ui 迁移(2026-09-17,视觉基座替换)—— 已废弃
|
||||
|
||||
> **已废弃(2026-09-21 整体回退)**:本节及其后全部子节(依赖与实际版本 / Tailwind 接入方式 / 令牌映射表 / vendored 组件清单 / 阴影策略 / 体积与 mount 结果 / 真机排障 / stock 风格回调 / 升级路径与本地适配清单 / 页面重组)记录的是 2026-09-17–09-21 期间任务页的 shadcn/ui 视觉基座。该基座已整体回退到插件自有体系,回退根因见文末「回退:任务页回到插件自有体系(2026-09-21,shadcn 层废弃)」。保留全文只为留下排障现场与决策证据——**其中描述的接入方式不再是本仓库或消费插件的建议做法**。
|
||||
|
||||
三轮返工把**行为**收敛到位(统一的详情窗口、常驻任务板、可拖动浮窗),但**视觉基座**仍是自建:
|
||||
|
||||
- 每张卡片 / 每个节点 / 每行都是一次手写样式,同一种「卡片」在四个文件里有四份近似声明;
|
||||
- 卡片自带 `color-mix()` 硬投影与描边,节点一多**满屏阴影相互叠加**,正是「辣眼睛」的根因(阴影是层级手段,被当成了装饰);
|
||||
- 控件形态靠逐处微调对齐,hover / focus-visible / disabled 三态在不同文件里覆盖程度不一。
|
||||
|
||||
处置不是再打磨一轮自建样式,而是**换基座**:把 shadcn/ui 的组件源码 vendoring 进 `src/client/ui/`,样式统一由 Tailwind v4 工具类产出,颜色统一走 shadcn 语义令牌 → `--dsw-*` 的桥接,**静态面板零阴影**(层级改由 1px hairline + 表面阶梯承载)。行为语义、稳定钩子、i18n 全部不变,因此这次迁移对上层是不可见的。
|
||||
|
||||
### 依赖与实际版本
|
||||
|
||||
| 包 | 版本 | 归属 | 作用 |
|
||||
|---|---|---|---|
|
||||
| `radix-ui` | `^1.6.7` | dependencies | vendored 组件的无样式原语(聚合包,不是 `@radix-ui/react-*` 一族) |
|
||||
| `class-variance-authority` | `^0.7.1` | dependencies | `buttonVariants` / `badgeVariants` / `toggleVariants` 的变体表 |
|
||||
| `clsx` | `^2.1.1` | dependencies | `cn()` 的条件拼装 |
|
||||
| `tailwind-merge` | `^3.7.0` | dependencies | `cn()` 的同族工具类去重(调用方的 `px-4` 胜过组件默认的 `px-2`) |
|
||||
| `tailwindcss` | `^4.3.3` | devDependencies | v4 引擎(只构建期用;运行期产物是编译后的 CSS) |
|
||||
| `@tailwindcss/postcss` | `^4.3.3` | devDependencies | 构建管线,被 `tsdown.config.ts` 与 `scripts/ui-css.mjs` 共用 |
|
||||
| `postcss` | `^8.5.26` | devDependencies | 上面的宿主管线 |
|
||||
|
||||
`components.json`(CLI 上下文,非运行期配置):`style: new-york` / `base: radix` / `rsc: false` / `css: src/client/ui/theme.css`,`aliases` 全部指向 `src/client/ui`——**所以 CLI 的默认 `@/lib/utils` 不会出现在这个仓库**(见下文「统一改动」第 2 条)。
|
||||
|
||||
CLI 曾顺手注入一个 `cn: ^0.3.0` 依赖(npm 上真实存在的同名包,仓库里无任何 import)——已删除并 `pnpm install` 重同步 `pnpm-lock.yaml` / `node_modules`。
|
||||
|
||||
### Tailwind 接入方式
|
||||
|
||||
入口是唯一的:`src/client/ui/theme.css`,编译有**两个**消费方但只有一份定义(`tsdown.config.ts` 导出 `compileTailwind()`,`scripts/ui-css.mjs` 复用它产出可视化 harness 的 `tailwind.css`):
|
||||
|
||||
```
|
||||
src/client/ui/theme.css ──┬─ tsdown css-inline 插件(生产)→ 内联进 lib/client.js 的 <style data-plugin>
|
||||
└─ scripts/ui-css.mjs(pnpm ui:css,仅本地 harness)
|
||||
```
|
||||
|
||||
**为什么只引 `theme` + `utilities`**:插件注入的样式表是**全局 `<style data-plugin>`**(`injectTag()`,无 shadow DOM)。Tailwind 的完整入口 `@import "tailwindcss"` 会连带 preflight,而 preflight 的 `*,::before,::after { box-sizing; margin: 0; padding: 0; border: 0 solid }` 与 `html { -webkit-text-size-adjust }` 是对**整张 DSH 宿主页面**的重置——会话正文、原生右侧栏、设置页全部会被改版。所以只引:
|
||||
|
||||
```css
|
||||
@import "tailwindcss/theme.css" layer(theme);
|
||||
@import "tailwindcss/utilities.css" layer(utilities);
|
||||
@source "../**/*.tsx";
|
||||
```
|
||||
|
||||
`@source` 是**显式**的:不给它,Tailwind 会以项目根为扫描面,把 `lib/`、`tests/`、`node_modules/` 里像类名的字符串也算进产物(既胖又不可控)。它只扫 `src/client/**/*.tsx`。
|
||||
|
||||
**深浅主题**:`@custom-variant dark (&:where([data-ds-dark-theme], [data-ds-dark-theme] *))` —— DSH 的主题翻转是给 `<body>` 打 `data-ds-dark-theme`,不是加 `.dark` 类(不给这条 `@custom-variant`,Tailwind 的 `dark:` 变体会去找 `.dark` 祖先,在本宿主里**永远不会命中**)。但**本次迁移把所有 `dark:` 覆写都删了**:`--dsw-*` 令牌本身就随主题翻转,再写一遍 `dark:` 是双重记账(上游 `dark:bg-destructive/60`、`dark:border-input`、`dark:aria-invalid:ring-destructive/40`、`dark:hover:bg-accent/50` 全属此类)。`@custom-variant` 保留是为了将来确需「令牌之外」的主题分支时有正确锚点。
|
||||
|
||||
**级联层与 `dsw-tasks` 作用域根类**(这一条是本仓库特有的坑):宿主的样式表是**无层级(unlayered)**的,而无层级声明**优先于任何 `@layer` 内的声明**——与特异性无关。也就是说 `layer(utilities)` 里的 `.rounded-md` 打不过宿主任何一条裸元素规则。补偿手段是把页面自己的补偿规则放进层里但抬到**类特异性**,并挂在 **`.dsw-tasks`**(任务页根类,`SubagentView` 的页面根 + `TaskWindow` 的内容根)上:
|
||||
|
||||
```css
|
||||
@layer base {
|
||||
.dsw-tasks { color: var(--dsw-alias-label-primary); }
|
||||
.dsw-tasks :where(button, input, textarea, select) { font: inherit; }
|
||||
.dsw-tasks :where(*, *::before, *::after) { box-sizing: border-box; }
|
||||
.dsw-tasks :where(a, button, input, textarea, select, [tabindex]):focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: 1px; }
|
||||
}
|
||||
```
|
||||
|
||||
`:where()` 把元素重置压回类特异性,所以这几条既到得了页面内的元素,又**不越出 `.dsw-tasks`**——用作用域根类换回了 preflight 里真正需要的三条(`box-sizing` / 控件继承字体 / 前景色),代价是不碰宿主页面。附带的两组:`@layer utilities` 里的细滚动条(走 `--dsw-alias-scrollbar-*`)与 `@media (prefers-reduced-motion: reduce)` 的动效全量关闭。
|
||||
|
||||
**`radix-ui` 的入口解析**:`tsdown.config.ts` 把 `module`/`browser` 放在 `mainFields` 首位(`react-remove-scroll` 家族的 `main` 是 `dist/es5`),并给 `tailwind-merge` 加显式 alias(它的 exports map 把 `require` 列在 `import` 之前,会解析到不可 tree-shake 的 `bundle-cjs.js`)。
|
||||
|
||||
### shadcn 令牌 → `--dsw-*` 映射表
|
||||
|
||||
`theme.css` 的 `:root` 是唯一的桥。每个值都是 `var(--dsw-…)` 引用,**没有颜色字面量**;`@theme inline` 把这些名字再接成 Tailwind 的 `--color-*`(`inline` 保证产物里留着 `var(--background)` 这层间接,宿主皮肤改令牌能立刻生效)。
|
||||
|
||||
| shadcn 令牌 | DSH 令牌 | 备注 |
|
||||
|---|---|---|
|
||||
| `--background` | `--dsw-alias-bg-base` | |
|
||||
| `--foreground` | `--dsw-alias-label-primary` | 正文墨色第 1 档 |
|
||||
| `--card` | `--dsw-alias-bg-layer-1` | 表面阶梯第 2 级(静态面板) |
|
||||
| `--card-foreground` | `--dsw-alias-label-primary` | |
|
||||
| `--popover` | `--dsw-alias-bg-layer-2` | 表面阶梯第 3 级(浮层) |
|
||||
| `--popover-foreground` | `--dsw-alias-label-primary` | |
|
||||
| `--primary` | `--dsw-alias-state-business-primary` | 只给主操作 / 焦点环 / 进行中 |
|
||||
| `--primary-foreground` | `--dsw-alias-label-primary-foreground` | |
|
||||
| `--secondary` | `--dsw-alias-interactive-bg-hover` | |
|
||||
| `--secondary-foreground` | `--dsw-alias-label-primary` | |
|
||||
| `--muted` | `--dsw-alias-interactive-bg-hover` | |
|
||||
| `--muted-foreground` | `--dsw-alias-label-secondary` | 墨色第 2 档 |
|
||||
| `--accent` | `--dsw-alias-interactive-bg-hover` | |
|
||||
| `--accent-foreground` | `--dsw-alias-label-primary` | |
|
||||
| `--destructive` | `--dsw-alias-state-error-primary` | 错误 / 删除 |
|
||||
| `--destructive-foreground` | `--dsw-alias-label-primary-foreground` | 上游此处是 `text-white`(迁移时删掉的唯一颜色字面量) |
|
||||
| `--border` | `--dsw-alias-border-l4` | 1px hairline 的来源 |
|
||||
| `--input` | `--dsw-alias-border-l4` | |
|
||||
| `--ring` | `--dsw-alias-state-business-primary` | |
|
||||
| `--success` | `--dsw-alias-state-success-primary` | 非 stock shadcn,任务状态需要 |
|
||||
| `--warning` | `--dsw-alias-state-warn-primary` | 非 stock shadcn,阻塞 / 审批需要 |
|
||||
| `--foreground-3` | `--dsw-alias-label-tertiary` | 墨色第 3 档(靠重量分层,不靠色数) |
|
||||
| `--border-strong` | `--dsw-alias-label-tertiary` | 需要更实的分隔时用 |
|
||||
|
||||
圆角是唯一不来自令牌的一组(`--radius` 6px / `sm` 4px / `md` 6px / `lg` 8px / `xl` 12px,纯几何,与皮肤无关);字体走 `--font-sans: var(--dsw-font-family-default)` / `--font-mono: var(--dsw-font-family-code)`,所以插件不可能与 DSH 的字阶漂移。
|
||||
|
||||
### vendored 组件清单与对上游的每处改动
|
||||
|
||||
安装命令(16 个组件,17 个文件——`toggle.tsx` 是 `toggle-group` 的 cva 依赖,随 `add` 一起到达):
|
||||
|
||||
```
|
||||
npx -y shadcn@latest add button card badge separator input textarea tooltip popover \
|
||||
dropdown-menu scroll-area collapsible toggle-group skeleton spinner empty
|
||||
```
|
||||
|
||||
按**消费面**清点(`src/client/ui/` 下 18 个文件:16 个组件 + `toggle.tsx` + `utils.ts`):
|
||||
|
||||
> **两个当前无消费者的文件**:`popover.tsx` 与 `skeleton.tsx`。浮层全部走自建的 `AnchoredPopover`(它需要锚定 + 拖动 + 关闭契约,shadcn popover 是 portal 语义,两者不通用),加载态走 `Spinner`。二者按简报要求随 `add` 一起 vendoring 进来,**保留原样**——但「保留」不等于「发货」:实测 `lib/client.js` 里**这两个模块的代码与 `@radix-ui/react-popover` 全部缺席**(rollup 按 import 图 tree-shake;`toggle.tsx` 则相反,`toggle-group` 只取 `toggleVariants`,模块在包内而 `Toggle` 组件不在)。若下次复盘确认仍无消费者,删除这两个文件是纯收益(少两份要跟上游 diff 的源码)。
|
||||
|
||||
| 文件 | 实际消费者 | 上游改动摘要 |
|
||||
|---|---|---|
|
||||
| `button.tsx` | JobsDrawer / SubagentView(别名 `UiButton`)/ TaskWindow / TasksGraph / TasksPopovers | 删 `link` 变体与 `xs` / `lg` / `icon-xs` / `icon-sm` / `icon-lg` 尺寸;`outline` 去掉 `shadow-xs` |
|
||||
| `card.tsx` | TaskWindow / TasksGraph / TasksPopovers / TeamBoard | 去掉卡片阴影(静态面板零阴影) |
|
||||
| `badge.tsx` | JobsDrawer / TaskWindow / TasksGraph / TasksPopovers / TeamBoard | 删 `ghost` / `link` 变体;`text-white` → `--destructive-foreground` |
|
||||
| `separator.tsx` | TaskWindow / TasksPopovers / TeamBoard | 无(保留 `data-slot` 与 orientation 数据属性) |
|
||||
| `input.tsx` | TaskWindow | 删上游 7 条 `file:` 变体工具类 |
|
||||
| `textarea.tsx` | TaskWindow | 无 |
|
||||
| `tooltip.tsx` | SubagentView / TasksGraph | 删 `dark:` 覆写 |
|
||||
| `popover.tsx` | **无消费者**(见下) | 只保留 `shadow-md`(真浮层)、删 `dark:` 覆写;删 `PopoverHeader` / `PopoverTitle` / `PopoverDescription` |
|
||||
| `dropdown-menu.tsx` | TeamBoard(改派负责人子菜单) | 删 `DropdownMenuCheckboxItem` / `DropdownMenuRadioGroup` / `DropdownMenuRadioItem`(无消费者,顺带消灭唯一的 `CircleIcon` 用法)、删 `DropdownMenuShortcut`;保留 `Sub` 家族;子菜单箭头换宿主图标;`shadow-md` / `shadow-lg` 保留(真浮层) |
|
||||
| `scroll-area.tsx` | JobsDrawer / TasksTree | 无 |
|
||||
| `collapsible.tsx` | JobsDrawer / TasksTree | 无 |
|
||||
| `toggle-group.tsx` | TaskWindow / TeamBoard | 删 `shadow-none`;`src/client/ui/toggle` → `./toggle` |
|
||||
| `toggle.tsx` | 无直接消费者(`toggle-group` 的 cva 依赖) | 删 `lg` 尺寸;`toggleVariants` 保留 |
|
||||
| `skeleton.tsx` | **无消费者**(见上) | 无 |
|
||||
| `spinner.tsx` | TasksTree | **重建**在宿主 `IconLoadingOutline16` 上(上游用 `Loader2Icon`),可访问状态包一层 `role="status"` |
|
||||
| `empty.tsx` | SubagentView / TeamBoard | 删 `dark:` 覆写 |
|
||||
| `utils.ts` | 全部 vendored 组件 | CLI 重建后重写(`clsx` + `twMerge`) |
|
||||
|
||||
逐条列出六类**统一改动**(每处在文件里都有注释说明理由):
|
||||
|
||||
1. **图标一律换宿主 primitives**:删掉 `lucide-react` 后,vendored 文件里只剩两处图标 import——`spinner.tsx` 的 `IconLoadingOutline16`(并据此重建了组件)与 `dropdown-menu.tsx` 的 `IconChevronRightOutline14`(子菜单箭头)。**没有新写一个 SVG**。宿主图标渲染的就是 `svg`,所以组件里的 `[&_svg]` / `[&_svg:not([class*='size-'])]:size-4` 选择器照旧成立。
|
||||
2. **`import { cn } from "cn"` → `./utils`**(全部 16 个文件):CLI 默认写的是 `cn` 这个**npm 上真实存在的包名**,本项目没有该依赖;同时 `toggle-group` 的 `src/client/ui/toggle` 改成相对路径 `./toggle`。全目录不再有 `@/lib/utils` 与裸包名 alias。
|
||||
3. **删所有 `dark:` 颜色覆写**(理由见上)。
|
||||
4. **非浮层变体删 `shadow-*`**:上游给 `card`(`shadow-sm`)/ `input`(`shadow-xs`)/ `textarea`(`shadow-xs`)/ `toggle`(outline 的 `shadow-xs`)/ `toggle-group`(`shadow-xs` + `data-[spacing=0]:shadow-none`)/ `button`(outline 的 `shadow-xs`)都带了投影,全部删除。迁移后全目录只剩三处 `shadow-*`:`popover.tsx` 一处 `shadow-md`、`dropdown-menu.tsx` 的 `shadow-md` 与 `shadow-lg`。**静态面板零阴影是设计语言,不是遗漏。**
|
||||
5. **删无消费者的变体 / 尺寸 / 子组件**:`button` 的 `link` + 5 个尺寸、`badge` 的 `ghost` / `link`、`toggle` 的 `lg`、`popover` 的 `PopoverHeader` / `PopoverTitle` / `PopoverDescription`、`dropdown-menu` 的 `DropdownMenuShortcut`。它们都是**运行期对象里的类字符串**,留着就会进 bundle。
|
||||
6. **`input.tsx` 的 `file:` 类删除是双重理由**:页面没有 `<input type="file">` 面,且它们编译出 `::file-selector-button` 选择器——那正是 Tailwind preflight 的特征串,构建产物守卫用它证明「preflight 从未入包」。保留这 7 条会让该守卫**永远误报**。守卫本身也据此收紧了识别方式:改判「chunk CSS 里的重置声明负载 + html 块」,而不是选择器拼写(`tests/ui-bundle.spec.ts` 的 docstring 记录了这次修正)。
|
||||
|
||||
外加上游 CLI 之外的两件事:`package.json` 删除 CLI 注入的 `cn` 依赖;`theme.css` 与 `utils.ts` 曾在迁移中误删,按同一定义重建并重新逐条复核(两者都由 `tests/ui-foundation.spec.ts` 完整守护,重建后全绿)。
|
||||
|
||||
### 阴影策略(静态面板零阴影,仅浮层)
|
||||
|
||||
层级由「重量」承担:1px `border-border` hairline + 表面阶梯(`background` → `card`/`layer-1` → `popover`/`layer-2`)+ 三档墨色。**阴影只允许出现在真正浮动、由自己的锚定几何定位的层**:
|
||||
|
||||
| 允许阴影 | 位置 |
|
||||
|---|---|
|
||||
| `AnchoredPopover`(`shadow-lg`) | 任务窗口 / 节点详情 / 输出浮窗的外壳(自建锚定 + 拖动) |
|
||||
| `ui/popover.tsx`(`shadow-md`) | portal 渲染的 shadcn popover |
|
||||
| `ui/dropdown-menu.tsx`(`shadow-md` / `shadow-lg`) | portal 渲染的菜单与子菜单 |
|
||||
| `ui/tooltip.tsx`(**白名单成员但当前不带阴影**) | portal 渲染的 tooltip 本来就是实心 `bg-foreground` 反色块,不需要投影;列入 `FLOATING_FILES` 只是承认它是浮层 |
|
||||
|
||||
守护是**源码级**的(`tests/ui-shadows.spec.ts`):`STATIC_PANEL_FILES`(页面内布局的 10 个文件)不得出现任何 Tailwind 阴影工具类,`FLOATING_FILES` 是唯一白名单,且最后一条断言要求白名单**不空转**(`AnchoredPopover` 必须真的带阴影,否则白名单在替别处的回归打掩护)。`box-shadow` 声明式写法同样被禁。
|
||||
|
||||
### 实测体积与 mount 结果(含返工:把任务页下沉为懒加载 chunk)
|
||||
|
||||
第一次门禁的唯一未达成项是体积:迁移后 `lib/client.js` **1452623 bytes(1418.6 KiB)**,比基线 +457.6 KiB,超出计划里 +250 KiB 的预算。定位结论是**浮层栈的固有成本**(`radix-ui` 的 popover / dropdown-menu / tooltip / scroll-area / collapsible 一族 + `floating-ui` + `react-remove-scroll` + `tailwind-merge`,逐生成行归属:浮动层 263.9 KiB、tailwind-merge 59.4 KiB)。
|
||||
|
||||
处置不是放宽预算,而是**把这层负载移出启动路径**:任务页(工作流图 + 树 + 任务窗口 + 团队任务板 + 后台任务抽屉 + 整个 vendored shadcn 层与其样式表)整体下沉为既有的懒加载 chunk——
|
||||
|
||||
- `src/client/chunks/tasks.tsx` 只 re-export `SubagentView`,并 `import '../ui/theme.css'`(Tailwind 产物随 chunk 走,不占核心包);
|
||||
- `CHUNK_NAMES`(`src/bundle-route.ts`)与 `CHUNKS`(`tsdown.config.ts`)与 `ChunkName`(`chunk-loader.ts`)各加一个 `tasks`,产出 `lib/client-tasks.js`,经 `/sidebar/bundle/tasks.js` 按需下发;
|
||||
- 任务页的 tab 描述符改用 `lazyChunkComponent('tasks', mod => mod.SubagentView)`(与终端同款机制:加载中显示占位、失败显示重试),**核心包不再静态 import 任何 chunk 入口**;
|
||||
- 从未打开任务页的用户完全不下载这 700 KiB;stub/树/浮窗的既有 hook 与行为全部不变。
|
||||
|
||||
返工后实测(同一次 `pnpm build`):
|
||||
|
||||
| 指标 | 值 |
|
||||
|---|---|
|
||||
| `lib/client.js`(迁移前基线,HEAD `12b4716` 同工具链实测) | 1012271 bytes = 988.5 KiB |
|
||||
| `lib/client.js`(迁移后) | **855612 bytes = 835.6 KiB** |
|
||||
| 核心包增量 | **−156659 bytes(−153.0 KiB,比迁移前更小)** |
|
||||
| `lib/client-tasks.js`(打开任务页时才拉) | 723656 bytes = 706.7 KiB |
|
||||
| 体积预算(核心包 ≤ 基线 +250 KiB) | ✅ 达成(且核心包净减) |
|
||||
| 核心包含 Tailwind / radix / tailwind-merge / `oklch(` / `lucide-react` | 全部为 0(由 `tests/ui-bundle.spec.ts` 断言) |
|
||||
| `lib/client-tasks.js` 含 Tailwind 产物 + radix + 令牌桥 | ✅(同一 spec 断言) |
|
||||
|
||||
因此 `tests/ui-bundle.spec.ts` 现在**双向断言**:核心包必须干净(无 utilities/radix/tailwind-merge、无 preflight、无调色板字面量)且 ≤ 基线 +250 KiB;chunk 必须携带 Tailwind 产物、radix 层、`var(--dsw-…)` 桥接与 `__dshChunks__["tasks"]` 槽位,同样不得带 preflight/oklch/lucide。
|
||||
|
||||
其余门禁(同一份构建产物):
|
||||
|
||||
- `pnpm typecheck` 0;`pnpm lint` 0;`pnpm vitest run` **136 文件 / 1499 用例通过 / 9 skipped**;
|
||||
- `pnpm build` 的四条产物断言全绿:Tailwind 产物确在包内(`--tw-*` + `.flex{`)、**无 preflight**、**无 `oklch(`**、**无 `lucide-react`**;
|
||||
- `pnpm pack` ✅;`pnpm test:mount`(真实挂载 + 无头 tab 全扫)**7/7**,`PERF_JSON`:`mountLatencyMs 437`、`longtaskCount 2`(≤ 8 预算)、并且资源清单里出现 **`/sidebar/bundle/tasks.js`** —— 懒加载路径在真实 DSH 外壳里被走到。
|
||||
|
||||
新增的守护文件:`tests/ui-foundation.spec.ts`(入口 import 清单 / 令牌桥全表 / 级联层 / 作用域根类 / `@source`)、`tests/ui-bundle.spec.ts`(核心包与 chunk 的双向产物断言 + 体积预算)、`tests/ui-shadows.spec.ts`(静态面板零阴影)。`tests/theme.spec.ts` 追加「迁移后皮肤契约」一节:`src/client/ui/**` 与迁移文件的**颜色字面量**、**Tailwind 默认调色板类**与**未解析 `var()`** 三类回归。
|
||||
|
||||
### 真机"完全没有 CSS"的根因:缺 preflight 导致表单控件保留 UA 样式(2026-09-20)
|
||||
|
||||
真机反馈:任务页"看起来完全没有 CSS,边框非常模糊"。第一反应是 Tailwind 没下发或级联被宿主压过,**两个假设都被实验否掉**:
|
||||
|
||||
- **样式确实下发**:chunk 里含注入代码与完整 CSS 文本,真机资源清单里 `/sidebar/bundle/tasks.js` 200;页面能看出我们的两行标题截断、Badge、ToggleGroup 等布局。
|
||||
- **级联不是根因**:用真实宿主样式表(`dsh-web-frontend` 的 index+vendor CSS)+真实编译产物做受控样本,`padding/radius/border/background/font` 全部是我们的值胜出;宿主 CSS 模块是哈希类名(`button._cfgyt_4`)只命中宿主自己的元素,全局 `button{}` 只有元素级特异性(0,0,1)压不过工具类(0,1,0)。
|
||||
|
||||
**真根因**:我们**刻意排除 preflight**(它会重绘整个宿主页面),但 preflight 同时负责**归零表单控件**。于是插件里的 `<button>` 全部保留浏览器 UA 外观 —— 在真实浏览器里对一个只写了 `size-7` 的图标按钮实测:`padding: 1px 6px`、`border: 2px outset`、`background: ButtonFace`(#efefef)、`font: 400 13.33px system-ui`。这正是"灰扑扑的立体小方块 + 发虚的双线边框 + 字号不搭"的来源;`<input>`/`<textarea>`/`<select>` 同理。
|
||||
|
||||
**修法**(`src/client/ui/theme.css`):在 `@layer base` 内补一份**限定 `.dsw-tasks` 作用域**的 preflight 子集(`margin/padding` 归零、`border-width/style` 归零、`background-color/-image` 归零、`color/letter-spacing: inherit`、`appearance: none`、`cursor: pointer`、`:disabled` 默认光标),全部写在 `:where()` 里保持 (0,1,0),与工具类同特异性但在**更晚的 `utilities` 层**,所以只清掉"没人要的" UA 外观、不抢我们自己的类。同时**显式声明 `@layer theme, base, components, utilities;`**:层序按首次出现决定,否则 `@import ... layer(utilities)` 会把 utilities 注册在 `base` 之前,让 reset 反过来压住 `rounded-md`(实测按钮渲染成直角)。产物里已核对层序为 `properties → theme → base → components → utilities`。
|
||||
|
||||
**为什么两层验证都漏了**:本地可视化 harness 的页面没有宿主样式、也没人量过 `getComputedStyle`,UA 外观被当成"我的极简风格";挂载冒烟断言的是"不崩 + 无 console 错误",样式正确性不在其内。**因此把"真实宿主样式表 + 真实编译产物 + 真实组件"的镜像页面加入视觉验证流程**(`index-host.html`),并补两条源码级守卫(`tests/ui-foundation.spec.ts`:作用域 reset 的声明必须存在;层序声明必须出现在 import 之前)。
|
||||
|
||||
### shadcn/ui stock 风格回调(2026-09-20)
|
||||
|
||||
用户的明确诉求是"**shadcn/ui 默认风格就行**"——此前那套"零阴影 + 1px 细线 + 11–13px 字"的极简取向被判定为"像没上样式"。回调原则:**stock 组件默认值优先,只保留画布必需的紧凑化**。改动(11 个文件):
|
||||
|
||||
- **阴影**:静态卡片/面板恢复 stock 轻阴影(按钮 `shadow-xs`、卡片/面板 `shadow-sm`);浮层继续 `shadow-lg`。`tests/ui-shadows.spec.ts` 的规则从"静态面板零阴影"改为"静态面板只允许 `shadow-xs`/`shadow-sm`,禁用 `shadow-md` 及以上与裸 `box-shadow`",浮层白名单不变且断言其非空转。
|
||||
- **字号**:正文 `text-sm`(14px)、meta `text-xs`(12px) 全面替换 `text-[13px]`/`text-[11px]`/`text-[10px]`;等宽只留 id/时长/工具参数。页面基准字号由 `.dsw-tasks` 的 `font-size: .875rem` 提供。
|
||||
- **组件**:状态一律用 vendored `Badge` 的 stock 变体(进行中 `default`、待办/完成 `secondary`、阻塞 `outline`+warning 墨色、错误 `destructive`);控制条与非图标按钮回到 `Button variant="outline" size="sm"`;行内操作(任务行菜单、抽屉终止)改为 hover/focus 显现但仍可键盘触达;任务窗口/面板内边距回到 stock(`p-4`/`p-6`)。
|
||||
- **画布**:节点卡 `rounded-lg border bg-card p-2.5 shadow-xs`,`GRAPH_NODE_W` 150→176、`GRAPH_NODE_H` 60→68(字号变大后需要宽度);相位框加 `bg-muted/40`。
|
||||
- **窄面板不再退化成单列**:`bandColsFor` 改为**按可读性下限预算列数**(`宽度/0.78` 而不是 1:1),360px 面板恢复两列(缩放 ~0.86);同时把 `FIT_MIN_SCALE` 提升为布局模块导出的 `GRAPH_FIT_MIN_SCALE`,让 fit 与列预算共用同一个下限常量。
|
||||
|
||||
### 迁移返工记录(门禁与审查发现)
|
||||
|
||||
**1. 体积 → 任务页整体下沉为懒加载 chunk。** 见上一节的返工说明:核心包从 988.5 KiB 降到 835.6 KiB(净减 153.0 KiB),shadcn/radix/Tailwind 产物(706.7 KiB)随 `lib/client-tasks.js` 按需加载。这次返工同时把 Tailwind 样式表挪进 chunk——它只服务任务页,没有理由占启动路径。
|
||||
|
||||
**2. React 18 的 ref 兼容(vendored 组件的必要本地适配)。** DSH 宿主跑的是 **React 18**(`@deepseek-ai/dsh-client-ui-primitives` 的 peer 是 `react@^18.2.0`),而 shadcn registry 的组件是按 **React 19** 写的(19 起 `ref` 是普通 prop,所以上游 `Button` 刻意不写 `forwardRef`)。后果:`<TooltipTrigger asChild><Button/></TooltipTrigger>` 里 radix 的 `Slot` 把 ref 递给函数组件会被丢掉 —— **dev 构建打印 "Function components cannot be given refs",生产构建静默地量不到锚点**(浮层定位失效)。修法是在 `src/client/ui/button.tsx` 上做一处有注释的本地适配(`React.forwardRef`),并在文件里写明升级时会被 CLI `--diff` 抹掉、需要重新施加。**这条只在 dev/可视化 harness 里可见,生产 bundle 不报错,所以 mount e2e 抓不到它** —— 依赖 harness 的 console 断言。
|
||||
|
||||
**3. 密度回归 → 卡片两行标题。** 迁移把卡片文字从 11px 提到 shadcn 的 13px,但节点宽度仍是 132px:实测标题只剩约 7 个汉字("图形重布重写" 被截成 "图…"),密集场景下比迁移前更难读。修法:`GRAPH_NODE_W` 132 → 150、标题改 `text-xs` + `line-clamp-2` + `[overflow-wrap:anywhere]`、`GRAPH_NODE_H` 46 → 60 预留两行高度(`GRAPH_LIVE_H` 13 → 14)。**教训:换字号必须同步核对卡片宽度预算**。
|
||||
|
||||
**4. 模型去重(重复 React key 的根因)。** 可视化 harness 在压力 fixture 上抓到 `sub-live-011` 等三个重复 key:根因在 `tasks-model.ts` —— workflow member 的 `childId` 若**不在 run 发起者的 catalog 里**(但存在于树中别处),代码会走"合成节点"分支,生成一个与真实节点**同 id** 的第二张卡片。修法:先按整棵树收集 `knownAgentIds`,只对 catalog 完全不知道的 id 合成节点;并在返回前加一条"每个 session id 只出现一次"的兜底去重。新增两条单测(已知 member 不重复 / 未知 member 仍合成)。
|
||||
|
||||
### 升级路径与本地适配清单(stock 优先)
|
||||
|
||||
**政策(2026-09-20 起):与上游 stock 保持一致优先,本地改动只保留"不这样就得坏"的那几条。** 早先那版"裁剪变体、去阴影、压字号"的本地取向已被真机反馈否掉(用户要求"改为 shadcn/ui 最新的默认样式对齐"),因此 `src/client/ui/**` 用 `npx shadcn@latest add … --overwrite` 整批刷成了最新 registry(new-york v4 / radix base),并**重新施加**下面这份最小适配清单:
|
||||
|
||||
| # | 本地适配 | 为什么必须 |
|
||||
|---|---|---|
|
||||
| 1 | `cn` 从 `./utils` 导入;跨组件 import 写显式 `./x.tsx` | registry 写的是虚拟别名 `cn` 与裸 `src/client/ui/...` 说明符,本项目没有那些解析规则 |
|
||||
| 2 | 图标一律用宿主 `@deepseek-ai/dsh-client-ui-primitives` 的 `IconXxx` | 皮肤契约禁 lucide;宿主图标随主题变色。`spinner.tsx` 的 `Loader2Icon` → `IconLoadingOutline16`(外层 span 承接 props),`dropdown-menu.tsx` 的勾/箭头 → `IconCheckOutline16`/`IconChevronRightOutline14`,单选圆点用 `span.bg-current` |
|
||||
| 3 | 删除所有 `dark:` 变体 | 令牌本身随宿主深浅主题翻转,`dark:` 是多余且会改写宿主主题语义(技能规则也禁手写 dark 覆盖) |
|
||||
| 4 | `text-white` → `text-destructive-foreground` | 无颜色字面量是皮肤契约的硬线 |
|
||||
| 5 | `Button` 保留 `React.forwardRef` | 宿主是 **React 18**,`asChild` 触发器要 ref 才能量到锚点(registry 面向 React 19,不写 forwardRef) |
|
||||
| 6 | 删除 `tw-animate-css` 的动画工具类(`animate-in`/`fade-in-*`/`zoom-in-*`/`slide-in-from-*`) | 该依赖未安装;装了它会向**我们不拥有的宿主页面**注入通用 `@keyframes` 名字,有与宿主动画撞名的风险。缺省即"立即出现",与 reduced-motion 行为一致 |
|
||||
|
||||
**已恢复为 stock(此前被本地裁掉的)**:Button 的完整变体/尺寸集(`link`/`xs`/`lg`/`icon-xs|sm|lg`)、`outline` 的 `shadow-xs`、`transition-all`、Badge 的 `ghost`/`link` 变体。它们只是运行时字符串,未使用的工具类不会进 CSS。
|
||||
|
||||
**升级流程**:`npx shadcn@latest add <component> --dry-run` → `--diff` 逐文件看上游改动 → 有本地改动的按上表重新施加(`--overwrite` 后必须重跑下面四条)。落盘后必跑:`pnpm typecheck`、`pnpm vitest run tests/theme.spec.ts tests/ui-shadows.spec.ts tests/ui-foundation.spec.ts tests/ui-bundle.spec.ts`、`pnpm build`(体积与产物断言),以及**镜像页视觉复核**(真实宿主样式表 + 真实组件,见上一节)。
|
||||
|
||||
### 页面重组:用最新 stock 组件,而不是手搓 div(2026-09-20)
|
||||
|
||||
按 shadcn 技能的硬规则把任务页的组成方式整体换成最新 registry 的构件(4 个并行代理按文件分区改,主线程统一验收):
|
||||
|
||||
- **团队任务板**:`Card` 全组合(`CardHeader`/`CardTitle` + `Separator` 分带 + `CardContent` + `CardFooter`),任务行 = `Item asChild`(`ItemMedia` StateDot / `ItemContent`/`ItemTitle`/`ItemActions`),筛选 = `ToggleGroup`(radix radiogroup + roving tabindex),行内菜单 = `DropdownMenuGroup` 包住每个 `DropdownMenuItem`,空态 = `Empty`。
|
||||
- **任务窗口**:`Card` 全组合 + `FieldGroup`/`Field`/`FieldLabel`/`FieldDescription`/`FieldError`;标题空值走 `Field data-invalid` + `Input aria-invalid`(不新增 i18n key);负责人 = `ToggleGroup`(**default 变体**:实测 `outline` 变体的 hover 与 pressed 同色,选中态不可辨);删除 armed 用 `Button variant="destructive"`,冲突提示用 `FieldError(role=alert)`。
|
||||
- **浮窗**:两张 portal 卡同样 `Card` 全组合(`CardTitle` 放身份、`CardDescription` 放种类、`CardAction` 放状态 Badge、`CardFooter` 放跳转),行 = `Item`(可点击行 `asChild` 真按钮)。
|
||||
- **抽屉/页头**:行 = `Item`(终止按钮在 `ItemActions`),分隔全用 `Separator`,加载 = `Spinner`,目录失败横幅 = `Item variant="outline"`,空态 = `Empty`。
|
||||
- **图/树**:节点卡配方 `rounded-lg border bg-card p-2.5 shadow-xs`(不再重复声明 stock `Card` 已有的墨色),控制条全部 stock `Button variant="outline" size="sm|icon"`,`z-[6]` → `z-10`;树行的条件类名改走 `cn()`。
|
||||
|
||||
**本轮在真实浏览器里抓到的两个"无 preflight"陷阱**(都已修,且在测试/文档里留痕):
|
||||
|
||||
1. **stock `Empty` 只有 `border-dashed` 没有宽度** → 没有 preflight 时露出 UA 的 `3px medium` 虚线框,整页像套了个粗虚线相框;`Empty` 上加 `border-0` 修掉(截图证实)。
|
||||
2. **`<Spinner size={12} />` 类型合法但静默失效**:刷新后的 Spinner 变成 `React.ComponentProps<"span">`,`size` 是合法 HTML 属性 → typecheck 全绿而图标按默认 `size-4` 渲染。改用 `className="size-3"`。**教训:组件 API 变更中"仍然类型合法但语义丢失"的那类最危险,只有看渲染结果才能发现。**
|
||||
|
||||
**已知未修(记录在案)**:抽屉行在 ~420px 以下的窄宽度里会横向溢出(Radix ScrollArea 的 table 视口按 min-content 计算 + 行内 `nowrap` 的 mono 标题),修复需要重新决定 ScrollArea/行的最小宽度策略;宽面板(用户实机)不受影响。
|
||||
|
||||
---
|
||||
|
||||
## 回退:任务页回到插件自有体系(2026-09-21,shadcn 层废弃)
|
||||
## 回退记录与结论(2026-09-21:任务页回到插件自有体系)
|
||||
|
||||
任务页 2026-09-17 换成 shadcn/ui + Tailwind v4 视觉基座,09-20 又按「对齐上游 stock」回调一轮;09-21 判定该基座与本插件的体系不可调和,整体回退。
|
||||
> 本节是 2026-09-17 – 09-21 那次视觉基座尝试的**唯一**记录:本文档曾用 250 余行详述它的依赖版本、Tailwind 接入方式、令牌映射表、vendored 组件清单、体积与真机排障,那套基座已整体回退,正文随之删除,只留「为什么回退」与「回退后的结论」。**本节出现的 shadcn / Tailwind / radix 字样都是对已废弃方案的引用**,不代表本仓库或消费插件的建议做法。
|
||||
|
||||
任务页 2026-09-17 换成 shadcn/ui + Tailwind v4 视觉基座(组件源码 vendoring 进 `src/client/ui/`,样式由工具类产出,颜色经 shadcn 语义令牌桥接到 `--dsw-*`),09-20 又按「对齐上游 stock」回调一轮;09-21 判定该基座与本插件的体系不可调和,整体回退。
|
||||
|
||||
**改动面**:8 个页面文件(`TasksGraph` / `TasksTree` / `TaskWindow` / `TeamBoard` / `JobsDrawer` / `TasksPopovers` / `SubagentView` / `tasks-shared`)以 `12b4716` 的原生实现(CSS Modules + 宿主 `@deepseek-ai/dsh-client-ui-primitives`)为基线重建,`src/client/ui/**`(23 个文件)、`components.json`、`scripts/ui-css.mjs` 与其 `ui:css` 脚本删除;`radix-ui` / `class-variance-authority` / `tailwind-merge` / `tailwindcss` / `@tailwindcss/postcss` / `postcss` 六个依赖下线;`tasks` 懒加载 chunk 与 `CHUNK_NAMES` 的 `tasks` 项一并取消(回到 `terminal` / `editor` / `mermaid` / `locale` 四项)。**回退只换视觉基座:09-17–09-21 期间的行为修复逐条重新落地**(见下「保留的行为修复」)。
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ peer 范围、`dsh.client.inject`、chunk externals 白名单、`SIDEBAR_SERVICE
|
||||
- `pnpm build` → 成功;`ui-bundle` 守卫仍绿(核心包 835.6 KiB、chunk 709.8 KiB、无 preflight/oklch/lucide)。
|
||||
- `pnpm test:mount`(`DSH_CMD="npx -y --package @deepseek-ai/dsh@0.1.6-alpha.2 dsh"`,真实挂载 + 无头 tab 全扫)→ **7/7**;`PERF_SUMMARY mount=480ms longtasks=2/221ms`(预算 ≤8);资源清单里 `/sidebar/bundle/tasks.js` **真实下载**(`decodedBodySize 726905`),懒加载路径在 alpha 线上同样成立。
|
||||
|
||||
> **注(2026-09-21 回退后)**:上面两条引用的 `ui-bundle` 守卫与 `tasks` 懒加载 chunk(`/sidebar/bundle/tasks.js`)都是 shadcn/ui 视觉基座时期的产物,该基座已整体回退(见 [2026-09-14 任务页设计文档](./2026-09-14-tasks-graph-workflow-teams-design.md) 文末「回退:任务页回到插件自有体系」):`src/client/ui/**`、`ui-bundle` spec 与 `tasks` chunk 均已删除,任务页回到核心包 + 原生 CSS Modules。以上数字是当时的实测记录,原样保留。
|
||||
> **注(2026-09-21 回退后)**:上面两条引用的 `ui-bundle` 守卫与 `tasks` 懒加载 chunk(`/sidebar/bundle/tasks.js`)都是已废弃的 shadcn/ui 视觉基座时期的产物,该基座已整体回退(见 [2026-09-14 任务页设计文档](./2026-09-14-tasks-graph-workflow-teams-design.md) 的「回退记录与结论」):`src/client/ui/**`、`ui-bundle` spec 与 `tasks` chunk 均已删除,任务页回到核心包 + 原生 CSS Modules。以上数字是当时的实测记录,原样保留。
|
||||
|
||||
## CI 钉版为什么留在 rc.2(含证伪过程)
|
||||
|
||||
|
||||
+43
-27
@@ -161,25 +161,33 @@ export function JobsDrawer(props: JobsDrawerProps): ReactNode {
|
||||
<Tag tone={jobTone(job)}>{jobStatusLabel(job.status, t)}</Tag>
|
||||
<span className={css.jobsMeta}>{secondary}</span>
|
||||
</Button>
|
||||
{job.status === 'running' && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className={css.jobsKill}
|
||||
data-armed={armed ? 'true' : 'false'}
|
||||
icon={<IconStopFill16 size={11} />}
|
||||
aria-label={armed ? t('jobKillConfirm') : t('jobKill')}
|
||||
title={armed ? t('jobKillConfirm') : t('jobKill')}
|
||||
disabled={killing}
|
||||
onClick={() => {
|
||||
if (armed) void kill(row)
|
||||
else setArmedId(job.id)
|
||||
}}
|
||||
>
|
||||
{armed ? t('jobKillConfirm') : undefined}
|
||||
</Button>
|
||||
)}
|
||||
{killFailed && <span className={css.jobsKillError}>{t('jobKillError')}</span>}
|
||||
{/*
|
||||
The terminate column is reserved by EVERY row (settled ones
|
||||
included): the button lives inside a fixed 28px box, so
|
||||
revealing it on hover/focus or arming the confirm never
|
||||
re-flows the row's text.
|
||||
*/}
|
||||
<span className={css.jobsKillSlot}>
|
||||
{job.status === 'running' && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className={css.jobsKill}
|
||||
data-armed={armed ? 'true' : 'false'}
|
||||
icon={<IconStopFill16 size={11} />}
|
||||
aria-label={armed ? t('jobKillConfirm') : t('jobKill')}
|
||||
title={armed ? t('jobKillConfirm') : t('jobKill')}
|
||||
disabled={killing}
|
||||
onClick={() => {
|
||||
if (armed) void kill(row)
|
||||
else setArmedId(job.id)
|
||||
}}
|
||||
>
|
||||
{armed ? t('jobKillConfirm') : undefined}
|
||||
</Button>
|
||||
)}
|
||||
{killFailed && <span className={css.jobsKillError}>{t('jobKillError')}</span>}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
@@ -308,7 +316,7 @@ export function JobOutputPopoverContent(props: {
|
||||
{typeof state === 'object' && (
|
||||
<>
|
||||
{state.text.length > 0
|
||||
? <pre ref={preRef} className={css.popPre} data-popover-no-drag>{state.text}</pre>
|
||||
? <pre ref={preRef} className={`${css.popPre} ${css.jobPopPre}`} data-popover-no-drag>{state.text}</pre>
|
||||
: state.read
|
||||
? <div className={css.popHint}>{t('jobNoOutput')}</div>
|
||||
: <div className={css.popHint}>{t('jobNotReadYet')}</div>}
|
||||
@@ -316,15 +324,23 @@ export function JobOutputPopoverContent(props: {
|
||||
</>
|
||||
)}
|
||||
<div className={css.jobPopActions} data-popover-no-drag>
|
||||
<Switch
|
||||
checked={follow}
|
||||
onChange={setFollow}
|
||||
label={t('jobFollowTail')}
|
||||
disabled={!live}
|
||||
/>
|
||||
{/*
|
||||
The host Switch draws a bare track, so its wording rides beside it —
|
||||
the same `jobFollowTail` copy the switch already carries as its
|
||||
accessible name.
|
||||
*/}
|
||||
<span className={css.jobPopFollow}>
|
||||
<Switch
|
||||
checked={follow}
|
||||
onChange={setFollow}
|
||||
label={t('jobFollowTail')}
|
||||
disabled={!live}
|
||||
/>
|
||||
<span className={css.jobPopFollowLabel}>{t('jobFollowTail')}</span>
|
||||
</span>
|
||||
{live && (
|
||||
<Button
|
||||
variant={armed ? 'primary' : 'outline'}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className={armed ? css.jobPopKillArmed : undefined}
|
||||
icon={<IconStopFill16 size={11} />}
|
||||
|
||||
@@ -9,115 +9,80 @@
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* The page header keeps the native header rhythm — the 12px strong title the
|
||||
other tabs use — plus a mono count, and the hairline underline that closes
|
||||
the toolbar off from the canvas (the plugin's divider token — see
|
||||
changes.module.css `.gitSection`). */
|
||||
/* The page header wears the plugin's own page-header rhythm (sidebar.module.css
|
||||
`.explorerHeader` / `.gitDiffTabHeader`): one control tall (28px) with the
|
||||
standard 12px gutter, the 1px l1 rule closing the toolbar off from the canvas
|
||||
(changes.module.css `.gitSection`), and a title/subject/meta hierarchy —
|
||||
the page name reads first, the session it belongs to follows, the tree
|
||||
readout closes the row as mono micro type. */
|
||||
.subagentHeader {
|
||||
flex: none;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 10px 10px 9px 12px;
|
||||
height: 36px;
|
||||
padding: 0 8px 0 12px;
|
||||
border-bottom: 1px solid var(--dsw-alias-border-l1);
|
||||
}
|
||||
|
||||
.subagentTitle {
|
||||
/* The page name + its session title share one baseline, so the 12px title and
|
||||
the 11px dimmed subject read as one line of text rather than two boxes. The
|
||||
heading clips (its own box only — the subject ellipsizes first), so a panel
|
||||
narrower than the page name cannot push the separator into the count. */
|
||||
.subagentHeading {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.subagentTitle {
|
||||
flex: none;
|
||||
font: var(--dsw-font-xxs-strong-12);
|
||||
color: var(--dsw-alias-label-primary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* The session the tree is rooted at: context, not the page name — it yields
|
||||
first when the header runs out of room. */
|
||||
.subagentSubject {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font: var(--dsw-font-xxs-12);
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* The descendant count badge ("3 · 1 运行中") beside the title. */
|
||||
/* The separator rides the subject's own ink, not the host's `label-dimmed`
|
||||
(which host.css uses for `::placeholder` only): at 1.26:1 the dot vanished
|
||||
and the title read as two adjacent strings, while the OTHER separator on the
|
||||
same row (inside `.subagentCount`) is `label-secondary`. */
|
||||
.subagentSep {
|
||||
flex: none;
|
||||
font: var(--dsw-font-xxs-12);
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
}
|
||||
|
||||
/* The descendant count readout ("3 个子代理 · 1 运行中"): mono micro type with
|
||||
tabular figures, so the ticking numbers never shift the row it closes. */
|
||||
.subagentCount {
|
||||
flex: none;
|
||||
font-family: var(--ds-font-family-code);
|
||||
font-family: var(--ds-font-family-code, monospace);
|
||||
font-size: 10px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
color: var(--dsw-alias-label-secondary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* The header's refresh control is the host ghost Button (28px tall, hover fill
|
||||
from `--dsw-alias-interactive-bg-hover`); the class only keeps it from being
|
||||
squeezed and recenters it against the baseline-aligned title row. */
|
||||
squeezed by a long session title. */
|
||||
.subagentRefresh {
|
||||
flex: none;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.subagentRow:hover {
|
||||
background: var(--dsw-alias-interactive-bg-hover);
|
||||
}
|
||||
|
||||
/* Keyboard focus (mirror of the official catalog row): a visible fill only
|
||||
when focused via keyboard; the selected state below still wins on top. */
|
||||
.subagentRow:focus-visible {
|
||||
background: var(--dsw-alias-interactive-bg-hover);
|
||||
}
|
||||
|
||||
/* The currently-open session, highlighted in place (mirror of the workspace
|
||||
`.sessionRow.selected` — declared after the hover/focus rules so it wins). */
|
||||
.subagentRowActive,
|
||||
.subagentRowActive:hover,
|
||||
.subagentRowActive:focus-visible {
|
||||
background: var(--dsw-alias-interactive-bg-active);
|
||||
}
|
||||
|
||||
.subagentRowDisabled:hover {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Loading placeholders are disabled but keep the default cursor (official
|
||||
`.loadingRow` distinction from `.disabled`). */
|
||||
|
||||
/* The state dot aligns to the first text line (official catalog detail). */
|
||||
.subagentDot {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.subagentLabel,
|
||||
|
||||
/* ── Live lines (running cards only) ──────────────────────────────────── */
|
||||
|
||||
/* ── Tree connector lines (official catalog recipe) ────────────────────── */
|
||||
|
||||
.subagentChildren::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: -26px;
|
||||
height: 26px;
|
||||
border-left: 1px solid var(--dsw-alias-border-l2);
|
||||
}
|
||||
|
||||
.subagentChildren[aria-busy='true']::before {
|
||||
content: none;
|
||||
}
|
||||
|
||||
.subagentChildren > .subagentNode::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: -4px;
|
||||
border-left: 1px solid var(--dsw-alias-border-l2);
|
||||
}
|
||||
|
||||
.subagentChildren > .subagentNode:last-child::before {
|
||||
bottom: auto;
|
||||
height: 17px;
|
||||
}
|
||||
|
||||
.subagentChildren > .subagentNode > .subagentRow::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: -4px;
|
||||
width: 14px;
|
||||
border-top: 1px solid var(--dsw-alias-border-l2);
|
||||
}
|
||||
|
||||
.subagentEmpty {
|
||||
@@ -130,9 +95,13 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* One rung above `.subagentEmpty`, sized one step down — the same ink the
|
||||
plugin's other empty panes use (`.explorerEmpty`, `.gitPlaceholder`). The
|
||||
host's `label-dimmed` is its `::placeholder` ink; a whole sentence in it
|
||||
measured 1.26:1 and was unreadable. */
|
||||
.subagentEmptyHint {
|
||||
font: var(--dsw-font-xxxs-11);
|
||||
color: var(--dsw-alias-label-dimmed);
|
||||
color: var(--dsw-alias-label-tertiary);
|
||||
}
|
||||
|
||||
.subagentError {
|
||||
@@ -151,57 +120,7 @@
|
||||
flex: none;
|
||||
}
|
||||
|
||||
/* ── Background-job section (below the topology tree) ────────────────── */
|
||||
|
||||
/* One job row; the whole row lights up on hover, the expandable target
|
||||
stays transparent (the kill button rides on the row's right edge). */
|
||||
|
||||
.jobsRow:hover {
|
||||
background: var(--dsw-alias-interactive-bg-hover);
|
||||
}
|
||||
|
||||
/* The row whose output is shown in the bottom dock. */
|
||||
.jobsRowSelected,
|
||||
.jobsRowSelected:hover {
|
||||
background: var(--dsw-alias-interactive-bg-active);
|
||||
}
|
||||
|
||||
.jobsRowMain:focus-visible {
|
||||
background: var(--dsw-alias-interactive-bg-hover);
|
||||
}
|
||||
|
||||
/* The command line: a kind badge followed by the command itself in the code
|
||||
face, like the terminal's live lines. */
|
||||
|
||||
.jobsKill:hover {
|
||||
background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent);
|
||||
color: var(--dsw-alias-state-error-primary);
|
||||
}
|
||||
|
||||
/* The armed (first-click) state: a filled confirm chip instead of the icon. */
|
||||
.jobsKillArmed,
|
||||
.jobsKillArmed:hover {
|
||||
width: auto;
|
||||
height: 20px;
|
||||
padding: 0 8px;
|
||||
background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent);
|
||||
color: var(--dsw-alias-state-error-primary);
|
||||
font: var(--dsw-font-xxxs-strong-11);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.jobsKill:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* ── The shared output dock (bottom of the page, sticky like a terminal) ── */
|
||||
|
||||
/* Direct child of the scrolling body, so it docks at the scrollport's bottom
|
||||
edge while the job list scrolls above it; a solid background keeps the
|
||||
tree from showing through. */
|
||||
|
||||
.jobsPaneClose:hover {
|
||||
background: var(--dsw-alias-interactive-bg-hover);
|
||||
}
|
||||
/* The background-job drawer (bar, rows, output popover) is styled entirely in
|
||||
tasks-graph.module.css — its `.jobs*` rules used to live here as dead copies
|
||||
of the pre-drawer in-page section and were pruned. */
|
||||
|
||||
|
||||
@@ -418,17 +418,27 @@ export function SubagentView(props: {
|
||||
return (
|
||||
<div className={legacy.subagent} style={{ position: 'relative' }}>
|
||||
<div className={legacy.subagentHeader}>
|
||||
<span className={legacy.subagentTitle}>
|
||||
{t('subagent')}
|
||||
{rootSummary?.displayTitle !== undefined && rootSummary.displayTitle !== ''
|
||||
? ` · ${rootSummary.displayTitle}`
|
||||
: ''}
|
||||
<span className={legacy.subagentHeading}>
|
||||
<span className={legacy.subagentTitle}>{t('subagent')}</span>
|
||||
{rootSummary?.displayTitle !== undefined && rootSummary.displayTitle !== '' && (
|
||||
<>
|
||||
<span className={legacy.subagentSep} aria-hidden="true">·</span>
|
||||
{/*
|
||||
The session the tree is rooted at: the header's subject, not the
|
||||
page name. It yields first when the row runs out of room, and
|
||||
carries the full title as a tooltip so a clipped one stays readable.
|
||||
*/}
|
||||
<span className={legacy.subagentSubject} title={rootSummary.displayTitle}>
|
||||
{rootSummary.displayTitle}
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</span>
|
||||
{countLabel !== undefined && <span className={legacy.subagentCount}>{countLabel}</span>}
|
||||
{/*
|
||||
The refresh control is the host ghost Button (28px) and carries the
|
||||
plugin's control chrome; the module class only recenters it on the
|
||||
baseline-aligned header row. Plain `title` rather than the host
|
||||
plugin's control chrome; the module class only keeps it from being
|
||||
squeezed by a long session title. Plain `title` rather than the host
|
||||
Tooltip: the Tooltip anchors by ref and the host Button forwards none.
|
||||
*/}
|
||||
<Button
|
||||
|
||||
+13
-24
@@ -15,8 +15,9 @@
|
||||
* and the shared `MarkdownText` renderer with the plugin's copy labels.
|
||||
*/
|
||||
import { useEffect, useId, useRef, useState, type ReactNode } from 'react'
|
||||
import clsx from 'clsx'
|
||||
import {
|
||||
Button, IconCheckOutline14, IconCloseOutline16, IconEditOutline16, IconPlusOutline16,
|
||||
Button, IconCheckOutline14, IconCloseOutline16, IconEditOutline16,
|
||||
IconRefreshOutline14, IconTrashOutline16, Input, MarkdownText, Pill, StateDot, Tag,
|
||||
} from '@deepseek-ai/dsh-client-ui-primitives'
|
||||
import type { SidebarTeamMemberView, SidebarTeamTaskView } from '../context-types.ts'
|
||||
@@ -74,6 +75,7 @@ function OwnerPicker(props: {
|
||||
return (
|
||||
<div className={css.taskOwnerRow} role="group" aria-label={t('teamTaskOwner')}>
|
||||
<Pill
|
||||
className={clsx(css.taskOwnerPill, props.owner === undefined && css.taskOwnerPillActive)}
|
||||
active={props.owner === undefined}
|
||||
disabled={props.disabled}
|
||||
onClick={() => { props.onPick('') }}
|
||||
@@ -83,6 +85,7 @@ function OwnerPicker(props: {
|
||||
{props.members.map(member => (
|
||||
<Pill
|
||||
key={member.id}
|
||||
className={clsx(css.taskOwnerPill, props.owner === member.name && css.taskOwnerPillActive)}
|
||||
active={props.owner === member.name}
|
||||
disabled={props.disabled}
|
||||
onClick={() => { props.onPick(member.name) }}
|
||||
@@ -117,11 +120,11 @@ function TaskViewBody(props: {
|
||||
</div>
|
||||
<div className={css.jobPopMeta}>
|
||||
<span className={css.popKey}>{t('teamTaskOwner')}</span>
|
||||
<span>{task.ownerName ?? t('teamTaskUnowned')}</span>
|
||||
<span className={css.jobPopValue}>{task.ownerName ?? t('teamTaskUnowned')}</span>
|
||||
{task.blockedBy.length > 0 && (
|
||||
<>
|
||||
<span className={css.popKey}>{t('teamTaskBlockedBy')}</span>
|
||||
<span>{task.blockedBy.join(' · ')}</span>
|
||||
<span className={css.jobPopValue}>{task.blockedBy.join(' · ')}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
@@ -170,6 +173,7 @@ function TaskEditBody(props: {
|
||||
<label className={css.taskField}>
|
||||
<span className={css.taskLabel}>{t('teamTaskSubject')}</span>
|
||||
<Input
|
||||
className={css.taskInput}
|
||||
value={props.subject}
|
||||
placeholder={t('teamTaskSubjectPlaceholder')}
|
||||
aria-label={t('teamTaskSubject')}
|
||||
@@ -375,10 +379,13 @@ export function TaskWindow(props: TaskWindowProps): ReactNode {
|
||||
>
|
||||
{t('teamTaskEdit')}
|
||||
</Button>
|
||||
{/* One primary per card: the affirmative state change (完成 /
|
||||
重新打开) is it, so 编辑 stays a plain outline and 删除 keeps
|
||||
the danger ink beside it. */}
|
||||
{task.status === 'completed'
|
||||
? (
|
||||
<Button
|
||||
variant="outline"
|
||||
variant="primary"
|
||||
size="sm"
|
||||
icon={<IconRefreshOutline14 size={12} />}
|
||||
disabled={busy}
|
||||
@@ -391,7 +398,7 @@ export function TaskWindow(props: TaskWindowProps): ReactNode {
|
||||
)
|
||||
: (
|
||||
<Button
|
||||
variant="outline"
|
||||
variant="primary"
|
||||
size="sm"
|
||||
icon={<IconCheckOutline14 size={12} />}
|
||||
disabled={busy}
|
||||
@@ -405,7 +412,7 @@ export function TaskWindow(props: TaskWindowProps): ReactNode {
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className={armedDelete ? css.jobPopKillArmed : undefined}
|
||||
className={clsx(css.taskDanger, armedDelete && css.taskDangerArmed)}
|
||||
icon={<IconTrashOutline16 size={12} />}
|
||||
disabled={busy}
|
||||
onClick={() => {
|
||||
@@ -437,21 +444,3 @@ export function TaskPopover(props: TaskWindowProps & { anchor: HTMLElement | nul
|
||||
</AnchoredPopover>
|
||||
)
|
||||
}
|
||||
|
||||
/** The create affordance every surface shares. */
|
||||
export function TaskCreateButton(props: {
|
||||
disabled?: boolean
|
||||
onClick(anchor: HTMLElement): void
|
||||
}): ReactNode {
|
||||
return (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
icon={<IconPlusOutline16 size={13} />}
|
||||
disabled={props.disabled}
|
||||
onClick={(event) => { props.onClick(event.currentTarget) }}
|
||||
>
|
||||
{t('teamTaskCreate')}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
+17
-14
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
* The workflow-graph mode of the Tasks page (the approved Variant-D canvas):
|
||||
* layered agent/workflow nodes over bezier edges on a dotted grid, drag-pan
|
||||
* from the BACKGROUND only (never from a node — the mockup's rule; capturing
|
||||
* pointers on the container is what silently swallowed node clicks), wheel
|
||||
* zoom to the cursor, dashed phase frames, fold aggregate nodes, and the
|
||||
* bottom-right horizontal control cluster (view toggle / zoom out / level /
|
||||
* zoom in / fit) that stays reachable in BOTH modes.
|
||||
* The workflow-graph mode of the Tasks page: layered agent / workflow nodes
|
||||
* over bezier edges on a dotted grid, drag-pan from the BACKGROUND only
|
||||
* (never from a node — capturing pointers on the container retargets the
|
||||
* derived click and silently swallows node clicks), wheel zoom to the cursor,
|
||||
* dashed phase frames, fold aggregate nodes, and the bottom-right horizontal
|
||||
* control cluster (view toggle / fold / zoom out / level / zoom in / fit)
|
||||
* that stays reachable in BOTH modes.
|
||||
*
|
||||
* Fitting: the canvas auto-fits while the reader has not touched the view,
|
||||
* re-running on container resize and layout growth (the sidebar mounts
|
||||
@@ -13,8 +13,9 @@
|
||||
* on both axes and scaling UP to {@link FIT_MAX_SCALE} so a small tree fills
|
||||
* the narrow panel instead of hugging the top-left corner.
|
||||
*
|
||||
* Cards: the page sheet's node recipe with a TWO-line clamped title (the 68px
|
||||
* card reserve in tasks-graph-layout.ts is sized for that second line) and the
|
||||
* Cards: the node card recipe of tasks-graph.module.css with a TWO-line
|
||||
* clamped title (the card reserve in tasks-graph-layout.ts is sized for that
|
||||
* second line, plus one row per live / task line the card renders) and the
|
||||
* full name in the `title` attribute. While the root catalog hydrates, an
|
||||
* empty canvas shows the same hint as the tree (`loading`).
|
||||
*/
|
||||
@@ -57,11 +58,12 @@ const FIT_MAX_SCALE = 1.15
|
||||
const CLICK_TOLERANCE_PX = 4
|
||||
|
||||
/**
|
||||
* Card line 1 of an agent / run node: the page sheet's node title with the
|
||||
* Card line 1 of an agent / run node: the canvas node title with the
|
||||
* truncation swapped for a TWO-line clamp — a single ellipsized line left too
|
||||
* few CJK characters to tell two siblings apart, and `GRAPH_NODE_H` in
|
||||
* tasks-graph-layout.ts reserves the card height for that second line. The
|
||||
* untruncated name stays in the `title` attribute.
|
||||
* few CJK characters to tell two siblings apart, and `nodeHeight` in
|
||||
* tasks-graph-layout.ts reserves the card height for that second line (plus
|
||||
* one row per live / task line below it). The untruncated name stays in the
|
||||
* `title` attribute.
|
||||
*/
|
||||
const NODE_TITLE = canvasCss.nodeTitle
|
||||
/** The fold aggregate's title: the same clamp on the receding plain ink. */
|
||||
@@ -95,7 +97,8 @@ export interface TasksGraphProps {
|
||||
loading?: boolean
|
||||
}
|
||||
|
||||
/** The shared view-mode toggle (glyph + label, per the mockup). */
|
||||
/** The shared view-mode toggle (glyph + label) both modes render in their
|
||||
* bottom-right control cluster. */
|
||||
export function ViewModeToggle(props: {
|
||||
mode: 'graph' | 'tree'
|
||||
onModeChange(mode: 'graph' | 'tree'): void
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
/**
|
||||
* The anchored-popover CONTENTS of the Tasks page (geometry and dismissal
|
||||
* live in AnchoredPopover): the agent node detail with a transcript jump and
|
||||
* the workflow run detail with clickable member rows. Both follow the mockup
|
||||
* grammar — a letter-spaced uppercase head, a dt/dd key/value grid, and one
|
||||
* full-width jump action.
|
||||
* the workflow run detail with clickable member rows. Both share one grammar:
|
||||
* a letter-spaced uppercase head, a dt/dd key/value grid, a titled well and
|
||||
* one full-width jump action.
|
||||
*
|
||||
* The two cards are ONE skeleton: the same head band, the same [glyph][title]
|
||||
* title row (the card's own host glyph, never a typed character), the same
|
||||
* inset list well of 28px rows, and one l1 hairline around whatever closes the
|
||||
* card. The only intended difference is where a group header sits: a single
|
||||
* list keeps its label fixed above the well, while a multi-phase run scrolls
|
||||
* each phase label with its own rows.
|
||||
*
|
||||
* Every control is a host primitive (`Button` / `StateDot` / `Tag`) — a row
|
||||
* that opens something IS a `<button>`, so it is keyboard reachable — and the
|
||||
@@ -23,7 +30,7 @@ import { Button, IconRightUpOutline14, StateDot, Tag } from '@deepseek-ai/dsh-cl
|
||||
import type { SidebarSubagentAddress } from '../context-types.ts'
|
||||
import type { TasksAgentNode, TasksWorkflowNode } from './tasks-model.ts'
|
||||
import {
|
||||
flatten, nodeDotState, taskDotState, taskStatusKey, workflowStatusKey,
|
||||
AgentGlyph, WorkflowGlyph, flatten, nodeDotState, taskDotState, taskStatusKey, workflowStatusKey,
|
||||
} from './tasks-shared.tsx'
|
||||
import { t, type CopyKey } from './locales.ts'
|
||||
import css from './tasks-graph.module.css'
|
||||
@@ -53,6 +60,16 @@ function PopRow(props: { label: string; mono?: boolean; children: ReactNode }):
|
||||
)
|
||||
}
|
||||
|
||||
/** The title row both popovers open with: the card's host glyph, then the name. */
|
||||
function PopTitleRow(props: { glyph: ReactNode; title: string }): ReactNode {
|
||||
return (
|
||||
<div className={css.popTitleRow}>
|
||||
<span className={css.popGlyph} aria-hidden="true">{props.glyph}</span>
|
||||
<span className={css.popTitle} title={props.title}>{props.title}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/** The agent node detail popover. */
|
||||
export function AgentNodePopover(props: {
|
||||
node: TasksAgentNode
|
||||
@@ -70,7 +87,7 @@ export function AgentNodePopover(props: {
|
||||
<div className={css.popHead}>
|
||||
<span>{t('tasksNodeDetail')}</span>
|
||||
</div>
|
||||
<span className={css.popTitle} title={node.label}>{node.label}</span>
|
||||
<PopTitleRow glyph={<AgentGlyph node={node} />} title={node.label} />
|
||||
<PopRows>
|
||||
<PopRow label={t('tasksNodeState')}>
|
||||
<StateDot state={nodeDotState(node.state)} size={6} /> {t(stateKey(node.state))}
|
||||
@@ -154,7 +171,7 @@ export function WorkflowNodePopover(props: {
|
||||
<div className={css.popHead}>
|
||||
<span>{t('workflowRun')}</span>
|
||||
</div>
|
||||
<span className={css.popTitle} title={run.name}>▶ {run.name}</span>
|
||||
<PopTitleRow glyph={<WorkflowGlyph />} title={run.name} />
|
||||
<PopRows>
|
||||
<PopRow label={t('tasksNodeState')}>{t(workflowStatusKey(run.status))}</PopRow>
|
||||
</PopRows>
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
* `[data-tasks-row]` focus order, ArrowUp / ArrowDown / Home / End focus moves,
|
||||
* Enter / Space activation, and the global fold aggregate (a fold row toggles
|
||||
* the whole page's fold state).
|
||||
*
|
||||
* Readability: rows sit on the page's 32px rhythm (a 2px accent bar marks the
|
||||
* current session, hover is the native fill, settled rows recede), and every
|
||||
* line that can be ellipsised carries its full text as `title` — the label, the
|
||||
* workflow name and the fold previews.
|
||||
*/
|
||||
import { useCallback, useMemo, useRef, type KeyboardEvent, type ReactNode } from 'react'
|
||||
import clsx from 'clsx'
|
||||
@@ -87,7 +92,8 @@ export function TasksTree(props: TasksTreeProps): ReactNode {
|
||||
}
|
||||
}
|
||||
|
||||
/** One row plus its nested children (connector line per the mockup). */
|
||||
/** One row plus its nested children (the connector line is drawn by
|
||||
* `.treeKids` in tasks-graph.module.css). */
|
||||
const renderNode = (node: TasksNode, depth: number): ReactNode => {
|
||||
const children = childrenOf.get(node.id) ?? []
|
||||
const row = node.kind === 'fold'
|
||||
@@ -111,7 +117,9 @@ export function TasksTree(props: TasksTreeProps): ReactNode {
|
||||
{t(folded ? 'tasksFoldExpand' : 'tasksFoldCollapse')}
|
||||
</span>
|
||||
</span>
|
||||
<span className={css.treeMeta}>{foldPreviews(node.previews)}</span>
|
||||
<span className={css.treeMeta} title={foldPreviews(node.previews)}>
|
||||
{foldPreviews(node.previews)}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
@@ -131,10 +139,10 @@ export function TasksTree(props: TasksTreeProps): ReactNode {
|
||||
activateOnKey(event, () => { onWorkflowInfo(node, event.currentTarget as HTMLElement) })
|
||||
}}
|
||||
>
|
||||
<StateDot state={node.run.status === 'running' ? 'ongoing' : 'done'} size={6} />
|
||||
<StateDot className={css.treeDot} state={node.run.status === 'running' ? 'ongoing' : 'done'} size={6} />
|
||||
<span className={css.treeGlyph} aria-hidden="true"><WorkflowGlyph /></span>
|
||||
<span className={css.treeContent}>
|
||||
<span className={css.treeTitle}>{node.run.name}</span>
|
||||
<span className={css.treeTitle} title={node.run.name}>{node.run.name}</span>
|
||||
<span className={css.treeMeta}>{workflowMeta(node)}</span>
|
||||
</span>
|
||||
</div>
|
||||
@@ -158,10 +166,10 @@ export function TasksTree(props: TasksTreeProps): ReactNode {
|
||||
activateOnKey(event, () => { onNodeInfo(node, event.currentTarget as HTMLElement) })
|
||||
}}
|
||||
>
|
||||
<StateDot state={nodeDotState(node.state)} size={6} />
|
||||
<StateDot className={css.treeDot} state={nodeDotState(node.state)} size={6} />
|
||||
<span className={css.treeGlyph} aria-hidden="true"><AgentGlyph node={node} /></span>
|
||||
<span className={css.treeContent}>
|
||||
<span className={css.treeTitle}>{node.label}</span>
|
||||
<span className={css.treeTitle} title={node.label}>{node.label}</span>
|
||||
<span className={css.treeMeta}>{agentMeta(node)}</span>
|
||||
{node.state === 'running' && <LiveLine live={node.live} />}
|
||||
<TaskLine tasks={node.tasks} onOpenTask={onOpenTask} />
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
* member row of Pills (also the owner filter), then task rows (subject +
|
||||
* owner + status Tag + ONE overflow Menu).
|
||||
*
|
||||
* Readability: the four blocks (bar / filters / rows / footer) share one 12px
|
||||
* gutter and one 6px vertical beat, divided by the 1px l1 rules the stylesheet
|
||||
* draws; a row sits on the 28px rhythm and every line that can be ellipsised
|
||||
* (subject, owner) carries its full text as `title`.
|
||||
*
|
||||
* Behaviour: a row and EVERY entry of its menu open the shared task window,
|
||||
* which is the ONE surface owning view / edit / create and every CAS mutation
|
||||
* — the menu is that window's affordance list hoisted onto the row, not a
|
||||
@@ -106,16 +111,12 @@ function TeamTaskRow(props: {
|
||||
|
||||
return (
|
||||
// The row is a flex line so the trailing Menu can sit beside the press
|
||||
// target; the stylesheet has no row+trailing-control class of its own.
|
||||
<div
|
||||
ref={rowRef}
|
||||
style={{ display: 'flex', alignItems: 'center', gap: 2 }}
|
||||
>
|
||||
// target (`.teamTaskRow`).
|
||||
<div ref={rowRef} className={css.teamTaskRow}>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className={css.teamTask}
|
||||
style={{ flex: 1, minWidth: 0 }}
|
||||
aria-label={`${t('teamTaskDetail')} ${task.subject}`}
|
||||
title={t('teamTaskDetail')}
|
||||
onClick={(event) => { onOpenTask(task, event.currentTarget) }}
|
||||
@@ -124,9 +125,9 @@ function TeamTaskRow(props: {
|
||||
size={6}
|
||||
state={task.status === 'completed' ? 'done' : task.ready ? 'ongoing' : 'warning'}
|
||||
/>
|
||||
<span className={css.teamTaskSubject}>{task.subject}</span>
|
||||
<span className={css.teamTaskSubject} title={task.subject}>{task.subject}</span>
|
||||
{task.ownerName !== undefined && (
|
||||
<span className={css.teamTaskOwner}>{task.ownerName}</span>
|
||||
<span className={css.teamTaskOwner} title={task.ownerName}>{task.ownerName}</span>
|
||||
)}
|
||||
<Tag tone={taskTone(task)}>
|
||||
{t(task.ready ? taskStatusKey(task.status) : 'teamTaskBlocked')}
|
||||
|
||||
@@ -39,16 +39,6 @@ export const IconDiffOutline16 = ({ size = 16, className }: IconProps) => (
|
||||
</svg>
|
||||
)
|
||||
|
||||
/**
|
||||
* Stop glyph for the background-job kill button: a filled square in the
|
||||
* app's outline scale (16), the universal "halt this work" mark.
|
||||
*/
|
||||
export const IconStopOutline16 = ({ size = 16, className }: IconProps) => (
|
||||
<svg width={size} height={size} className={className} viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="4" y="4" width="8" height="8" rx="1.5" fill="currentColor" stroke="none" />
|
||||
</svg>
|
||||
)
|
||||
|
||||
/** Upload glyph in the app's outline style: an arrow rising into a tray
|
||||
* (the file-manager "upload into the workspace" action). */
|
||||
export const IconUploadOutline16 = ({ size = 16, className }: IconProps) => (
|
||||
|
||||
@@ -79,29 +79,16 @@ export const ar: Record<string, string> = {
|
||||
openWithSettingsRemove: 'إزالة',
|
||||
openWithSettingsInvalidHint: 'لن تظهر المحرّرات التي تفتقر إلى الاسم أو القالب (يلزم أن يحتوي على {path} ويبدأ بـ scheme://) في القائمة',
|
||||
newTab: 'تبويب جديد',
|
||||
openExplorer: 'المستكشف',
|
||||
brokenSymlink: 'رابط رمزي معطوب',
|
||||
openGit: 'لوحة Git',
|
||||
newTerminal: 'طرفية جديدة',
|
||||
terminalLimit: 'تم بلوغ حد الطرفيات (3)',
|
||||
close: 'إغلاق',
|
||||
closeOtherTabs: 'إغلاق التبويبات الأخرى',
|
||||
closeLeftTabs: 'إغلاق التبويبات على اليسار',
|
||||
closeRightTabs: 'إغلاق التبويبات على اليمين',
|
||||
floatDropHint: 'حرّك للفتح في نافذة حرة',
|
||||
dockToSidebar: 'العودة إلى الشريط الجانبي',
|
||||
pinTerminal: 'تثبيت الطرفية',
|
||||
pinAgentTerminal: 'تثبيت طرفية Agent',
|
||||
pinToWorkspace: 'تثبيت إلى مساحة العمل',
|
||||
pinToGlobal: 'تثبيت عام',
|
||||
unpinTerminal: 'إلغاء التثبيت',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'واجهة طرفية',
|
||||
pinnedTerminalKindAgent: 'طرفية Agent',
|
||||
pinnedTerminalScopeWorkspace: 'مثبتة في مساحة العمل',
|
||||
pinnedTerminalScopeGlobal: 'مثبتة عام',
|
||||
pinnedRailLabel: 'الطرفيات المثبتة',
|
||||
closePinnedTerminal: 'إغلاق الطرفية',
|
||||
collapseBottomPanel: 'طي اللوحة السفلية',
|
||||
expandBottomPanel: 'توسيع اللوحة السفلية',
|
||||
terminalError: 'فشل اتصال الطرفية',
|
||||
@@ -133,10 +120,6 @@ export const ar: Record<string, string> = {
|
||||
loading: 'جارٍ التحميل…',
|
||||
error: 'فشل التحميل',
|
||||
retry: 'إعادة المحاولة',
|
||||
splitLeft: 'تقسيم يساراً',
|
||||
splitRight: 'تقسيم يميناً',
|
||||
splitUp: 'تقسيم لأعلى',
|
||||
splitDown: 'تقسيم لأسفل',
|
||||
notRepo: 'هذا الدليل ليس مستودع git',
|
||||
noChanges: 'لا تغييرات',
|
||||
statusTruncated: 'التغييرات كثيرة جدًا؛ يتم عرض أول 2000 إدخال فقط',
|
||||
@@ -146,7 +129,6 @@ export const ar: Record<string, string> = {
|
||||
unstageAll: 'إلغاء إدراج الكل',
|
||||
commitPlaceholder: 'رسالة التثبيت (Ctrl+Enter)',
|
||||
commit: 'تثبيت',
|
||||
commitError: 'فشل التثبيت',
|
||||
branch: 'الفرع',
|
||||
worktree: 'شجرة العمل',
|
||||
checkoutError: 'فشل تبديل الفرع',
|
||||
@@ -170,7 +152,6 @@ export const ar: Record<string, string> = {
|
||||
diffDeleted: 'محذوف',
|
||||
diffRenamed: 'إعادة تسمية',
|
||||
diffExpand: 'إظهار {count} صفوف أخرى',
|
||||
diffCollapse: 'طي',
|
||||
discard: 'تجاهل التغييرات',
|
||||
discardTitle: 'تجاهل التغييرات',
|
||||
discardDesc: 'هذا يتجاهل تغييرات مساحة العمل في "{path}" (غير قابل للاستعادة).',
|
||||
@@ -191,18 +172,14 @@ export const ar: Record<string, string> = {
|
||||
loadMore: 'تحميل المزيد',
|
||||
historyLoadError: 'فشل تحميل المزيد من السجل',
|
||||
produced: 'النواتج',
|
||||
producedOpen: 'فتح في الشريط الجانبي',
|
||||
disconnected: 'انقطع اتصال الطرفية، جارٍ إعادة الاتصال…',
|
||||
exited: 'خرجت عملية الطرفية',
|
||||
noSession: 'اختر محادثة لاستخدام الشريط الجانبي',
|
||||
pluginNotLoaded: 'الإضافة غير محمّلة؛ التبويب غير متاح:',
|
||||
hiddenFiles: 'ملفات مخفية',
|
||||
parent: 'الدليل الأصل',
|
||||
copied: 'تم النسخ',
|
||||
copy: 'نسخ',
|
||||
newFile: 'ملف جديد',
|
||||
openEditor: 'فتح المحرّر',
|
||||
gitDetail: 'عرض تفاصيل التغيير',
|
||||
referenceFile: '@ملف',
|
||||
addToConversation: 'إضافة إلى المحادثة',
|
||||
copyRelative: 'نسخ المسار النسبي',
|
||||
@@ -246,7 +223,6 @@ export const ar: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'تحكّم كامل: حقن CSS مخصّص (يمكن أن يلغي الأنماط المدمجة) وتحديد مسافة إزاحة الشريط العلوي',
|
||||
settingsSchemeDetectedSuffix: 'تم الكشف',
|
||||
settingsCustomCssTitle: 'CSS مخصّص',
|
||||
settingsCustomCssDesc: 'أنماط تُضاف في نهاية الصفحة (المكتوب لاحقاً يكسر التعادل في نفس الأولوية؛ استخدم !important لتلغي المتغيرات المكتوبة بواسطة JS)',
|
||||
settingsCustomCssPlaceholder: '/* مثال: حجز 36px لغلاف له شريط علوي مرسوم ذاتياً */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'فشل الحفظ',
|
||||
settingsConflict: 'تغيّر الإعداد في نافذة أخرى — يُرجى إعادة المحاولة',
|
||||
@@ -269,7 +245,6 @@ export const ar: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'حجم خط الطرفية',
|
||||
settingsFontSizeDesc: 'حجم خط الطرفية بالبكسل (9–32، افتراضي 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'مسار الصدفة',
|
||||
settingsShellDesc: 'الصدفة التي تُطلق لطرفيات الواجهة والنموذج (مسار مطلق أو اسم تنفيذي مجرّد). الفراغ يحافظ على الترتيب القائم: yaml config.shell ← $SHELL / صدفة الدخول / Windows powershell.exe. يسري على الطرفيات المفتوحة لاحقاً',
|
||||
settingsShellPlaceholder: 'مثل /bin/zsh (فارغ = تلقائي)',
|
||||
@@ -311,19 +286,14 @@ export const ar: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'يحظر الموقع عرضه داخل صفحات أخرى (X-Frame-Options / frame-ancestors)، لذا لا يمكن تحميله في الشريط الجانبي. افتحه مباشرة في متصفحك بدلاً من ذلك.',
|
||||
browserEmbedAnyway: 'تحميل على أي حال',
|
||||
subagent: 'المهام',
|
||||
openSubagent: 'المهام',
|
||||
subagentMainAgent: 'الوكيل الرئيسي',
|
||||
subagentEmpty: 'لا وكلاء فرعيون',
|
||||
subagentEmptyDesc: 'الوكلاء الفرعيون المُنتَجون تحت الوكيل الرئيسي سيظهرون هنا',
|
||||
subagentRunning: 'قيد التشغيل',
|
||||
subagentInactive: 'خامل',
|
||||
subagentModeOneShot: 'مرة واحدة',
|
||||
subagentModeContinuable: 'قابل للاستئناف',
|
||||
subagentCount: '{count} وكلاء فرعيون',
|
||||
subagentCountRunning: '{count} وكلاء فرعيون · {running} قيد التشغيل',
|
||||
subagentDiagCorrupt: 'تالف',
|
||||
subagentDiagUnsupported: 'غير مدعوم',
|
||||
subagentDiagUnavailable: 'غير متاح',
|
||||
subagentThinking: 'جارٍ التفكير…',
|
||||
sideChat: 'محادثة جانبية (تجريبية)',
|
||||
sideChatNew: 'خيط جديد',
|
||||
@@ -344,10 +314,7 @@ export const ar: Record<string, string> = {
|
||||
sideChatThink: 'التفكير',
|
||||
sideChatInjection: 'تم حقن السياق',
|
||||
sideChatSend: 'إرسال',
|
||||
sideChatCancel: 'إيقاف',
|
||||
sideChatCancelTitle: 'إلغاء الدور الجاري (يُحتفظ بالعمل في قائمة الانتظار)',
|
||||
sideChatClose: 'إغلاق الخيط',
|
||||
sideChatCloseTitle: 'تحرير وكيل الخيط (يُحتفظ بالسجل)',
|
||||
sideChatError: 'خطأ في المحادثة الجانبية: {message}',
|
||||
sideChatTurnUsage: 'إدخال {input} توكن · إخراج {output} توكن',
|
||||
sideChatBlockCollapse: 'طي',
|
||||
@@ -383,7 +350,6 @@ export const ar: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes}د {seconds}ث',
|
||||
jobDurationHours: '{hours}س {minutes}د',
|
||||
jobViewOutput: 'عرض الإخراج',
|
||||
jobHideOutput: 'إخفاء الإخراج',
|
||||
jobNoOutput: 'لا إخراج بعد',
|
||||
jobNotReadYet: 'في انتظار قراءة النموذج لإخراج هذه المهمة؛ سيظهر الإخراج هنا بمجرد أن يشغّل النموذج job_output',
|
||||
jobOutputTruncated: 'الإخراج مقطوع',
|
||||
@@ -401,7 +367,6 @@ export const ar: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'مخطط عُقد متدرج مع تكبير وتحريك',
|
||||
settingsViewModeTree: 'شجرة',
|
||||
settingsViewModeTreeDesc: 'شجرة كلاسيكية بمسافات بادئة، قابلة للتنقل بلوحة المفاتيح',
|
||||
tasksWorkflowMember: 'عضو سير العمل',
|
||||
tasksFoldCompleted: '✓ {count} مكتمل',
|
||||
tasksFoldExpand: 'توسيع العُقد المكتملة',
|
||||
tasksFoldCollapse: 'طي العُقد المكتملة',
|
||||
@@ -422,7 +387,6 @@ export const ar: Record<string, string> = {
|
||||
tasksStateError: 'خطأ',
|
||||
teamBoard: 'لوحة مهام الفريق',
|
||||
teamChip: 'فريق {members} أعضاء · {tasks} مهام',
|
||||
teamMembers: 'الأعضاء',
|
||||
teamTasksEmpty: 'لا مهام مشتركة بعد',
|
||||
teamTaskCreate: 'مهمة جديدة',
|
||||
teamTaskSubject: 'الموضوع',
|
||||
|
||||
@@ -64,29 +64,16 @@ export const de: Record<string, string> = {
|
||||
openWithSettingsRemove: 'Entfernen',
|
||||
openWithSettingsInvalidHint: 'Editoren ohne Namen oder mit Vorlage ohne {path} / scheme:// erscheinen nicht im Menü',
|
||||
newTab: 'Neuer Tab',
|
||||
openExplorer: 'Explorer',
|
||||
brokenSymlink: 'Defekter Symlink',
|
||||
openGit: 'Git-Panel',
|
||||
newTerminal: 'Neues Terminal',
|
||||
terminalLimit: 'Terminal-Limit erreicht (3)',
|
||||
close: 'Schließen',
|
||||
closeOtherTabs: 'Andere Tabs schließen',
|
||||
closeLeftTabs: 'Tabs links schließen',
|
||||
closeRightTabs: 'Tabs rechts schließen',
|
||||
floatDropHint: 'Loslassen, um in einem freien Fenster zu öffnen',
|
||||
dockToSidebar: 'Zurück zur Seitenleiste',
|
||||
pinTerminal: 'Terminal anheften',
|
||||
pinAgentTerminal: 'Agent-Terminal anheften',
|
||||
pinToWorkspace: 'An Arbeitsbereich anheften',
|
||||
pinToGlobal: 'Global anheften',
|
||||
unpinTerminal: 'Lösen',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'UI-Terminal',
|
||||
pinnedTerminalKindAgent: 'Agent-Terminal',
|
||||
pinnedTerminalScopeWorkspace: 'An Arbeitsbereich angeheftet',
|
||||
pinnedTerminalScopeGlobal: 'Global angeheftet',
|
||||
pinnedRailLabel: 'Angeheftete Terminals',
|
||||
closePinnedTerminal: 'Terminal schließen',
|
||||
collapseBottomPanel: 'Unteres Panel einklappen',
|
||||
expandBottomPanel: 'Unteres Panel ausklappen',
|
||||
terminalError: 'Terminalverbindung fehlgeschlagen',
|
||||
@@ -118,10 +105,6 @@ export const de: Record<string, string> = {
|
||||
loading: 'Wird geladen…',
|
||||
error: 'Laden fehlgeschlagen',
|
||||
retry: 'Erneut versuchen',
|
||||
splitLeft: 'Nach links teilen',
|
||||
splitRight: 'Nach rechts teilen',
|
||||
splitUp: 'Nach oben teilen',
|
||||
splitDown: 'Nach unten teilen',
|
||||
notRepo: 'Dieses Verzeichnis ist kein Git-Repository',
|
||||
noChanges: 'Keine Änderungen',
|
||||
statusTruncated: 'Zu viele Änderungen; nur die ersten 2000 Einträge werden angezeigt',
|
||||
@@ -131,7 +114,6 @@ export const de: Record<string, string> = {
|
||||
unstageAll: 'Alle unstagen',
|
||||
commitPlaceholder: 'Commit-Nachricht (Ctrl+Enter)',
|
||||
commit: 'Committen',
|
||||
commitError: 'Commit fehlgeschlagen',
|
||||
branch: 'Branch',
|
||||
worktree: 'Worktree',
|
||||
checkoutError: 'Branchenwechsel fehlgeschlagen',
|
||||
@@ -155,7 +137,6 @@ export const de: Record<string, string> = {
|
||||
diffDeleted: 'Gelöscht',
|
||||
diffRenamed: 'Umbenannt',
|
||||
diffExpand: '{count} weitere Zeilen ausklappen',
|
||||
diffCollapse: 'Einklappen',
|
||||
discard: 'Änderungen verwerfen',
|
||||
discardTitle: 'Änderungen verwerfen',
|
||||
discardDesc: 'Dadurch werden die Arbeitsbereichsänderungen von „{path}“ verworfen (nicht wiederherstellbar).',
|
||||
@@ -176,18 +157,14 @@ export const de: Record<string, string> = {
|
||||
loadMore: 'Mehr laden',
|
||||
historyLoadError: 'Laden weiterer Verlaufseinträge fehlgeschlagen',
|
||||
produced: 'Erstellt',
|
||||
producedOpen: 'In der Seitenleiste öffnen',
|
||||
disconnected: 'Terminalverbindung getrennt, Verbindung wird wiederhergestellt…',
|
||||
exited: 'Terminalprozess beendet',
|
||||
noSession: 'Wählen Sie eine Sitzung, um die Seitenleiste zu verwenden',
|
||||
pluginNotLoaded: 'Plugin nicht geladen; Tab vorübergehend nicht verfügbar:',
|
||||
hiddenFiles: 'Versteckte Dateien',
|
||||
parent: 'Übergeordnetes Verzeichnis',
|
||||
copied: 'Kopiert',
|
||||
copy: 'Kopieren',
|
||||
newFile: 'Neue Datei',
|
||||
openEditor: 'Editor öffnen',
|
||||
gitDetail: 'Änderungsdetails ansehen',
|
||||
referenceFile: '@Datei',
|
||||
addToConversation: 'Zur Unterhaltung hinzufügen',
|
||||
copyRelative: 'Relativen Pfad kopieren',
|
||||
@@ -231,7 +208,6 @@ export const de: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'Volle Kontrolle: benutzerdefiniertes CSS einspielen (kann eingebaute Stile überschreiben) und den Verschiebungsabstand der Titelleiste festlegen',
|
||||
settingsSchemeDetectedSuffix: 'erkannt',
|
||||
settingsCustomCssTitle: 'Benutzerdefiniertes CSS',
|
||||
settingsCustomCssDesc: 'Am Seitenende angehängte Stile (bei gleicher Priorität gewinnt der spätere; zum Überschreiben von JS-Inline-Variablen ist !important nötig)',
|
||||
settingsCustomCssPlaceholder: '/* z. B. 36px für eine Shell mit selbst gezeichneter Titelleiste reservieren */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'Speichern fehlgeschlagen',
|
||||
settingsConflict: 'Die Einstellung wurde in einem anderen Fenster geändert – bitte erneut versuchen',
|
||||
@@ -254,7 +230,6 @@ export const de: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'Terminal-Schriftgröße',
|
||||
settingsFontSizeDesc: 'Terminal-Schriftgröße in px (9–32, Standard 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Shell-Pfad',
|
||||
settingsShellDesc: 'Shell für UI- und Modell-Terminals (absoluter Pfad oder ausführbarer Name). Leer lassen für die bestehende Reihenfolge: config.shell aus der yaml → $SHELL / Login-Shell / powershell.exe unter Windows. Wirkt für danach geöffnete Terminals',
|
||||
settingsShellPlaceholder: 'z. B. /bin/zsh (leer = automatisch)',
|
||||
@@ -296,19 +271,14 @@ export const de: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'Die Site verbietet die Anzeige in anderen Seiten (X-Frame-Options / frame-ancestors) und kann daher nicht in der Seitenleiste geladen werden. Öffnen Sie sie stattdessen direkt im Browser.',
|
||||
browserEmbedAnyway: 'Trotzdem laden',
|
||||
subagent: 'Aufgaben',
|
||||
openSubagent: 'Aufgaben',
|
||||
subagentMainAgent: 'Hauptagent',
|
||||
subagentEmpty: 'Keine Subagenten',
|
||||
subagentEmptyDesc: 'Subagenten, die unter dem Hauptagenten erzeugt werden, erscheinen hier',
|
||||
subagentRunning: 'Läuft',
|
||||
subagentInactive: 'Inaktiv',
|
||||
subagentModeOneShot: 'Einmalig',
|
||||
subagentModeContinuable: 'Fortsetzbar',
|
||||
subagentCount: '{count} Subagenten',
|
||||
subagentCountRunning: '{count} Subagenten · {running} läuft',
|
||||
subagentDiagCorrupt: 'Beschädigt',
|
||||
subagentDiagUnsupported: 'Nicht unterstützt',
|
||||
subagentDiagUnavailable: 'Nicht verfügbar',
|
||||
subagentThinking: 'Denkt nach…',
|
||||
sideChat: 'Seitenchat (beta)',
|
||||
sideChatNew: 'Neuer Thread',
|
||||
@@ -329,10 +299,7 @@ export const de: Record<string, string> = {
|
||||
sideChatThink: 'Denkvorgang',
|
||||
sideChatInjection: 'Kontext eingespielt',
|
||||
sideChatSend: 'Senden',
|
||||
sideChatCancel: 'Stoppen',
|
||||
sideChatCancelTitle: 'Laufende Runde abbrechen (wartende Nachrichten bleiben erhalten)',
|
||||
sideChatClose: 'Thread schließen',
|
||||
sideChatCloseTitle: 'Den Agenten des Threads freigeben (Verlauf bleibt erhalten)',
|
||||
sideChatError: 'Seitenchat-Fehler: {message}',
|
||||
sideChatTurnUsage: 'Eingabe {input} tok · Ausgabe {output} tok',
|
||||
sideChatBlockCollapse: 'Einklappen',
|
||||
@@ -368,7 +335,6 @@ export const de: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes} m {seconds} s',
|
||||
jobDurationHours: '{hours} h {minutes} m',
|
||||
jobViewOutput: 'Ausgabe ansehen',
|
||||
jobHideOutput: 'Ausgabe ausblenden',
|
||||
jobNoOutput: 'Noch keine Ausgabe',
|
||||
jobNotReadYet: 'Warten, bis das Modell die Ausgabe dieser Aufgabe liest (nach Ausführung von job_output durch das Modell erscheint die Ausgabe hier)',
|
||||
jobOutputTruncated: 'Ausgabe zu lang, gekürzt angezeigt',
|
||||
@@ -386,7 +352,6 @@ export const de: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'Geschichtetes Knotendiagramm mit Zoom und Schwenken',
|
||||
settingsViewModeTree: 'Baum',
|
||||
settingsViewModeTreeDesc: 'Klassischer Einrückungsbaum, per Tastatur navigierbar',
|
||||
tasksWorkflowMember: 'Workflow-Mitglied',
|
||||
tasksFoldCompleted: '✓ {count} abgeschlossen',
|
||||
tasksFoldExpand: 'Abgeschlossene Knoten ausklappen',
|
||||
tasksFoldCollapse: 'Abgeschlossene Knoten einklappen',
|
||||
@@ -407,7 +372,6 @@ export const de: Record<string, string> = {
|
||||
tasksStateError: 'Fehler',
|
||||
teamBoard: 'Team-Aufgabenboard',
|
||||
teamChip: 'Team {members} Mitglieder · {tasks} Aufgaben',
|
||||
teamMembers: 'Mitglieder',
|
||||
teamTasksEmpty: 'Noch keine geteilten Aufgaben',
|
||||
teamTaskCreate: 'Neue Aufgabe',
|
||||
teamTaskSubject: 'Titel',
|
||||
|
||||
@@ -71,29 +71,16 @@ export const fr: Record<string, string> = {
|
||||
openWithSettingsRemove: 'Supprimer',
|
||||
openWithSettingsInvalidHint: 'Les éditeurs sans nom ou sans modèle (contenant {path} et commençant par scheme://) n’apparaissent pas dans le menu',
|
||||
newTab: 'Nouvel onglet',
|
||||
openExplorer: 'Explorateur',
|
||||
brokenSymlink: 'Lien symbolique cassé',
|
||||
openGit: 'Panneau Git',
|
||||
newTerminal: 'Nouveau terminal',
|
||||
terminalLimit: 'Nombre maximal de terminaux atteint (3)',
|
||||
close: 'Fermer',
|
||||
closeOtherTabs: 'Fermer les autres onglets',
|
||||
closeLeftTabs: 'Fermer les onglets à gauche',
|
||||
closeRightTabs: 'Fermer les onglets à droite',
|
||||
floatDropHint: 'Relâchez pour ouvrir dans une fenêtre flottante',
|
||||
dockToSidebar: 'Revenir à la barre latérale',
|
||||
pinTerminal: 'Épingler le terminal',
|
||||
pinAgentTerminal: 'Épingler le terminal Agent',
|
||||
pinToWorkspace: 'Épingler à l\'espace de travail',
|
||||
pinToGlobal: 'Épingler globalement',
|
||||
unpinTerminal: 'Désépingler',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'Terminal UI',
|
||||
pinnedTerminalKindAgent: 'Terminal Agent',
|
||||
pinnedTerminalScopeWorkspace: 'Épinglé à l\'espace de travail',
|
||||
pinnedTerminalScopeGlobal: 'Épinglé globalement',
|
||||
pinnedRailLabel: 'Terminaux épinglés',
|
||||
closePinnedTerminal: 'Fermer le terminal',
|
||||
collapseBottomPanel: 'Réduire le panneau inférieur',
|
||||
expandBottomPanel: 'Déployer le panneau inférieur',
|
||||
terminalError: 'Échec de la connexion au terminal',
|
||||
@@ -125,10 +112,6 @@ export const fr: Record<string, string> = {
|
||||
loading: 'Chargement…',
|
||||
error: 'Échec du chargement',
|
||||
retry: 'Réessayer',
|
||||
splitLeft: 'Diviser à gauche',
|
||||
splitRight: 'Diviser à droite',
|
||||
splitUp: 'Diviser en haut',
|
||||
splitDown: 'Diviser en bas',
|
||||
notRepo: 'Ce répertoire n’est pas un dépôt git',
|
||||
noChanges: 'Aucune modification',
|
||||
statusTruncated: 'Trop de modifications ; seules les 2000 premières entrées sont affichées',
|
||||
@@ -138,7 +121,6 @@ export const fr: Record<string, string> = {
|
||||
unstageAll: 'Tout retirer de la scène',
|
||||
commitPlaceholder: 'Message de commit (Ctrl+Entrée)',
|
||||
commit: 'Valider',
|
||||
commitError: 'Échec du commit',
|
||||
branch: 'Branche',
|
||||
worktree: 'Arborescence de travail',
|
||||
checkoutError: 'Échec du changement de branche',
|
||||
@@ -162,7 +144,6 @@ export const fr: Record<string, string> = {
|
||||
diffDeleted: 'Supprimé',
|
||||
diffRenamed: 'Renommé',
|
||||
diffExpand: 'Déployer les {count} lignes restantes',
|
||||
diffCollapse: 'Réduire',
|
||||
discard: 'Abandonner les modifications',
|
||||
discardTitle: 'Abandonner les modifications',
|
||||
discardDesc: 'Les modifications de l’espace de travail de « {path} » seront abandonnées (irréversible).',
|
||||
@@ -183,18 +164,14 @@ export const fr: Record<string, string> = {
|
||||
loadMore: 'Charger plus',
|
||||
historyLoadError: 'Échec du chargement de davantage d’historique',
|
||||
produced: 'Produits de cette exécution',
|
||||
producedOpen: 'Ouvrir dans la barre latérale',
|
||||
disconnected: 'Connexion du terminal perdue, reconnexion…',
|
||||
exited: 'Le processus du terminal s’est terminé',
|
||||
noSession: 'Sélectionnez une session pour utiliser la barre latérale',
|
||||
pluginNotLoaded: 'Plugin non chargé, onglet indisponible pour le moment :',
|
||||
hiddenFiles: 'Fichiers cachés',
|
||||
parent: 'Répertoire parent',
|
||||
copied: 'Copié',
|
||||
copy: 'Copier',
|
||||
newFile: 'Nouveau fichier',
|
||||
openEditor: 'Ouvrir l’éditeur',
|
||||
gitDetail: 'Voir le détail des modifications',
|
||||
referenceFile: '@fichier',
|
||||
addToConversation: 'Ajouter à la discussion',
|
||||
copyRelative: 'Copier le chemin relatif',
|
||||
@@ -238,7 +215,6 @@ export const fr: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'Entièrement à votre contrôle : injecter du CSS personnalisé (pouvant remplacer les styles intégrés) et définir la distance de décalage de la barre de titre',
|
||||
settingsSchemeDetectedSuffix: 'détecté',
|
||||
settingsCustomCssTitle: 'CSS personnalisé',
|
||||
settingsCustomCssDesc: 'Styles ajoutés à la fin de la page (à priorité égale, le dernier écrit gagne ; utilisez !important pour remplacer les variables en ligne écrites par JS)',
|
||||
settingsCustomCssPlaceholder: '/* ex. : réserver 36px pour une coquille à barre de titre dessinée */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'Échec de l’enregistrement',
|
||||
settingsConflict: 'Les réglages ont été modifiés par une autre fenêtre, veuillez réessayer',
|
||||
@@ -261,7 +237,6 @@ export const fr: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'Taille de police du terminal',
|
||||
settingsFontSizeDesc: 'Taille de police du terminal (9–32, défaut 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Chemin du shell',
|
||||
settingsShellDesc: 'Shell lancé pour les terminaux de l’interface et du modèle (chemin absolu ou nom d’exécutable). Vide = résolution dans l’ordre existant : config.shell du yaml → $SHELL / shell de connexion / powershell.exe sur Windows. S’applique aux terminaux ouverts ensuite',
|
||||
settingsShellPlaceholder: 'ex. /bin/zsh (vide = résolution automatique)',
|
||||
@@ -303,19 +278,14 @@ export const fr: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'Ce site interdit son affichage dans d’autres pages (X-Frame-Options / frame-ancestors) et ne peut donc pas être chargé dans la barre latérale. Vous pouvez l’ouvrir directement dans le navigateur',
|
||||
browserEmbedAnyway: 'Charger quand même',
|
||||
subagent: 'Gestion des tâches',
|
||||
openSubagent: 'Gestion des tâches',
|
||||
subagentMainAgent: 'Agent principal',
|
||||
subagentEmpty: 'Aucun sous-agent pour l’instant',
|
||||
subagentEmptyDesc: 'Les sous-agents dérivés de l’agent principal actuel s’afficheront ici',
|
||||
subagentRunning: 'En cours',
|
||||
subagentInactive: 'Inactif',
|
||||
subagentModeOneShot: 'À usage unique',
|
||||
subagentModeContinuable: 'Reprenable',
|
||||
subagentCount: '{count} sous-agent(s)',
|
||||
subagentCountRunning: '{count} sous-agent(s) · {running} en cours',
|
||||
subagentDiagCorrupt: 'Répertoire corrompu',
|
||||
subagentDiagUnsupported: 'Entrée non prise en charge',
|
||||
subagentDiagUnavailable: 'Indisponible',
|
||||
subagentThinking: 'Réflexion…',
|
||||
sideChat: 'Discussion latérale (bêta)',
|
||||
sideChatNew: 'Nouvelle discussion',
|
||||
@@ -336,10 +306,7 @@ export const fr: Record<string, string> = {
|
||||
sideChatThink: 'Processus de réflexion',
|
||||
sideChatInjection: 'Contexte injecté',
|
||||
sideChatSend: 'Envoyer',
|
||||
sideChatCancel: 'Arrêter',
|
||||
sideChatCancelTitle: 'Interrompre le tour en cours (la file d’attente est conservée)',
|
||||
sideChatClose: 'Fermer le fil',
|
||||
sideChatCloseTitle: 'Libérer l’agent du fil (l’historique est conservé)',
|
||||
sideChatError: 'Erreur de la discussion latérale : {message}',
|
||||
sideChatTurnUsage: 'Entrée {input} tok · Sortie {output} tok',
|
||||
sideChatBlockCollapse: 'Réduire',
|
||||
@@ -375,7 +342,6 @@ export const fr: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes} min {seconds} s',
|
||||
jobDurationHours: '{hours} h {minutes} min',
|
||||
jobViewOutput: 'Voir la sortie',
|
||||
jobHideOutput: 'Réduire la sortie',
|
||||
jobNoOutput: 'Aucune sortie pour l’instant',
|
||||
jobNotReadYet: 'En attente que le modèle lise la sortie de cette tâche (la sortie s’affichera ici une fois que le modèle aura exécuté job_output)',
|
||||
jobOutputTruncated: 'Sortie trop longue, affichage tronqué',
|
||||
@@ -393,7 +359,6 @@ export const fr: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'Graphe de nœuds en couches, avec zoom et panoramique',
|
||||
settingsViewModeTree: 'Arbre',
|
||||
settingsViewModeTreeDesc: 'Arbre à indentation classique, navigable au clavier',
|
||||
tasksWorkflowMember: 'Membre du workflow',
|
||||
tasksFoldCompleted: '✓ {count} terminés',
|
||||
tasksFoldExpand: 'Déplier les nœuds terminés',
|
||||
tasksFoldCollapse: 'Replier les nœuds terminés',
|
||||
@@ -414,7 +379,6 @@ export const fr: Record<string, string> = {
|
||||
tasksStateError: 'Erreur',
|
||||
teamBoard: 'Tableau des tâches d’équipe',
|
||||
teamChip: 'Équipe {members} membres · {tasks} tâches',
|
||||
teamMembers: 'Membres',
|
||||
teamTasksEmpty: 'Aucune tâche partagée pour l’instant',
|
||||
teamTaskCreate: 'Nouvelle tâche',
|
||||
teamTaskSubject: 'Sujet',
|
||||
|
||||
@@ -78,29 +78,16 @@ export const hi: Record<string, string> = {
|
||||
openWithSettingsRemove: 'हटाएं',
|
||||
openWithSettingsInvalidHint: 'नाम या {path} / scheme:// के बिना टेम्पलेट वाले एडिटर मेन्यू में नहीं दिखते',
|
||||
newTab: 'नया टैब',
|
||||
openExplorer: 'एक्सप्लोरर',
|
||||
brokenSymlink: 'टूटा सिमलिंक',
|
||||
openGit: 'Git पैनल',
|
||||
newTerminal: 'नया टर्मिनल',
|
||||
terminalLimit: 'टर्मिनल सीमा पहुँची (3)',
|
||||
close: 'बंद करें',
|
||||
closeOtherTabs: 'अन्य टैब बंद करें',
|
||||
closeLeftTabs: 'बाएँ टैब बंद करें',
|
||||
closeRightTabs: 'दाएँ टैब बंद करें',
|
||||
floatDropHint: 'फ़्री विंडो में खोलने के लिए छोड़ें',
|
||||
dockToSidebar: 'साइडबार पर वापस जाएँ',
|
||||
pinTerminal: 'टर्मिनल पिन करें',
|
||||
pinAgentTerminal: 'Agent टर्मिनल पिन करें',
|
||||
pinToWorkspace: 'वर्कस्पेस पर पिन करें',
|
||||
pinToGlobal: 'वैश्विक रूप से पिन करें',
|
||||
unpinTerminal: 'पिन हटाएँ',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'UI टर्मिनल',
|
||||
pinnedTerminalKindAgent: 'Agent टर्मिनल',
|
||||
pinnedTerminalScopeWorkspace: 'वर्कस्पेस पर पिन किया गया',
|
||||
pinnedTerminalScopeGlobal: 'वैश्विक रूप से पिन किया गया',
|
||||
pinnedRailLabel: 'पिन किए गए टर्मिनल',
|
||||
closePinnedTerminal: 'टर्मिनल बंद करें',
|
||||
collapseBottomPanel: 'निचला पैनल संक्षिप्त करें',
|
||||
expandBottomPanel: 'निचला पैनल विस्तृत करें',
|
||||
terminalError: 'टर्मिनल कनेक्शन विफल',
|
||||
@@ -132,10 +119,6 @@ export const hi: Record<string, string> = {
|
||||
loading: 'लोड हो रहा…',
|
||||
error: 'लोड विफल',
|
||||
retry: 'पुनः प्रयास',
|
||||
splitLeft: 'बाएँ स्प्लिट',
|
||||
splitRight: 'दाएँ स्प्लिट',
|
||||
splitUp: 'ऊपर स्प्लिट',
|
||||
splitDown: 'नीचे स्प्लिट',
|
||||
notRepo: 'यह डायरेक्टरी एक git रिपॉज़िटरी नहीं है',
|
||||
noChanges: 'कोई बदलाव नहीं',
|
||||
statusTruncated: 'बहुत अधिक बदलाव; केवल पहली 2000 प्रविष्टियाँ दिखाई जा रही हैं',
|
||||
@@ -145,7 +128,6 @@ export const hi: Record<string, string> = {
|
||||
unstageAll: 'सभी अनस्टेज करें',
|
||||
commitPlaceholder: 'कमिट संदेश (Ctrl+Enter)',
|
||||
commit: 'कमिट',
|
||||
commitError: 'कमिट विफल',
|
||||
branch: 'ब्रांच',
|
||||
worktree: 'वर्कट्री',
|
||||
checkoutError: 'ब्रांच स्विच विफल',
|
||||
@@ -169,7 +151,6 @@ export const hi: Record<string, string> = {
|
||||
diffDeleted: 'हटाया',
|
||||
diffRenamed: 'नाम बदला',
|
||||
diffExpand: '{count} और पंक्तियाँ विस्तृत करें',
|
||||
diffCollapse: 'संक्षिप्त करें',
|
||||
discard: 'बदलाव त्यागें',
|
||||
discardTitle: 'बदलाव त्यागें',
|
||||
discardDesc: 'यह "{path}" के वर्कट्री बदलाव त्याग देगा (पुनर्प्राप्त नहीं)।',
|
||||
@@ -190,18 +171,14 @@ export const hi: Record<string, string> = {
|
||||
loadMore: 'और लोड करें',
|
||||
historyLoadError: 'और इतिहास लोड विफल',
|
||||
produced: 'उत्पादित',
|
||||
producedOpen: 'साइडबार में खोलें',
|
||||
disconnected: 'टर्मिनल डिस्कनेक्ट हो गया, पुनः कनेक्ट हो रहा…',
|
||||
exited: 'टर्मिनल प्रक्रिया बाहर निकली',
|
||||
noSession: 'साइडबार उपयोग करने के लिए एक वार्तालाप चुनें',
|
||||
pluginNotLoaded: 'प्लगइन लोड नहीं; टैब अनुपलब्ध:',
|
||||
hiddenFiles: 'छिपी फ़ाइलें',
|
||||
parent: 'मूल डायरेक्टरी',
|
||||
copied: 'कॉपी हो गया',
|
||||
copy: 'कॉपी',
|
||||
newFile: 'नई फ़ाइल',
|
||||
openEditor: 'एडिटर खोलें',
|
||||
gitDetail: 'बदलाव विवरण देखें',
|
||||
referenceFile: '@फ़ाइल',
|
||||
addToConversation: 'वार्तालाप में जोड़ें',
|
||||
copyRelative: 'सापेक्ष पथ कॉपी',
|
||||
@@ -245,7 +222,6 @@ export const hi: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'पूर्ण नियंत्रण: कस्टम CSS इंजेक्ट करें (अंतर्निहित शैलियाँ ओवरराइड कर सकते हैं) और टाइटल-बार शिफ्ट दूरी सेट करें',
|
||||
settingsSchemeDetectedSuffix: 'पहचाना गया',
|
||||
settingsCustomCssTitle: 'कस्टम CSS',
|
||||
settingsCustomCssDesc: 'पृष्ठ के अंत में जोड़ी गई शैलियाँ (कैस्केड में बाद में टाई जीतता है; JS-लिखित इनलाइन चर ओवरराइड करने के लिए !important उपयोग करें)',
|
||||
settingsCustomCssPlaceholder: '/* उदा.: कस्टम-तैयार टाइटल बार वाले शेल के लिए 36px आरक्षित करें */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'सहेजना विफल',
|
||||
settingsConflict: 'सेटिंग दूसरी विंडो में बदली — कृपया पुनः प्रयास करें',
|
||||
@@ -268,7 +244,6 @@ export const hi: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'टर्मिनल फ़ॉन्ट आकार',
|
||||
settingsFontSizeDesc: 'टर्मिनल फ़ॉन्ट आकार px में (9–32, डिफ़ॉल्ट 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Shell पथ',
|
||||
settingsShellDesc: 'UI और मॉडल टर्मिनल के लिए शुरू किया गया shell (निरपेक्ष पथ या निष्पादन योग्य नाम)। खाली पुराना क्रम रखता है: yaml config.shell → $SHELL / लॉगिन shell / Windows powershell.exe। बाद में खुले टर्मिनल पर लागू',
|
||||
settingsShellPlaceholder: 'जैसे /bin/zsh (खाली = ऑटो)',
|
||||
@@ -310,19 +285,14 @@ export const hi: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'साइट अन्य पृष्ठों के अंदर प्रदर्शित होने से मना करती है (X-Frame-Options / frame-ancestors), इसलिए साइडबार में लोड नहीं हो सकती। इसे अपने ब्राउज़र में सीधे खोलें।',
|
||||
browserEmbedAnyway: 'फिर भी लोड करें',
|
||||
subagent: 'कार्य',
|
||||
openSubagent: 'कार्य',
|
||||
subagentMainAgent: 'मुख्य एजेंट',
|
||||
subagentEmpty: 'कोई सबएजेंट नहीं',
|
||||
subagentEmptyDesc: 'मुख्य एजेंट के अंतर्गत बने सबएजेंट यहाँ दिखेंगे',
|
||||
subagentRunning: 'चल रहा',
|
||||
subagentInactive: 'निष्क्रिय',
|
||||
subagentModeOneShot: 'एक-बार',
|
||||
subagentModeContinuable: 'जारी रखने योग्य',
|
||||
subagentCount: '{count} सबएजेंट',
|
||||
subagentCountRunning: '{count} सबएजेंट · {running} चल रहे',
|
||||
subagentDiagCorrupt: 'दूषित',
|
||||
subagentDiagUnsupported: 'असमर्थित',
|
||||
subagentDiagUnavailable: 'अनुपलब्ध',
|
||||
subagentThinking: 'सोच रहा…',
|
||||
sideChat: 'साइड चैट (बीटा)',
|
||||
sideChatNew: 'नया थ्रेड',
|
||||
@@ -343,10 +313,7 @@ export const hi: Record<string, string> = {
|
||||
sideChatThink: 'विचार',
|
||||
sideChatInjection: 'संदर्भ इंजेक्ट किया',
|
||||
sideChatSend: 'भेजें',
|
||||
sideChatCancel: 'रोकें',
|
||||
sideChatCancelTitle: 'चल रहे टर्न को रोकें (कतारबद्ध कार्य रखा जाता है)',
|
||||
sideChatClose: 'थ्रेड बंद करें',
|
||||
sideChatCloseTitle: 'थ्रेड का एजेंट रिलीज़ करें (इतिहास रखा जाता है)',
|
||||
sideChatError: 'साइड चैट त्रुटि: {message}',
|
||||
sideChatTurnUsage: 'इनपुट {input} टोकन · आउटपुट {output} टोकन',
|
||||
sideChatBlockCollapse: 'सिकोड़ें',
|
||||
@@ -382,7 +349,6 @@ export const hi: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes}मि {seconds}से',
|
||||
jobDurationHours: '{hours}घं {minutes}मि',
|
||||
jobViewOutput: 'आउटपुट देखें',
|
||||
jobHideOutput: 'आउटपुट छिपाएं',
|
||||
jobNoOutput: 'अभी कोई आउटपुट नहीं',
|
||||
jobNotReadYet: 'मॉडल का इस कार्य का आउटपुट पढ़ने की प्रतीक्षा; मॉडल job_output चलाने पर आउटपुट यहाँ दिखेगा',
|
||||
jobOutputTruncated: 'आउटपुट कटा हुआ',
|
||||
@@ -400,7 +366,6 @@ export const hi: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'स्तरित नोड ग्राफ़, ज़ूम और पैन के साथ',
|
||||
settingsViewModeTree: 'ट्री',
|
||||
settingsViewModeTreeDesc: 'क्लासिक इंडेंटेड ट्री, कीबोर्ड से नेविगेट करने योग्य',
|
||||
tasksWorkflowMember: 'वर्कफ़्लो सदस्य',
|
||||
tasksFoldCompleted: '✓ {count} पूर्ण',
|
||||
tasksFoldExpand: 'पूर्ण नोड्स विस्तारित करें',
|
||||
tasksFoldCollapse: 'पूर्ण नोड्स संकुचित करें',
|
||||
@@ -421,7 +386,6 @@ export const hi: Record<string, string> = {
|
||||
tasksStateError: 'त्रुटि',
|
||||
teamBoard: 'टीम कार्य बोर्ड',
|
||||
teamChip: 'टीम {members} सदस्य · {tasks} कार्य',
|
||||
teamMembers: 'सदस्य',
|
||||
teamTasksEmpty: 'अभी कोई साझा कार्य नहीं',
|
||||
teamTaskCreate: 'नया कार्य',
|
||||
teamTaskSubject: 'विषय',
|
||||
|
||||
@@ -76,29 +76,16 @@ export const id: Record<string, string> = {
|
||||
openWithSettingsRemove: 'Hapus',
|
||||
openWithSettingsInvalidHint: 'Editor dengan nama hilang atau template tanpa {path} / scheme:// tidak ditampilkan di menu',
|
||||
newTab: 'Tab baru',
|
||||
openExplorer: 'Explorer',
|
||||
brokenSymlink: 'Symlink rusak',
|
||||
openGit: 'Panel Git',
|
||||
newTerminal: 'Terminal baru',
|
||||
terminalLimit: 'Batas terminal tercapai (3)',
|
||||
close: 'Tutup',
|
||||
closeOtherTabs: 'Tutup Tab Lain',
|
||||
closeLeftTabs: 'Tutup Tab di Kiri',
|
||||
closeRightTabs: 'Tutup Tab di Kanan',
|
||||
floatDropHint: 'Lepaskan untuk membuka di jendela bebas',
|
||||
dockToSidebar: 'Kembali ke bilah samping',
|
||||
pinTerminal: 'Sematkan Terminal',
|
||||
pinAgentTerminal: 'Sematkan Terminal Agent',
|
||||
pinToWorkspace: 'Sematkan ke Workspace',
|
||||
pinToGlobal: 'Sematkan Global',
|
||||
unpinTerminal: 'Lepas Sematan',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'Terminal UI',
|
||||
pinnedTerminalKindAgent: 'Terminal Agent',
|
||||
pinnedTerminalScopeWorkspace: 'Disematkan ke workspace',
|
||||
pinnedTerminalScopeGlobal: 'Disematkan global',
|
||||
pinnedRailLabel: 'Terminal Tersemat',
|
||||
closePinnedTerminal: 'Tutup Terminal',
|
||||
collapseBottomPanel: 'Lipat panel bawah',
|
||||
expandBottomPanel: 'Bentangkan panel bawah',
|
||||
terminalError: 'Koneksi terminal gagal',
|
||||
@@ -130,10 +117,6 @@ export const id: Record<string, string> = {
|
||||
loading: 'Memuat…',
|
||||
error: 'Gagal memuat',
|
||||
retry: 'Coba lagi',
|
||||
splitLeft: 'Bagi ke kiri',
|
||||
splitRight: 'Bagi ke kanan',
|
||||
splitUp: 'Bagi ke atas',
|
||||
splitDown: 'Bagi ke bawah',
|
||||
notRepo: 'Direktori ini bukan repositori git',
|
||||
noChanges: 'Tidak ada perubahan',
|
||||
statusTruncated: 'Terlalu banyak perubahan; hanya 2000 entri pertama yang ditampilkan',
|
||||
@@ -143,7 +126,6 @@ export const id: Record<string, string> = {
|
||||
unstageAll: 'Unstage semua',
|
||||
commitPlaceholder: 'Pesan commit (Ctrl+Enter)',
|
||||
commit: 'Commit',
|
||||
commitError: 'Commit gagal',
|
||||
branch: 'Branch',
|
||||
worktree: 'Worktree',
|
||||
checkoutError: 'Beralih branch gagal',
|
||||
@@ -167,7 +149,6 @@ export const id: Record<string, string> = {
|
||||
diffDeleted: 'Dihapus',
|
||||
diffRenamed: 'Diubah nama',
|
||||
diffExpand: 'Bentangkan {count} baris lagi',
|
||||
diffCollapse: 'Lipat',
|
||||
discard: 'Buang perubahan',
|
||||
discardTitle: 'Buang perubahan',
|
||||
discardDesc: 'Ini membuang perubahan worktree "{path}" (tidak dapat dipulihkan).',
|
||||
@@ -188,18 +169,14 @@ export const id: Record<string, string> = {
|
||||
loadMore: 'Muat lebih banyak',
|
||||
historyLoadError: 'Gagal memuat lebih banyak riwayat',
|
||||
produced: 'Dihasilkan',
|
||||
producedOpen: 'Buka di sidebar',
|
||||
disconnected: 'Terminal terputus, menyambung ulang…',
|
||||
exited: 'Proses terminal keluar',
|
||||
noSession: 'Pilih obrolan untuk menggunakan sidebar',
|
||||
pluginNotLoaded: 'Plugin tidak dimuat; tab tidak tersedia untuk sementara:',
|
||||
hiddenFiles: 'Berkas tersembunyi',
|
||||
parent: 'Direktori induk',
|
||||
copied: 'Tersalin',
|
||||
copy: 'Salin',
|
||||
newFile: 'Berkas baru',
|
||||
openEditor: 'Buka editor',
|
||||
gitDetail: 'Lihat detail perubahan',
|
||||
referenceFile: '@berkas',
|
||||
addToConversation: 'Tambahkan ke obrolan',
|
||||
copyRelative: 'Salin path relatif',
|
||||
@@ -243,7 +220,6 @@ export const id: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'Kendali penuh: injeksikan CSS kustom (dapat menimpa style bawaan) dan atur jarak geser title-bar',
|
||||
settingsSchemeDetectedSuffix: 'terdeteksi',
|
||||
settingsCustomCssTitle: 'CSS kustom',
|
||||
settingsCustomCssDesc: 'Style yang ditambahkan di akhir halaman (yang ditulis kemudian menang pada seri; gunakan !important untuk menimpa variabel inline yang ditulis JS)',
|
||||
settingsCustomCssPlaceholder: '/* mis. sediakan 36px untuk shell dengan title-bar yang digambar sendiri */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'Gagal menyimpan',
|
||||
settingsConflict: 'Pengaturan diubah di jendela lain — silakan coba lagi',
|
||||
@@ -266,7 +242,6 @@ export const id: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'Ukuran font terminal',
|
||||
settingsFontSizeDesc: 'Ukuran font terminal dalam px (9–32, default 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Path shell',
|
||||
settingsShellDesc: 'Shell yang dibangkitkan untuk terminal UI dan model (path absolut atau executable polos). Kosong mempertahankan urutan lama: config.shell yaml → $SHELL / login shell / powershell.exe Windows. Berlaku untuk terminal yang dibuka setelahnya',
|
||||
settingsShellPlaceholder: 'mis. /bin/zsh (kosong = auto)',
|
||||
@@ -308,19 +283,14 @@ export const id: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'Situs melarang ditampilkan di dalam halaman lain (X-Frame-Options / frame-ancestors), sehingga tidak dapat dimuat di sidebar. Buka langsung di browser Anda.',
|
||||
browserEmbedAnyway: 'Tetap muat',
|
||||
subagent: 'Tasks',
|
||||
openSubagent: 'Tasks',
|
||||
subagentMainAgent: 'Agen utama',
|
||||
subagentEmpty: 'Tidak ada subagen',
|
||||
subagentEmptyDesc: 'Subagen yang dibangkitkan di bawah agen utama akan muncul di sini',
|
||||
subagentRunning: 'Berjalan',
|
||||
subagentInactive: 'Menganggur',
|
||||
subagentModeOneShot: 'Sekali pakai',
|
||||
subagentModeContinuable: 'Dapat dilanjutkan',
|
||||
subagentCount: '{count} subagen',
|
||||
subagentCountRunning: '{count} subagen · {running} berjalan',
|
||||
subagentDiagCorrupt: 'Rusak',
|
||||
subagentDiagUnsupported: 'Tidak didukung',
|
||||
subagentDiagUnavailable: 'Tidak tersedia',
|
||||
subagentThinking: 'Berpikir…',
|
||||
sideChat: 'Side Chat (beta)',
|
||||
sideChatNew: 'Thread baru',
|
||||
@@ -341,10 +311,7 @@ export const id: Record<string, string> = {
|
||||
sideChatThink: 'Berpikir',
|
||||
sideChatInjection: 'Konteks disuntik',
|
||||
sideChatSend: 'Kirim',
|
||||
sideChatCancel: 'Hentikan',
|
||||
sideChatCancelTitle: 'Batalkan giliran yang berjalan (pekerjaan antrean dipertahankan)',
|
||||
sideChatClose: 'Tutup thread',
|
||||
sideChatCloseTitle: 'Lepaskan agen thread (riwayat dipertahankan)',
|
||||
sideChatError: 'Kesalahan Side Chat: {message}',
|
||||
sideChatTurnUsage: 'Input {input} tok · Output {output} tok',
|
||||
sideChatBlockCollapse: 'Lipat',
|
||||
@@ -380,7 +347,6 @@ export const id: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes}m {seconds}d',
|
||||
jobDurationHours: '{hours}j {minutes}m',
|
||||
jobViewOutput: 'Lihat keluaran',
|
||||
jobHideOutput: 'Sembunyikan keluaran',
|
||||
jobNoOutput: 'Belum ada keluaran',
|
||||
jobNotReadYet: 'Menunggu model membaca tugas ini; keluarannya muncul di sini setelah model menjalankan job_output',
|
||||
jobOutputTruncated: 'Keluaran dipotong',
|
||||
@@ -398,7 +364,6 @@ export const id: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'Graf node berlapis dengan zoom dan pan',
|
||||
settingsViewModeTree: 'Pohon',
|
||||
settingsViewModeTreeDesc: 'Pohon indentasi klasik, dapat dinavigasi dengan keyboard',
|
||||
tasksWorkflowMember: 'Anggota alur kerja',
|
||||
tasksFoldCompleted: '✓ {count} selesai',
|
||||
tasksFoldExpand: 'Perluas node yang selesai',
|
||||
tasksFoldCollapse: 'Lipat node yang selesai',
|
||||
@@ -419,7 +384,6 @@ export const id: Record<string, string> = {
|
||||
tasksStateError: 'Error',
|
||||
teamBoard: 'Papan tugas tim',
|
||||
teamChip: 'Tim {members} anggota · {tasks} tugas',
|
||||
teamMembers: 'Anggota',
|
||||
teamTasksEmpty: 'Belum ada tugas bersama',
|
||||
teamTaskCreate: 'Tugas baru',
|
||||
teamTaskSubject: 'Judul',
|
||||
|
||||
@@ -69,29 +69,16 @@ export const it: Record<string, string> = {
|
||||
openWithSettingsRemove: 'Rimuovi',
|
||||
openWithSettingsInvalidHint: 'Gli editor con nome mancante o modello senza {path} / scheme:// non vengono mostrati nel menu',
|
||||
newTab: 'Nuova scheda',
|
||||
openExplorer: 'Esplora risorse',
|
||||
brokenSymlink: 'Collegamento simbolico interrotto',
|
||||
openGit: 'Pannello Git',
|
||||
newTerminal: 'Nuovo terminale',
|
||||
terminalLimit: 'Numero massimo di terminali raggiunto (3)',
|
||||
close: 'Chiudi',
|
||||
closeOtherTabs: 'Chiudi le altre schede',
|
||||
closeLeftTabs: 'Chiudi le schede a sinistra',
|
||||
closeRightTabs: 'Chiudi le schede a destra',
|
||||
floatDropHint: 'Rilascia per aprire in una finestra libera',
|
||||
dockToSidebar: 'Torna alla barra laterale',
|
||||
pinTerminal: 'Blocca Terminale',
|
||||
pinAgentTerminal: 'Blocca Terminale Agent',
|
||||
pinToWorkspace: 'Blocca in Workspace',
|
||||
pinToGlobal: 'Blocca Globalmente',
|
||||
unpinTerminal: 'Sblocca',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'Terminale UI',
|
||||
pinnedTerminalKindAgent: 'Terminale Agent',
|
||||
pinnedTerminalScopeWorkspace: 'Bloccato in workspace',
|
||||
pinnedTerminalScopeGlobal: 'Bloccato globalmente',
|
||||
pinnedRailLabel: 'Terminali Bloccati',
|
||||
closePinnedTerminal: 'Chiudi Terminale',
|
||||
collapseBottomPanel: 'Comprimi pannello inferiore',
|
||||
expandBottomPanel: 'Espandi pannello inferiore',
|
||||
terminalError: 'Connessione del terminale non riuscita',
|
||||
@@ -123,10 +110,6 @@ export const it: Record<string, string> = {
|
||||
loading: 'Caricamento…',
|
||||
error: 'Caricamento non riuscito',
|
||||
retry: 'Riprova',
|
||||
splitLeft: 'Dividi a sinistra',
|
||||
splitRight: 'Dividi a destra',
|
||||
splitUp: 'Dividi in alto',
|
||||
splitDown: 'Dividi in basso',
|
||||
notRepo: 'Questa directory non è un repository git',
|
||||
noChanges: 'Nessuna modifica',
|
||||
statusTruncated: 'Troppe modifiche; vengono mostrate solo le prime 2000 voci',
|
||||
@@ -136,7 +119,6 @@ export const it: Record<string, string> = {
|
||||
unstageAll: 'Rimuovi tutto dalla preparazione',
|
||||
commitPlaceholder: 'Messaggio di commit (Ctrl+Enter)',
|
||||
commit: 'Commit',
|
||||
commitError: 'Commit non riuscito',
|
||||
branch: 'Ramo',
|
||||
worktree: 'Albero di lavoro',
|
||||
checkoutError: 'Cambio di ramo non riuscito',
|
||||
@@ -160,7 +142,6 @@ export const it: Record<string, string> = {
|
||||
diffDeleted: 'Eliminato',
|
||||
diffRenamed: 'Rinominato',
|
||||
diffExpand: 'Espandi altre {count} righe',
|
||||
diffCollapse: 'Comprimi',
|
||||
discard: 'Annulla modifiche',
|
||||
discardTitle: 'Annulla modifiche',
|
||||
discardDesc: 'Questo annulla le modifiche della copia di lavoro di «{path}» (non recuperabile).',
|
||||
@@ -181,18 +162,14 @@ export const it: Record<string, string> = {
|
||||
loadMore: 'Carica altro',
|
||||
historyLoadError: 'Caricamento di altra cronologia non riuscito',
|
||||
produced: 'Prodotti',
|
||||
producedOpen: 'Apri nella barra laterale',
|
||||
disconnected: 'Terminale disconnesso, riconnessione…',
|
||||
exited: 'Il processo del terminale è terminato',
|
||||
noSession: 'Selezioni una conversazione per usare la barra laterale',
|
||||
pluginNotLoaded: 'Plugin non caricato; scheda non disponibile:',
|
||||
hiddenFiles: 'File nascosti',
|
||||
parent: 'Directory superiore',
|
||||
copied: 'Copiato',
|
||||
copy: 'Copia',
|
||||
newFile: 'Nuovo file',
|
||||
openEditor: 'Apri editor',
|
||||
gitDetail: 'Vedi i dettagli delle modifiche',
|
||||
referenceFile: '@file',
|
||||
addToConversation: 'Aggiungi alla conversazione',
|
||||
copyRelative: 'Copia percorso relativo',
|
||||
@@ -236,7 +213,6 @@ export const it: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'Controllo totale: inietti CSS personalizzato (può sovrascrivere gli stili integrati) e imposti la distanza di scorrimento della barra del titolo',
|
||||
settingsSchemeDetectedSuffix: 'rilevato',
|
||||
settingsCustomCssTitle: 'CSS personalizzato',
|
||||
settingsCustomCssDesc: 'Stili accodati alla fine della pagina (in caso di parità vince chi è dopo; usi !important per sovrascrivere le variabili inline scritte da JS)',
|
||||
settingsCustomCssPlaceholder: '/* es. riserva 36px per una shell con barra del titolo disegnata a mano */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'Salvataggio non riuscito',
|
||||
settingsConflict: 'L’impostazione è stata modificata in un’altra finestra — riprovi',
|
||||
@@ -259,7 +235,6 @@ export const it: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'Dimensione del carattere del terminale',
|
||||
settingsFontSizeDesc: 'Dimensione del carattere del terminale in px (9–32, predefinito 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Percorso della shell',
|
||||
settingsShellDesc: 'Shell avviata per i terminali dell’interfaccia e del modello (percorso assoluto o nome eseguibile). Vuoto mantiene l’ordine preesistente: config.shell di yaml → $SHELL / shell di login / powershell.exe di Windows. Si applica ai terminali aperti successivamente',
|
||||
settingsShellPlaceholder: 'es. /bin/zsh (vuoto = automatico)',
|
||||
@@ -301,19 +276,14 @@ export const it: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'Il sito vieta di essere mostrato all’interno di altre pagine (X-Frame-Options / frame-ancestors), per cui non può essere caricato nella barra laterale. Lo apra direttamente nel browser.',
|
||||
browserEmbedAnyway: 'Carica comunque',
|
||||
subagent: 'Attività',
|
||||
openSubagent: 'Attività',
|
||||
subagentMainAgent: 'Agente principale',
|
||||
subagentEmpty: 'Nessun sottoagente',
|
||||
subagentEmptyDesc: 'I sottoagenti generati dall’agente principale compariranno qui',
|
||||
subagentRunning: 'In esecuzione',
|
||||
subagentInactive: 'Inattivo',
|
||||
subagentModeOneShot: 'Monouso',
|
||||
subagentModeContinuable: 'Proseguibile',
|
||||
subagentCount: '{count} sottoagenti',
|
||||
subagentCountRunning: '{count} sottoagenti · {running} in esecuzione',
|
||||
subagentDiagCorrupt: 'Danneggiato',
|
||||
subagentDiagUnsupported: 'Non supportato',
|
||||
subagentDiagUnavailable: 'Non disponibile',
|
||||
subagentThinking: 'In pensiero…',
|
||||
sideChat: 'Chat laterale (beta)',
|
||||
sideChatNew: 'Nuova conversazione',
|
||||
@@ -334,10 +304,7 @@ export const it: Record<string, string> = {
|
||||
sideChatThink: 'Pensiero',
|
||||
sideChatInjection: 'Contesto iniettato',
|
||||
sideChatSend: 'Invia',
|
||||
sideChatCancel: 'Arresta',
|
||||
sideChatCancelTitle: 'Interrompe il turno in corso (il lavoro in coda è conservato)',
|
||||
sideChatClose: 'Chiudi conversazione',
|
||||
sideChatCloseTitle: 'Rilascia l’agente della conversazione (la cronologia è conservata)',
|
||||
sideChatError: 'Errore della chat laterale: {message}',
|
||||
sideChatTurnUsage: 'Input {input} tok · Output {output} tok',
|
||||
sideChatBlockCollapse: 'Comprimi',
|
||||
@@ -373,7 +340,6 @@ export const it: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes}min {seconds}s',
|
||||
jobDurationHours: '{hours}h {minutes}min',
|
||||
jobViewOutput: 'Vedi output',
|
||||
jobHideOutput: 'Nascondi output',
|
||||
jobNoOutput: 'Nessun output per ora',
|
||||
jobNotReadYet: 'In attesa che il modello legga questa attività; il suo output compare qui quando il modello esegue job_output',
|
||||
jobOutputTruncated: 'Output troncato',
|
||||
@@ -391,7 +357,6 @@ export const it: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'Grafo di nodi a livelli, con zoom e pan',
|
||||
settingsViewModeTree: 'Albero',
|
||||
settingsViewModeTreeDesc: 'Albero a rientri classico, navigabile da tastiera',
|
||||
tasksWorkflowMember: 'Membro del workflow',
|
||||
tasksFoldCompleted: '✓ {count} completati',
|
||||
tasksFoldExpand: 'Espandi i nodi completati',
|
||||
tasksFoldCollapse: 'Comprimi i nodi completati',
|
||||
@@ -412,7 +377,6 @@ export const it: Record<string, string> = {
|
||||
tasksStateError: 'Errore',
|
||||
teamBoard: 'Bacheca delle attività del team',
|
||||
teamChip: 'Team {members} membri · {tasks} attività',
|
||||
teamMembers: 'Membri',
|
||||
teamTasksEmpty: 'Ancora nessuna attività condivisa',
|
||||
teamTaskCreate: 'Nuova attività',
|
||||
teamTaskSubject: 'Titolo',
|
||||
|
||||
@@ -78,29 +78,16 @@ export const ja: Record<string, string> = {
|
||||
openWithSettingsRemove: '削除',
|
||||
openWithSettingsInvalidHint: '名前またはテンプレート({path} を含み scheme:// で始まる必要あり)が未入力の編集者はメニューに表示されません',
|
||||
newTab: '新しいタブ',
|
||||
openExplorer: 'エクスプローラー',
|
||||
brokenSymlink: '無効なシンボリックリンク',
|
||||
openGit: 'Git パネル',
|
||||
newTerminal: '新しいターミナル',
|
||||
terminalLimit: 'ターミナル数が上限に達しました (3)',
|
||||
close: '閉じる',
|
||||
closeOtherTabs: '他のタブを閉じる',
|
||||
closeLeftTabs: '左のタブを閉じる',
|
||||
closeRightTabs: '右のタブを閉じる',
|
||||
floatDropHint: '離すとフリーウィンドウで開きます',
|
||||
dockToSidebar: 'サイドバーへ戻す',
|
||||
pinTerminal: 'ターミナルを固定',
|
||||
pinAgentTerminal: 'Agent ターミナルを固定',
|
||||
pinToWorkspace: 'ワークスペースに固定',
|
||||
pinToGlobal: 'グローバルに固定',
|
||||
unpinTerminal: '固定を解除',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'UI ターミナル',
|
||||
pinnedTerminalKindAgent: 'Agent ターミナル',
|
||||
pinnedTerminalScopeWorkspace: 'ワークスペースに固定',
|
||||
pinnedTerminalScopeGlobal: 'グローバルに固定',
|
||||
pinnedRailLabel: '固定されたターミナル',
|
||||
closePinnedTerminal: 'ターミナルを閉じる',
|
||||
collapseBottomPanel: '下パネルを折りたたむ',
|
||||
expandBottomPanel: '下パネルを展開',
|
||||
terminalError: 'ターミナル接続に失敗',
|
||||
@@ -132,10 +119,6 @@ export const ja: Record<string, string> = {
|
||||
loading: '読み込み中…',
|
||||
error: '読み込みに失敗',
|
||||
retry: '再試行',
|
||||
splitLeft: '左に分割',
|
||||
splitRight: '右に分割',
|
||||
splitUp: '上に分割',
|
||||
splitDown: '下に分割',
|
||||
notRepo: 'このディレクトリは git リポジトリではありません',
|
||||
noChanges: '変更はありません',
|
||||
statusTruncated: '変更が多すぎるため、最初の 2000 件のみ表示しています',
|
||||
@@ -145,7 +128,6 @@ export const ja: Record<string, string> = {
|
||||
unstageAll: 'すべてステージ解除',
|
||||
commitPlaceholder: 'コミットメッセージ (Ctrl+Enter)',
|
||||
commit: 'コミット',
|
||||
commitError: 'コミット失敗',
|
||||
branch: 'ブランチ',
|
||||
worktree: 'ワークツリー',
|
||||
checkoutError: 'ブランチ切り替えに失敗',
|
||||
@@ -169,7 +151,6 @@ export const ja: Record<string, string> = {
|
||||
diffDeleted: '削除',
|
||||
diffRenamed: '名前変更',
|
||||
diffExpand: '残り {count} 行を展開',
|
||||
diffCollapse: '折りたたむ',
|
||||
discard: '変更を破棄',
|
||||
discardTitle: '変更を破棄',
|
||||
discardDesc: '「{path}」のワークツリー変更を破棄します(復元不可)。',
|
||||
@@ -190,18 +171,14 @@ export const ja: Record<string, string> = {
|
||||
loadMore: 'もっと読み込む',
|
||||
historyLoadError: '履歴の追加読み込みに失敗',
|
||||
produced: '今回の産物',
|
||||
producedOpen: 'サイドバーで開く',
|
||||
disconnected: 'ターミナル接続が切れました、再接続中…',
|
||||
exited: 'ターミナルプロセスが終了しました',
|
||||
noSession: 'サイドバーを使うには会話を選択してください',
|
||||
pluginNotLoaded: 'プラグイン未読み込み、タブは一時的に利用不可:',
|
||||
hiddenFiles: '隠しファイル',
|
||||
parent: '上位ディレクトリ',
|
||||
copied: 'コピーしました',
|
||||
copy: 'コピー',
|
||||
newFile: '新規ファイル',
|
||||
openEditor: 'エディターで開く',
|
||||
gitDetail: '変更詳細を表示',
|
||||
referenceFile: '@ファイル',
|
||||
addToConversation: '会話に追加',
|
||||
copyRelative: '相対パスをコピー',
|
||||
@@ -245,7 +222,6 @@ export const ja: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: '完全に制御:カスタム CSS を注入(内置スタイルも上書き可)し、タイトルバーの下移動距離を指定',
|
||||
settingsSchemeDetectedSuffix: '検出済み',
|
||||
settingsCustomCssTitle: 'カスタム CSS',
|
||||
settingsCustomCssDesc: 'ページ末尾に追加されるスタイル(同優先度では後勝ち。JS 起点のインライン変数を上書きするには !important を使用)',
|
||||
settingsCustomCssPlaceholder: '/* 例:自描きタイトルバーのシェルに 36px を予約 */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: '保存に失敗',
|
||||
settingsConflict: '設定が別のウィンドウで変更されました、再試行してください',
|
||||
@@ -268,7 +244,6 @@ export const ja: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'ターミナルフォントサイズ',
|
||||
settingsFontSizeDesc: 'ターミナルのフォントサイズ (px、9–32、デフォルト 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'シェルパス',
|
||||
settingsShellDesc: 'UI とモデルのターミナルが起動するシェル(絶対パス or 実行ファイル名)。空欄時は従来順で解決: yaml の config.shell → $SHELL / ログインシェル / Windows の powershell.exe。以降に開くターミナルに適用',
|
||||
settingsShellPlaceholder: '例: /bin/zsh(空欄で自動解決)',
|
||||
@@ -310,19 +285,14 @@ export const ja: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'このサイトは X-Frame-Options / frame-ancestors で他ページ内での表示を禁止しているため、サイドバー内で読み込めません。ブラウザーで直接開いてください',
|
||||
browserEmbedAnyway: 'それでも読み込む',
|
||||
subagent: 'タスク管理',
|
||||
openSubagent: 'タスク管理',
|
||||
subagentMainAgent: 'メインエージェント',
|
||||
subagentEmpty: 'サブエージェントなし',
|
||||
subagentEmptyDesc: 'メインエージェントが派生したサブエージェントはここに表示されます',
|
||||
subagentRunning: '実行中',
|
||||
subagentInactive: 'アイドル',
|
||||
subagentModeOneShot: 'ワンショット',
|
||||
subagentModeContinuable: '継続可',
|
||||
subagentCount: '{count} 個のサブエージェント',
|
||||
subagentCountRunning: '{count} 個のサブエージェント ・ {running} 個実行中',
|
||||
subagentDiagCorrupt: 'ディレクトリ破損',
|
||||
subagentDiagUnsupported: '未サポートのエントリ',
|
||||
subagentDiagUnavailable: '利用不可',
|
||||
subagentThinking: '思考中…',
|
||||
sideChat: 'サイドチャット(beta)',
|
||||
sideChatNew: '新規スレッド',
|
||||
@@ -343,10 +313,7 @@ export const ja: Record<string, string> = {
|
||||
sideChatThink: '思考プロセス',
|
||||
sideChatInjection: 'コンテキスト注入済み',
|
||||
sideChatSend: '送信',
|
||||
sideChatCancel: '停止',
|
||||
sideChatCancelTitle: '現在のターンを中止(キューは保持)',
|
||||
sideChatClose: 'スレッドを閉じる',
|
||||
sideChatCloseTitle: 'スレッドの agent を解放(履歴は保持)',
|
||||
sideChatError: 'サイド会話エラー:{message}',
|
||||
sideChatTurnUsage: '入力 {input} tok · 出力 {output} tok',
|
||||
sideChatBlockCollapse: '折りたたむ',
|
||||
@@ -382,7 +349,6 @@ export const ja: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes} 分 {seconds} 秒',
|
||||
jobDurationHours: '{hours} 時間 {minutes} 分',
|
||||
jobViewOutput: '出力を表示',
|
||||
jobHideOutput: '出力を隠す',
|
||||
jobNoOutput: 'まだ出力なし',
|
||||
jobNotReadYet: 'モデルがこのタスクの出力を読み取るのを待機中(モデルが job_output を実行すると、出力がここに表示されます)',
|
||||
jobOutputTruncated: '出力が長すぎるため表示を切り詰めました',
|
||||
@@ -400,7 +366,6 @@ export const ja: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: '階層ノードグラフ(ズーム・パン対応)',
|
||||
settingsViewModeTree: 'ツリー',
|
||||
settingsViewModeTreeDesc: '従来のインデントツリー(キーボード操作可)',
|
||||
tasksWorkflowMember: 'ワークフローメンバー',
|
||||
tasksFoldCompleted: '✓ {count} 件完了',
|
||||
tasksFoldExpand: '完了ノードを展開',
|
||||
tasksFoldCollapse: '完了ノードを折りたたむ',
|
||||
@@ -421,7 +386,6 @@ export const ja: Record<string, string> = {
|
||||
tasksStateError: 'エラー',
|
||||
teamBoard: 'チームタスクボード',
|
||||
teamChip: 'チーム {members} 名 · {tasks} タスク',
|
||||
teamMembers: 'メンバー',
|
||||
teamTasksEmpty: '共有タスクはまだありません',
|
||||
teamTaskCreate: 'タスクを作成',
|
||||
teamTaskSubject: '件名',
|
||||
|
||||
@@ -70,29 +70,16 @@ export const ko: Record<string, string> = {
|
||||
openWithSettingsRemove: '삭제',
|
||||
openWithSettingsInvalidHint: '이름이나 템플릿({path} 포함, scheme:// 로 시작해야 함)을 입력하지 않은 편집기는 메뉴에 표시되지 않습니다',
|
||||
newTab: '새 탭',
|
||||
openExplorer: '파일 탐색기',
|
||||
brokenSymlink: '깨진 심볼릭 링크',
|
||||
openGit: 'Git 패널',
|
||||
newTerminal: '새 터미널',
|
||||
terminalLimit: '터미널 개수가 최대치에 도달했습니다 (3)',
|
||||
close: '닫기',
|
||||
closeOtherTabs: '다른 탭 닫기',
|
||||
closeLeftTabs: '왼쪽 탭 닫기',
|
||||
closeRightTabs: '오른쪽 탭 닫기',
|
||||
floatDropHint: '놓으면 자유 창에서 열립니다',
|
||||
dockToSidebar: '사이드바로 돌아가기',
|
||||
pinTerminal: '터미널 고정',
|
||||
pinAgentTerminal: 'Agent 터미널 고정',
|
||||
pinToWorkspace: '워크스페이스에 고정',
|
||||
pinToGlobal: '전역에 고정',
|
||||
unpinTerminal: '고정 해제',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'UI 터미널',
|
||||
pinnedTerminalKindAgent: 'Agent 터미널',
|
||||
pinnedTerminalScopeWorkspace: '워크스페이스에 고정됨',
|
||||
pinnedTerminalScopeGlobal: '전역에 고정됨',
|
||||
pinnedRailLabel: '고정된 터미널',
|
||||
closePinnedTerminal: '터미널 닫기',
|
||||
collapseBottomPanel: '하단 패널 접기',
|
||||
expandBottomPanel: '하단 패널 펼치기',
|
||||
terminalError: '터미널 연결 실패',
|
||||
@@ -124,10 +111,6 @@ export const ko: Record<string, string> = {
|
||||
loading: '불러오는 중…',
|
||||
error: '불러오기 실패',
|
||||
retry: '다시 시도',
|
||||
splitLeft: '왼쪽으로 분할',
|
||||
splitRight: '오른쪽으로 분할',
|
||||
splitUp: '위로 분할',
|
||||
splitDown: '아래로 분할',
|
||||
notRepo: '현재 디렉터리는 git 저장소가 아닙니다',
|
||||
noChanges: '변경 사항 없음',
|
||||
statusTruncated: '변경 사항이 너무 많아 처음 2000개만 표시합니다',
|
||||
@@ -137,7 +120,6 @@ export const ko: Record<string, string> = {
|
||||
unstageAll: '모두 스테이징 해제',
|
||||
commitPlaceholder: '커밋 메시지 (Ctrl+Enter)',
|
||||
commit: '커밋',
|
||||
commitError: '커밋 실패',
|
||||
branch: '브랜치',
|
||||
worktree: '워크트리',
|
||||
checkoutError: '브랜치 전환 실패',
|
||||
@@ -161,7 +143,6 @@ export const ko: Record<string, string> = {
|
||||
diffDeleted: '삭제됨',
|
||||
diffRenamed: '이름 변경됨',
|
||||
diffExpand: '나머지 {count}줄 펼치기',
|
||||
diffCollapse: '접기',
|
||||
discard: '변경 사항 버리기',
|
||||
discardTitle: '변경 사항 버리기',
|
||||
discardDesc: '"{path}"의 작업 공간 수정을 버립니다(복구 불가).',
|
||||
@@ -182,18 +163,14 @@ export const ko: Record<string, string> = {
|
||||
loadMore: '더 불러오기',
|
||||
historyLoadError: '더 많은 기록 불러오기 실패',
|
||||
produced: '이번 산출물',
|
||||
producedOpen: '사이드바에서 열기',
|
||||
disconnected: '터미널 연결이 끊겨 다시 연결하는 중…',
|
||||
exited: '터미널 프로세스가 종료되었습니다',
|
||||
noSession: '사이드바를 사용하려면 대화를 선택하세요',
|
||||
pluginNotLoaded: '플러그인이 로드되지 않아 탭을 지금 사용할 수 없습니다:',
|
||||
hiddenFiles: '숨김 파일',
|
||||
parent: '상위 디렉터리',
|
||||
copied: '복사됨',
|
||||
copy: '복사',
|
||||
newFile: '새 파일',
|
||||
openEditor: '편집기 열기',
|
||||
gitDetail: '변경 사항 세부 정보 보기',
|
||||
referenceFile: '@파일',
|
||||
addToConversation: '대화에 추가',
|
||||
copyRelative: '상대 경로 복사',
|
||||
@@ -237,7 +214,6 @@ export const ko: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: '전적으로 사용자가 제어합니다. 사용자 지정 CSS(내장 스타일 덮어쓰기 가능)를 주입하고 타이틀 바 하강 거리를 지정합니다',
|
||||
settingsSchemeDetectedSuffix: '감지됨',
|
||||
settingsCustomCssTitle: '사용자 지정 CSS',
|
||||
settingsCustomCssDesc: '페이지 끝에 추가되는 스타일(동일 우선순위에서는 나중에 쓴 것이 이깁니다. JS 인라인 변수를 덮으려면 !important를 사용해야 합니다)',
|
||||
settingsCustomCssPlaceholder: '/* 예: 직접 그린 타이틀 바의 셸을 위해 36px 확보 */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: '저장 실패',
|
||||
settingsConflict: '설정이 다른 창에서 수정되었습니다. 다시 시도하세요',
|
||||
@@ -260,7 +236,6 @@ export const ko: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: '터미널 글꼴 크기',
|
||||
settingsFontSizeDesc: '터미널 글꼴 크기(9–32, 기본 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Shell 경로',
|
||||
settingsShellDesc: 'UI와 모델 터미널이 시작하는 shell(절대 경로 또는 실행 파일 이름). 비워두면 기존 순서로 해석합니다: yaml의 config.shell → $SHELL / 로그인 shell / Windows의 powershell.exe. 이후에 여는 터미널부터 적용됩니다',
|
||||
settingsShellPlaceholder: '예: /bin/zsh (비워두면 자동 해석)',
|
||||
@@ -302,19 +277,14 @@ export const ko: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: '이 사이트는 X-Frame-Options / frame-ancestors로 다른 페이지에 표시되는 것을 금지하여 사이드바에서 로드할 수 없습니다. 브라우저에서 직접 열 수 있습니다',
|
||||
browserEmbedAnyway: '그래도 로드',
|
||||
subagent: '작업 관리',
|
||||
openSubagent: '작업 관리',
|
||||
subagentMainAgent: '주 에이전트',
|
||||
subagentEmpty: '서브 에이전트 없음',
|
||||
subagentEmptyDesc: '현재 주 에이전트에서 파생된 서브 에이전트가 여기에 표시됩니다',
|
||||
subagentRunning: '실행 중',
|
||||
subagentInactive: '대기 중',
|
||||
subagentModeOneShot: '일회성',
|
||||
subagentModeContinuable: '이어서 가능',
|
||||
subagentCount: '서브 에이전트 {count}개',
|
||||
subagentCountRunning: '서브 에이전트 {count}개 · {running} 실행 중',
|
||||
subagentDiagCorrupt: '기록 손상',
|
||||
subagentDiagUnsupported: '지원되지 않는 항목',
|
||||
subagentDiagUnavailable: '사용할 수 없음',
|
||||
subagentThinking: '생각하는 중…',
|
||||
sideChat: '사이드 채팅(beta)',
|
||||
sideChatNew: '새 대화',
|
||||
@@ -335,10 +305,7 @@ export const ko: Record<string, string> = {
|
||||
sideChatThink: '생각 과정',
|
||||
sideChatInjection: '컨텍스트 주입됨',
|
||||
sideChatSend: '보내기',
|
||||
sideChatCancel: '중지',
|
||||
sideChatCancelTitle: '현재 턴 중단(대기열 유지)',
|
||||
sideChatClose: '스레드 닫기',
|
||||
sideChatCloseTitle: '스레드의 agent를 해제합니다(기록은 유지)',
|
||||
sideChatError: '사이드 대화 오류: {message}',
|
||||
sideChatTurnUsage: '입력 {input} tok · 출력 {output} tok',
|
||||
sideChatBlockCollapse: '접기',
|
||||
@@ -374,7 +341,6 @@ export const ko: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes}분 {seconds}초',
|
||||
jobDurationHours: '{hours}시간 {minutes}분',
|
||||
jobViewOutput: '출력 보기',
|
||||
jobHideOutput: '출력 접기',
|
||||
jobNoOutput: '출력 없음',
|
||||
jobNotReadYet: '모델이 이 작업의 출력을 읽기를 기다리는 중입니다(모델이 job_output을 실행하면 출력이 여기에 표시됩니다)',
|
||||
jobOutputTruncated: '출력이 너무 길어 잘라서 표시합니다',
|
||||
@@ -392,7 +358,6 @@ export const ko: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: '계층형 노드 그래프, 확대/이동 가능',
|
||||
settingsViewModeTree: '트리',
|
||||
settingsViewModeTreeDesc: '클래식 들여쓰기 트리, 키보드 탐색 지원',
|
||||
tasksWorkflowMember: '워크플로 멤버',
|
||||
tasksFoldCompleted: '✓ {count} 완료됨',
|
||||
tasksFoldExpand: '완료된 노드 펼치기',
|
||||
tasksFoldCollapse: '완료된 노드 접기',
|
||||
@@ -413,7 +378,6 @@ export const ko: Record<string, string> = {
|
||||
tasksStateError: '오류',
|
||||
teamBoard: '팀 작업 보드',
|
||||
teamChip: '팀 멤버 {members}명 · 작업 {tasks}개',
|
||||
teamMembers: '멤버',
|
||||
teamTasksEmpty: '공유 작업이 없습니다',
|
||||
teamTaskCreate: '새 작업',
|
||||
teamTaskSubject: '제목',
|
||||
|
||||
@@ -76,29 +76,16 @@ export const nl: Record<string, string> = {
|
||||
openWithSettingsRemove: 'Verwijderen',
|
||||
openWithSettingsInvalidHint: 'Editors met een ontbrekende naam of een sjabloon zonder {path} / scheme:// worden niet in het menu getoond',
|
||||
newTab: 'Nieuw tabblad',
|
||||
openExplorer: 'Verkenner',
|
||||
brokenSymlink: 'Gebroken symlink',
|
||||
openGit: 'Git-paneel',
|
||||
newTerminal: 'Nieuwe terminal',
|
||||
terminalLimit: 'Terminallimiet bereikt (3)',
|
||||
close: 'Sluiten',
|
||||
closeOtherTabs: 'Andere tabbladen sluiten',
|
||||
closeLeftTabs: 'Tabbladen links sluiten',
|
||||
closeRightTabs: 'Tabbladen rechts sluiten',
|
||||
floatDropHint: 'Loslaten om in een vrij venster te openen',
|
||||
dockToSidebar: 'Terug naar de zijbalk',
|
||||
pinTerminal: 'Terminal vastmaken',
|
||||
pinAgentTerminal: 'Agent-terminal vastmaken',
|
||||
pinToWorkspace: 'Vastmaken aan werkruimte',
|
||||
pinToGlobal: 'Wereldwijd vastmaken',
|
||||
unpinTerminal: 'Losmaken',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'UI-terminal',
|
||||
pinnedTerminalKindAgent: 'Agent-terminal',
|
||||
pinnedTerminalScopeWorkspace: 'Vastgemaakt aan werkruimte',
|
||||
pinnedTerminalScopeGlobal: 'Wereldwijd vastgemaakt',
|
||||
pinnedRailLabel: 'Vastgemaakte terminals',
|
||||
closePinnedTerminal: 'Terminal sluiten',
|
||||
collapseBottomPanel: 'Onderpaneel inklappen',
|
||||
expandBottomPanel: 'Onderpaneel uitklappen',
|
||||
terminalError: 'Terminalverbinding mislukt',
|
||||
@@ -130,10 +117,6 @@ export const nl: Record<string, string> = {
|
||||
loading: 'Laden…',
|
||||
error: 'Laden mislukt',
|
||||
retry: 'Opnieuw proberen',
|
||||
splitLeft: 'Splitsen links',
|
||||
splitRight: 'Splitsen rechts',
|
||||
splitUp: 'Splitsen omhoog',
|
||||
splitDown: 'Splitsen omlaag',
|
||||
notRepo: 'Deze map is geen git-repository',
|
||||
noChanges: 'Geen wijzigingen',
|
||||
statusTruncated: 'Te veel wijzigingen; alleen de eerste 2000 items worden weergegeven',
|
||||
@@ -143,7 +126,6 @@ export const nl: Record<string, string> = {
|
||||
unstageAll: 'Alles unstagen',
|
||||
commitPlaceholder: 'Commitbericht (Ctrl+Enter)',
|
||||
commit: 'Commit',
|
||||
commitError: 'Commit mislukt',
|
||||
branch: 'Branch',
|
||||
worktree: 'Worktree',
|
||||
checkoutError: 'Wisselen van branch mislukt',
|
||||
@@ -167,7 +149,6 @@ export const nl: Record<string, string> = {
|
||||
diffDeleted: 'Verwijderd',
|
||||
diffRenamed: 'Hernoemd',
|
||||
diffExpand: '{count} rijen extra uitklappen',
|
||||
diffCollapse: 'Inklappen',
|
||||
discard: 'Wijzigingen verwijderen',
|
||||
discardTitle: 'Wijzigingen verwijderen',
|
||||
discardDesc: 'Dit verwijdert de worktree-wijzigingen van "{path}" (niet terugdraaibaar).',
|
||||
@@ -188,18 +169,14 @@ export const nl: Record<string, string> = {
|
||||
loadMore: 'Meer laden',
|
||||
historyLoadError: 'Meer geschiedenis laden mislukt',
|
||||
produced: 'Geproduceerd',
|
||||
producedOpen: 'Openen in zijbalk',
|
||||
disconnected: 'Terminalverbinding verbroken, opnieuw verbinden…',
|
||||
exited: 'Terminalproces beëindigd',
|
||||
noSession: 'Selecteer een conversatie om de zijbalk te gebruiken',
|
||||
pluginNotLoaded: 'Plugin niet geladen; tabblad niet beschikbaar:',
|
||||
hiddenFiles: 'Verborgen bestanden',
|
||||
parent: 'Bovenliggende map',
|
||||
copied: 'Gekopieerd',
|
||||
copy: 'Kopiëren',
|
||||
newFile: 'Nieuw bestand',
|
||||
openEditor: 'Editor openen',
|
||||
gitDetail: 'Wijzigingsdetails bekijken',
|
||||
referenceFile: '@bestand',
|
||||
addToConversation: 'Aan conversatie toevoegen',
|
||||
copyRelative: 'Relatief pad kopiëren',
|
||||
@@ -243,7 +220,6 @@ export const nl: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'Volledige controle: aangepaste CSS injecteren (kan ingebouwde stijlen overschrijven) en de verschuivingsafstand van de titelbalk instellen',
|
||||
settingsSchemeDetectedSuffix: 'gedetecteerd',
|
||||
settingsCustomCssTitle: 'Aangepaste CSS',
|
||||
settingsCustomCssDesc: 'Stijlen die aan het einde van de pagina worden toegevoegd (later in de cascade wint bij gelijke prioriteit; gebruik !important om JS-geschreven inline-variabelen te overschrijven)',
|
||||
settingsCustomCssPlaceholder: '/* bijv. reserveer 36px voor een shell met een zelf-getekende titelbalk */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'Opslaan mislukt',
|
||||
settingsConflict: 'De instelling is in een ander venster gewijzigd — probeer het opnieuw',
|
||||
@@ -266,7 +242,6 @@ export const nl: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'Terminallettergrootte',
|
||||
settingsFontSizeDesc: 'Terminallettergrootte in px (9–32, standaard 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Shell-pad',
|
||||
settingsShellDesc: 'Shell die wordt gestart voor UI- en model-terminals (absoluut pad of kale executable). Leeg houden volgt de bestaande volgorde: yaml config.shell → $SHELL / inlog-shell / Windows powershell.exe. Geldt voor terminals die daarna worden geopend',
|
||||
settingsShellPlaceholder: 'bijv. /bin/zsh (leeg = auto)',
|
||||
@@ -308,19 +283,14 @@ export const nl: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'De site verbiedt weergave binnen andere pagina\'s (X-Frame-Options / frame-ancestors), dus kan niet in de zijbalk laden. Open de site direct in uw browser.',
|
||||
browserEmbedAnyway: 'Toch laden',
|
||||
subagent: 'Taken',
|
||||
openSubagent: 'Taken',
|
||||
subagentMainAgent: 'Hoofdagent',
|
||||
subagentEmpty: 'Geen subagents',
|
||||
subagentEmptyDesc: 'Subagents voortgebracht door de hoofdagent verschijnen hier',
|
||||
subagentRunning: 'Actief',
|
||||
subagentInactive: 'Inactief',
|
||||
subagentModeOneShot: 'One-shot',
|
||||
subagentModeContinuable: 'Vervolgbaar',
|
||||
subagentCount: '{count} subagents',
|
||||
subagentCountRunning: '{count} subagents · {running} actief',
|
||||
subagentDiagCorrupt: 'Corrupt',
|
||||
subagentDiagUnsupported: 'Niet ondersteund',
|
||||
subagentDiagUnavailable: 'Niet beschikbaar',
|
||||
subagentThinking: 'Nadenken…',
|
||||
sideChat: 'Side Chat (bèta)',
|
||||
sideChatNew: 'Nieuwe thread',
|
||||
@@ -341,10 +311,7 @@ export const nl: Record<string, string> = {
|
||||
sideChatThink: 'Denken',
|
||||
sideChatInjection: 'Context geïnjecteerd',
|
||||
sideChatSend: 'Versturen',
|
||||
sideChatCancel: 'Stoppen',
|
||||
sideChatCancelTitle: 'De lopende beurt afbreken (wachtrij blijft behouden)',
|
||||
sideChatClose: 'Thread sluiten',
|
||||
sideChatCloseTitle: 'De agent van de thread vrijgeven (geschiedenis blijft behouden)',
|
||||
sideChatError: 'Side Chat-fout: {message}',
|
||||
sideChatTurnUsage: 'Invoer {input} tok · Uitvoer {output} tok',
|
||||
sideChatBlockCollapse: 'Invouwen',
|
||||
@@ -380,7 +347,6 @@ export const nl: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes}m {seconds}s',
|
||||
jobDurationHours: '{hours}u {minutes}m',
|
||||
jobViewOutput: 'Uitvoer bekijken',
|
||||
jobHideOutput: 'Uitvoer verbergen',
|
||||
jobNoOutput: 'Nog geen uitvoer',
|
||||
jobNotReadYet: 'Wachten tot het model deze taak leest; de uitvoer verschijnt hier zodra het model job_output uitvoert',
|
||||
jobOutputTruncated: 'Uitvoer afgekapt',
|
||||
@@ -398,7 +364,6 @@ export const nl: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'Gelaagde knoppengrafiek met in- en uitzoomen en pannen',
|
||||
settingsViewModeTree: 'Boom',
|
||||
settingsViewModeTreeDesc: 'Klassieke inspringboom, navigeerbaar met het toetsenbord',
|
||||
tasksWorkflowMember: 'Workflowlid',
|
||||
tasksFoldCompleted: '✓ {count} voltooid',
|
||||
tasksFoldExpand: 'Voltooide knopen uitklappen',
|
||||
tasksFoldCollapse: 'Voltooide knopen inklappen',
|
||||
@@ -419,7 +384,6 @@ export const nl: Record<string, string> = {
|
||||
tasksStateError: 'Fout',
|
||||
teamBoard: 'Teamtakenbord',
|
||||
teamChip: 'Team {members} leden · {tasks} taken',
|
||||
teamMembers: 'Leden',
|
||||
teamTasksEmpty: 'Nog geen gedeelde taken',
|
||||
teamTaskCreate: 'Nieuwe taak',
|
||||
teamTaskSubject: 'Onderwerp',
|
||||
|
||||
@@ -80,29 +80,16 @@ export const pl: Record<string, string> = {
|
||||
openWithSettingsRemove: 'Usuń',
|
||||
openWithSettingsInvalidHint: 'Edytory z brakującą nazwą lub szablonem bez {path} / scheme:// nie są pokazywane w menu',
|
||||
newTab: 'Nowa karta',
|
||||
openExplorer: 'Eksplorator',
|
||||
brokenSymlink: 'Uszkodzone dowiązanie symboliczne',
|
||||
openGit: 'Panel Git',
|
||||
newTerminal: 'Nowy terminal',
|
||||
terminalLimit: 'Osiągnięto limit terminali (3)',
|
||||
close: 'Zamknij',
|
||||
closeOtherTabs: 'Zamknij inne karty',
|
||||
closeLeftTabs: 'Zamknij karty po lewej',
|
||||
closeRightTabs: 'Zamknij karty po prawej',
|
||||
floatDropHint: 'Puść, aby otworzyć w wolnym oknie',
|
||||
dockToSidebar: 'Wróć do panelu bocznego',
|
||||
pinTerminal: 'Przypnij Terminal',
|
||||
pinAgentTerminal: 'Przypnij Terminal Agent',
|
||||
pinToWorkspace: 'Przypnij do obszaru roboczego',
|
||||
pinToGlobal: 'Przypnij globalnie',
|
||||
unpinTerminal: 'Odepnij',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'Terminal interfejsu',
|
||||
pinnedTerminalKindAgent: 'Terminal Agent',
|
||||
pinnedTerminalScopeWorkspace: 'Przypięty do obszaru roboczego',
|
||||
pinnedTerminalScopeGlobal: 'Przypięty globalnie',
|
||||
pinnedRailLabel: 'Przypięte terminale',
|
||||
closePinnedTerminal: 'Zamknij terminal',
|
||||
collapseBottomPanel: 'Zwiń panel dolny',
|
||||
expandBottomPanel: 'Rozwiń panel dolny',
|
||||
terminalError: 'Połączenie z terminalem nie powiodło się',
|
||||
@@ -134,10 +121,6 @@ export const pl: Record<string, string> = {
|
||||
loading: 'Ładowanie…',
|
||||
error: 'Ładowanie nie powiodło się',
|
||||
retry: 'Ponów',
|
||||
splitLeft: 'Podziel w lewo',
|
||||
splitRight: 'Podziel w prawo',
|
||||
splitUp: 'Podziel w górę',
|
||||
splitDown: 'Podziel w dół',
|
||||
notRepo: 'Ten katalog nie jest repozytorium git',
|
||||
noChanges: 'Brak zmian',
|
||||
statusTruncated: 'Zbyt wiele zmian; pokazywane jest tylko pierwsze 2000 wpisów',
|
||||
@@ -147,7 +130,6 @@ export const pl: Record<string, string> = {
|
||||
unstageAll: 'Usuń wszystko z indeksu',
|
||||
commitPlaceholder: 'Komunikat commitu (Ctrl+Enter)',
|
||||
commit: 'Commit',
|
||||
commitError: 'Commit nie powiódł się',
|
||||
branch: 'Gałąź',
|
||||
worktree: 'Drzewo robocze',
|
||||
checkoutError: 'Przełączenie gałęzi nie powiodło się',
|
||||
@@ -171,7 +153,6 @@ export const pl: Record<string, string> = {
|
||||
diffDeleted: 'Usunięty',
|
||||
diffRenamed: 'Zmieniono nazwę',
|
||||
diffExpand: 'Rozwiń jeszcze {count} wierszy',
|
||||
diffCollapse: 'Zwiń',
|
||||
discard: 'Odrzuć zmiany',
|
||||
discardTitle: 'Odrzuć zmiany',
|
||||
discardDesc: 'To odrzuci zmiany w drzewie roboczym dla „{path}” (nieodwracalne).',
|
||||
@@ -192,18 +173,14 @@ export const pl: Record<string, string> = {
|
||||
loadMore: 'Wczytaj więcej',
|
||||
historyLoadError: 'Ładowanie dalszej historii nie powiodło się',
|
||||
produced: 'Wyprodukowane',
|
||||
producedOpen: 'Otwórz w panelu bocznym',
|
||||
disconnected: 'Terminal odłączony, ponowne łączenie…',
|
||||
exited: 'Proces terminala zakończony',
|
||||
noSession: 'Wybierz rozmowę, aby korzystać z panelu bocznego',
|
||||
pluginNotLoaded: 'Wtyczka niezaładowana; karta chwilowo niedostępna:',
|
||||
hiddenFiles: 'Ukryte pliki',
|
||||
parent: 'Katalog nadrzędny',
|
||||
copied: 'Skopiowano',
|
||||
copy: 'Kopiuj',
|
||||
newFile: 'Nowy plik',
|
||||
openEditor: 'Otwórz edytor',
|
||||
gitDetail: 'Zobacz szczegóły zmian',
|
||||
referenceFile: '@plik',
|
||||
addToConversation: 'Dodaj do rozmowy',
|
||||
copyRelative: 'Kopiuj ścieżkę względną',
|
||||
@@ -247,7 +224,6 @@ export const pl: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'Pełna kontrola: wstrzykuj własne CSS (może nadpisać style wbudowane) i ustawiasz przesunięcie paska tytułu',
|
||||
settingsSchemeDetectedSuffix: 'wykryto',
|
||||
settingsCustomCssTitle: 'Niestandardowe CSS',
|
||||
settingsCustomCssDesc: 'Style dodawane na końcu strony (późniejsze w kaskadzie wygrywa remisy; użyj !important, aby nadpisać zmienne inline zapisane przez JS)',
|
||||
settingsCustomCssPlaceholder: '/* np. zarezerwuj 36px dla powłoki z własnym paskiem tytułu */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'Zapis nie powiódł się',
|
||||
settingsConflict: 'Ustawienie zmienione w innym oknie — spróbuj ponownie',
|
||||
@@ -270,7 +246,6 @@ export const pl: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'Rozmiar czcionki terminala',
|
||||
settingsFontSizeDesc: 'Rozmiar czcionki terminala w px (9–32, domyślnie 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Ścieżka powłoki',
|
||||
settingsShellDesc: 'Powłoka uruchamiana dla terminali UI i modelu (ścieżka bezwzględna lub nazwa pliku). Puste zachowuje dawną kolejność: yaml config.shell → $SHELL / powłoka logowania / Windows powershell.exe. Dotyczy terminali otwieranych potem',
|
||||
settingsShellPlaceholder: 'np. /bin/zsh (puste = auto)',
|
||||
@@ -312,19 +287,14 @@ export const pl: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'Witryna zabrania wyświetlania w innych stronach (X-Frame-Options / frame-ancestors), więc nie może się załadować w panelu bocznym. Otwórz ją bezpośrednio w przeglądarce.',
|
||||
browserEmbedAnyway: 'Załaduj mimo to',
|
||||
subagent: 'Zadania',
|
||||
openSubagent: 'Zadania',
|
||||
subagentMainAgent: 'Agent główny',
|
||||
subagentEmpty: 'Brak podagentów',
|
||||
subagentEmptyDesc: 'Podagenci powołani przez agenta głównego pojawią się tutaj',
|
||||
subagentRunning: 'Działa',
|
||||
subagentInactive: 'Bezczynny',
|
||||
subagentModeOneShot: 'Jednorazowy',
|
||||
subagentModeContinuable: 'Kontynuowalny',
|
||||
subagentCount: '{count} podagentów',
|
||||
subagentCountRunning: '{count} podagentów · {running} działa',
|
||||
subagentDiagCorrupt: 'Uszkodzony',
|
||||
subagentDiagUnsupported: 'Nieobsługiwany',
|
||||
subagentDiagUnavailable: 'Niedostępny',
|
||||
subagentThinking: 'Myśli…',
|
||||
sideChat: 'Czat boczny (beta)',
|
||||
sideChatNew: 'Nowy wątek',
|
||||
@@ -345,10 +315,7 @@ export const pl: Record<string, string> = {
|
||||
sideChatThink: 'Myślenie',
|
||||
sideChatInjection: 'Kontekst wstrzyknięty',
|
||||
sideChatSend: 'Wyślij',
|
||||
sideChatCancel: 'Zatrzymaj',
|
||||
sideChatCancelTitle: 'Przerwij bieżącą turę (kolejka jest zachowana)',
|
||||
sideChatClose: 'Zamknij wątek',
|
||||
sideChatCloseTitle: 'Zwolnij agenta wątku (historia jest zachowana)',
|
||||
sideChatError: 'Błąd czatu bocznego: {message}',
|
||||
sideChatTurnUsage: 'Wejście {input} tok · Wyjście {output} tok',
|
||||
sideChatBlockCollapse: 'Zwiń',
|
||||
@@ -384,7 +351,6 @@ export const pl: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes}m {seconds}s',
|
||||
jobDurationHours: '{hours}g {minutes}m',
|
||||
jobViewOutput: 'Pokaż wyjście',
|
||||
jobHideOutput: 'Ukryj wyjście',
|
||||
jobNoOutput: 'Brak wyjścia',
|
||||
jobNotReadYet: 'Oczekiwanie, aż model odczyta to zadanie; wyjście pojawi się tutaj, gdy model uruchomi job_output',
|
||||
jobOutputTruncated: 'Wyjście skrócone',
|
||||
@@ -402,7 +368,6 @@ export const pl: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'Warstwowy graf węzłów ze zoomowaniem i przesuwaniem',
|
||||
settingsViewModeTree: 'Drzewo',
|
||||
settingsViewModeTreeDesc: 'Klasyczne drzewo wcięć, nawigowalne z klawiatury',
|
||||
tasksWorkflowMember: 'Członek przepływu pracy',
|
||||
tasksFoldCompleted: '✓ {count} ukończonych',
|
||||
tasksFoldExpand: 'Rozwiń ukończone węzły',
|
||||
tasksFoldCollapse: 'Zwiń ukończone węzły',
|
||||
@@ -423,7 +388,6 @@ export const pl: Record<string, string> = {
|
||||
tasksStateError: 'Błąd',
|
||||
teamBoard: 'Tablica zadań zespołu',
|
||||
teamChip: 'Zespół {members} członków · {tasks} zadań',
|
||||
teamMembers: 'Członkowie',
|
||||
teamTasksEmpty: 'Brak wspólnych zadań',
|
||||
teamTaskCreate: 'Nowe zadanie',
|
||||
teamTaskSubject: 'Temat',
|
||||
|
||||
@@ -61,29 +61,16 @@ export const pt: Record<string, string> = {
|
||||
openWithSettingsRemove: 'Remover',
|
||||
openWithSettingsInvalidHint: 'Editores com nome ausente ou modelo sem {path} / scheme:// não aparecem no menu',
|
||||
newTab: 'Nova aba',
|
||||
openExplorer: 'Explorador',
|
||||
brokenSymlink: 'Symlink quebrado',
|
||||
openGit: 'Painel Git',
|
||||
newTerminal: 'Novo terminal',
|
||||
terminalLimit: 'Limite de terminais atingido (3)',
|
||||
close: 'Fechar',
|
||||
closeOtherTabs: 'Fechar outras abas',
|
||||
closeLeftTabs: 'Fechar abas à esquerda',
|
||||
closeRightTabs: 'Fechar abas à direita',
|
||||
floatDropHint: 'Solte para abrir em uma janela flutuante',
|
||||
dockToSidebar: 'Voltar para a barra lateral',
|
||||
pinTerminal: 'Fixar Terminal',
|
||||
pinAgentTerminal: 'Fixar Terminal do Agent',
|
||||
pinToWorkspace: 'Fixar no Workspace',
|
||||
pinToGlobal: 'Fixar Globalmente',
|
||||
unpinTerminal: 'Desafixar',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'Terminal de UI',
|
||||
pinnedTerminalKindAgent: 'Terminal do Agent',
|
||||
pinnedTerminalScopeWorkspace: 'Fixado no workspace',
|
||||
pinnedTerminalScopeGlobal: 'Fixado globalmente',
|
||||
pinnedRailLabel: 'Terminais Fixados',
|
||||
closePinnedTerminal: 'Fechar Terminal',
|
||||
collapseBottomPanel: 'Recolher painel inferior',
|
||||
expandBottomPanel: 'Expandir painel inferior',
|
||||
terminalError: 'Falha na conexão do terminal',
|
||||
@@ -115,10 +102,6 @@ export const pt: Record<string, string> = {
|
||||
loading: 'Carregando…',
|
||||
error: 'Falha ao carregar',
|
||||
retry: 'Tentar novamente',
|
||||
splitLeft: 'Dividir à esquerda',
|
||||
splitRight: 'Dividir à direita',
|
||||
splitUp: 'Dividir acima',
|
||||
splitDown: 'Dividir abaixo',
|
||||
notRepo: 'Este diretório não é um repositório git',
|
||||
noChanges: 'Sem alterações',
|
||||
statusTruncated: 'Muitas alterações; exibindo apenas as primeiras 2000 entradas',
|
||||
@@ -128,7 +111,6 @@ export const pt: Record<string, string> = {
|
||||
unstageAll: 'Desfazer stage de tudo',
|
||||
commitPlaceholder: 'Mensagem de commit (Ctrl+Enter)',
|
||||
commit: 'Commit',
|
||||
commitError: 'Falha no commit',
|
||||
branch: 'Branch',
|
||||
worktree: 'Worktree',
|
||||
checkoutError: 'Falha ao alternar de branch',
|
||||
@@ -152,7 +134,6 @@ export const pt: Record<string, string> = {
|
||||
diffDeleted: 'Excluído',
|
||||
diffRenamed: 'Renomeado',
|
||||
diffExpand: 'Expandir mais {count} linhas',
|
||||
diffCollapse: 'Recolher',
|
||||
discard: 'Descartar alterações',
|
||||
discardTitle: 'Descartar alterações',
|
||||
discardDesc: 'Isso descarta as alterações do diretório de trabalho de "{path}" (não recuperável).',
|
||||
@@ -173,18 +154,14 @@ export const pt: Record<string, string> = {
|
||||
loadMore: 'Carregar mais',
|
||||
historyLoadError: 'Falha ao carregar mais histórico',
|
||||
produced: 'Produzidos',
|
||||
producedOpen: 'Abrir na barra lateral',
|
||||
disconnected: 'Terminal desconectado, reconectando…',
|
||||
exited: 'O processo do terminal saiu',
|
||||
noSession: 'Selecione uma conversa para usar a barra lateral',
|
||||
pluginNotLoaded: 'Plugin não carregado; aba indisponível:',
|
||||
hiddenFiles: 'Arquivos ocultos',
|
||||
parent: 'Diretório pai',
|
||||
copied: 'Copiado',
|
||||
copy: 'Copiar',
|
||||
newFile: 'Novo arquivo',
|
||||
openEditor: 'Abrir editor',
|
||||
gitDetail: 'Ver detalhes das alterações',
|
||||
referenceFile: '@arquivo',
|
||||
addToConversation: 'Adicionar à conversa',
|
||||
copyRelative: 'Copiar caminho relativo',
|
||||
@@ -228,7 +205,6 @@ export const pt: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'Controle total: injete CSS personalizado (pode sobrescrever estilos internos) e defina a distância de deslocamento da barra de título',
|
||||
settingsSchemeDetectedSuffix: 'detectado',
|
||||
settingsCustomCssTitle: 'CSS personalizado',
|
||||
settingsCustomCssDesc: 'Estilos anexados ao final da página (quem vem depois vence em empate de cascata; use !important para sobrescrever variáveis inline escritas por JS)',
|
||||
settingsCustomCssPlaceholder: '/* ex.: reserve 36px para um shell com barra de título desenhada por conta própria */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'Falha ao salvar',
|
||||
settingsConflict: 'A configuração foi alterada em outra janela — tente novamente',
|
||||
@@ -251,7 +227,6 @@ export const pt: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'Tamanho da fonte do terminal',
|
||||
settingsFontSizeDesc: 'Tamanho da fonte do terminal em px (9–32, padrão 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Caminho do shell',
|
||||
settingsShellDesc: 'Shell iniciado para terminais de UI e do modelo (caminho absoluto ou executável puro). Vazio mantém a ordem legada: config.shell do yaml → $SHELL / shell de login / powershell.exe no Windows. Aplica-se aos terminais abertos depois',
|
||||
settingsShellPlaceholder: 'ex.: /bin/zsh (vazio = automático)',
|
||||
@@ -293,19 +268,14 @@ export const pt: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'O site proíbe ser exibido dentro de outras páginas (X-Frame-Options / frame-ancestors), então não pode carregar na barra lateral. Abra-o diretamente no navegador.',
|
||||
browserEmbedAnyway: 'Carregar mesmo assim',
|
||||
subagent: 'Tarefas',
|
||||
openSubagent: 'Tarefas',
|
||||
subagentMainAgent: 'Agente principal',
|
||||
subagentEmpty: 'Nenhum subagente',
|
||||
subagentEmptyDesc: 'Subagentes gerados sob o agente principal aparecerão aqui',
|
||||
subagentRunning: 'Executando',
|
||||
subagentInactive: 'Inativo',
|
||||
subagentModeOneShot: 'De uso único',
|
||||
subagentModeContinuable: 'Continuável',
|
||||
subagentCount: '{count} subagentes',
|
||||
subagentCountRunning: '{count} subagentes · {running} executando',
|
||||
subagentDiagCorrupt: 'Corrompido',
|
||||
subagentDiagUnsupported: 'Não suportado',
|
||||
subagentDiagUnavailable: 'Indisponível',
|
||||
subagentThinking: 'Pensando…',
|
||||
sideChat: 'Chat lateral (beta)',
|
||||
sideChatNew: 'Novo tópico',
|
||||
@@ -326,10 +296,7 @@ export const pt: Record<string, string> = {
|
||||
sideChatThink: 'Pensamento',
|
||||
sideChatInjection: 'Contexto injetado',
|
||||
sideChatSend: 'Enviar',
|
||||
sideChatCancel: 'Parar',
|
||||
sideChatCancelTitle: 'Abortar o turno em execução (o trabalho na fila é mantido)',
|
||||
sideChatClose: 'Fechar tópico',
|
||||
sideChatCloseTitle: 'Liberar o agente do tópico (o histórico é mantido)',
|
||||
sideChatError: 'Erro no chat lateral: {message}',
|
||||
sideChatTurnUsage: 'Entrada {input} tok · Saída {output} tok',
|
||||
sideChatBlockCollapse: 'Recolher',
|
||||
@@ -365,7 +332,6 @@ export const pt: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes}m {seconds}s',
|
||||
jobDurationHours: '{hours}h {minutes}m',
|
||||
jobViewOutput: 'Ver saída',
|
||||
jobHideOutput: 'Ocultar saída',
|
||||
jobNoOutput: 'Sem saída ainda',
|
||||
jobNotReadYet: 'Aguardando o modelo ler esta tarefa; a saída aparece aqui quando o modelo executa job_output',
|
||||
jobOutputTruncated: 'Saída truncada',
|
||||
@@ -383,7 +349,6 @@ export const pt: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'Grafo de nós em camadas, com zoom e deslocamento',
|
||||
settingsViewModeTree: 'Árvore',
|
||||
settingsViewModeTreeDesc: 'Árvore com indentação clássica, navegável pelo teclado',
|
||||
tasksWorkflowMember: 'Membro do workflow',
|
||||
tasksFoldCompleted: '✓ {count} concluídos',
|
||||
tasksFoldExpand: 'Expandir os nós concluídos',
|
||||
tasksFoldCollapse: 'Recolher os nós concluídos',
|
||||
@@ -404,7 +369,6 @@ export const pt: Record<string, string> = {
|
||||
tasksStateError: 'Erro',
|
||||
teamBoard: 'Quadro de tarefas da equipe',
|
||||
teamChip: 'Equipe {members} membros · {tasks} tarefas',
|
||||
teamMembers: 'Membros',
|
||||
teamTasksEmpty: 'Ainda não há tarefas compartilhadas',
|
||||
teamTaskCreate: 'Nova tarefa',
|
||||
teamTaskSubject: 'Assunto',
|
||||
|
||||
@@ -74,29 +74,16 @@ export const ru: Record<string, string> = {
|
||||
openWithSettingsRemove: 'Удалить',
|
||||
openWithSettingsInvalidHint: 'Редакторы без имени или с шаблоном без {path} / scheme:// не появятся в меню',
|
||||
newTab: 'Новая вкладка',
|
||||
openExplorer: 'Проводник',
|
||||
brokenSymlink: 'Сломанная символическая ссылка',
|
||||
openGit: 'Панель Git',
|
||||
newTerminal: 'Новый терминал',
|
||||
terminalLimit: 'Достигнут лимит терминалов (3)',
|
||||
close: 'Закрыть',
|
||||
closeOtherTabs: 'Закрыть остальные вкладки',
|
||||
closeLeftTabs: 'Закрыть вкладки слева',
|
||||
closeRightTabs: 'Закрыть вкладки справа',
|
||||
floatDropHint: 'Отпустите, чтобы открыть в свободном окне',
|
||||
dockToSidebar: 'Вернуть на боковую панель',
|
||||
pinTerminal: 'Закрепить терминал',
|
||||
pinAgentTerminal: 'Закрепить терминал Agent',
|
||||
pinToWorkspace: 'Закрепить в рабочей области',
|
||||
pinToGlobal: 'Закрепить глобально',
|
||||
unpinTerminal: 'Открепить',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'Терминал интерфейса',
|
||||
pinnedTerminalKindAgent: 'Терминал Agent',
|
||||
pinnedTerminalScopeWorkspace: 'Закреплён в рабочей области',
|
||||
pinnedTerminalScopeGlobal: 'Закреплён глобально',
|
||||
pinnedRailLabel: 'Закреплённые терминалы',
|
||||
closePinnedTerminal: 'Закрыть терминал',
|
||||
collapseBottomPanel: 'Свернуть нижнюю панель',
|
||||
expandBottomPanel: 'Развернуть нижнюю панель',
|
||||
terminalError: 'Сбой подключения терминала',
|
||||
@@ -128,10 +115,6 @@ export const ru: Record<string, string> = {
|
||||
loading: 'Загрузка…',
|
||||
error: 'Ошибка загрузки',
|
||||
retry: 'Повторить',
|
||||
splitLeft: 'Разделить влево',
|
||||
splitRight: 'Разделить вправо',
|
||||
splitUp: 'Разделить вверх',
|
||||
splitDown: 'Разделить вниз',
|
||||
notRepo: 'Этот каталог не является git-репозиторием',
|
||||
noChanges: 'Нет изменений',
|
||||
statusTruncated: 'Слишком много изменений; показаны только первые 2000 записей',
|
||||
@@ -141,7 +124,6 @@ export const ru: Record<string, string> = {
|
||||
unstageAll: 'Убрать всё из индекса',
|
||||
commitPlaceholder: 'Сообщение коммита (Ctrl+Enter)',
|
||||
commit: 'Закоммитить',
|
||||
commitError: 'Сбой коммита',
|
||||
branch: 'Ветка',
|
||||
worktree: 'Рабочее дерево',
|
||||
checkoutError: 'Сбой переключения ветки',
|
||||
@@ -165,7 +147,6 @@ export const ru: Record<string, string> = {
|
||||
diffDeleted: 'Удалён',
|
||||
diffRenamed: 'Переименован',
|
||||
diffExpand: 'Показать оставшиеся {count} строк',
|
||||
diffCollapse: 'Свернуть',
|
||||
discard: 'Отменить изменения',
|
||||
discardTitle: 'Отменить изменения',
|
||||
discardDesc: 'Изменения «{path}» в рабочем дереве будут отброшены (восстановить нельзя).',
|
||||
@@ -186,18 +167,14 @@ export const ru: Record<string, string> = {
|
||||
loadMore: 'Загрузить ещё',
|
||||
historyLoadError: 'Не удалось загрузить ещё историю',
|
||||
produced: 'Результаты',
|
||||
producedOpen: 'Открыть в боковой панели',
|
||||
disconnected: 'Терминал отключён, переподключение…',
|
||||
exited: 'Процесс терминала завершился',
|
||||
noSession: 'Выберите сессию, чтобы использовать боковую панель',
|
||||
pluginNotLoaded: 'Плагин не загружен — вкладка недоступна:',
|
||||
hiddenFiles: 'Скрытые файлы',
|
||||
parent: 'Родительский каталог',
|
||||
copied: 'Скопировано',
|
||||
copy: 'Копировать',
|
||||
newFile: 'Новый файл',
|
||||
openEditor: 'Открыть редактор',
|
||||
gitDetail: 'Просмотр изменений',
|
||||
referenceFile: '@файл',
|
||||
addToConversation: 'Добавить в диалог',
|
||||
copyRelative: 'Копировать относительный путь',
|
||||
@@ -242,7 +219,6 @@ export const ru: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'Полный контроль: внедряется пользовательский CSS (может перекрывать встроенные стили) и задаётся величина смещения заголовка',
|
||||
settingsSchemeDetectedSuffix: 'обнаружено',
|
||||
settingsCustomCssTitle: 'Пользовательский CSS',
|
||||
settingsCustomCssDesc: 'Стили, добавляемые в конец страницы (при равном приоритете побеждает более поздний; для перезаписи инлайновых переменных из JS используйте !important)',
|
||||
settingsCustomCssPlaceholder: '/* напр.: зарезервировать 36px для оболочки с собственным заголовком */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'Не удалось сохранить',
|
||||
settingsConflict: 'Настройки были изменены в другом окне — повторите',
|
||||
@@ -265,7 +241,6 @@ export const ru: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'Размер шрифта терминала',
|
||||
settingsFontSizeDesc: 'Размер шрифта терминала в px (9–32, по умолчанию 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Путь к shell',
|
||||
settingsShellDesc: 'Shell для терминалов UI и модели (абсолютный путь или имя исполняемого файла). Пусто — сохраняется прежний порядок: config.shell из yaml → $SHELL / login shell / powershell.exe в Windows. Применяется к терминалам, открываемым позже',
|
||||
settingsShellPlaceholder: 'напр. /bin/zsh (пусто = авто)',
|
||||
@@ -308,19 +283,14 @@ export const ru: Record<string, string> = {
|
||||
browserEmbedAnyway: 'Загрузить всё равно',
|
||||
|
||||
subagent: 'Задачи',
|
||||
openSubagent: 'Задачи',
|
||||
subagentMainAgent: 'Главный агент',
|
||||
subagentEmpty: 'Нет субагентов',
|
||||
subagentEmptyDesc: 'Субагенты, порождённые главным агентом, появятся здесь',
|
||||
subagentRunning: 'Выполняется',
|
||||
subagentInactive: 'Простаивает',
|
||||
subagentModeOneShot: 'Одноразовый',
|
||||
subagentModeContinuable: 'Продолжаемый',
|
||||
subagentCount: '{count} субагентов',
|
||||
subagentCountRunning: '{count} субагентов · {running} выполняется',
|
||||
subagentDiagCorrupt: 'Повреждён',
|
||||
subagentDiagUnsupported: 'Не поддерживается',
|
||||
subagentDiagUnavailable: 'Недоступен',
|
||||
subagentThinking: 'Размышляет…',
|
||||
sideChat: 'Боковой чат (бета)',
|
||||
sideChatNew: 'Новый поток',
|
||||
@@ -341,10 +311,7 @@ export const ru: Record<string, string> = {
|
||||
sideChatThink: 'Размышления',
|
||||
sideChatInjection: 'Контекст внедрён',
|
||||
sideChatSend: 'Отправить',
|
||||
sideChatCancel: 'Остановить',
|
||||
sideChatCancelTitle: 'Прервать текущий ход (очередь сохраняется)',
|
||||
sideChatClose: 'Закрыть поток',
|
||||
sideChatCloseTitle: 'Освободить агента потока (история сохраняется)',
|
||||
sideChatError: 'Ошибка бокового чата: {message}',
|
||||
sideChatTurnUsage: 'Вход {input} tok · Выход {output} tok',
|
||||
sideChatBlockCollapse: 'Свернуть',
|
||||
@@ -380,7 +347,6 @@ export const ru: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes}м {seconds}с',
|
||||
jobDurationHours: '{hours}ч {minutes}м',
|
||||
jobViewOutput: 'Показать вывод',
|
||||
jobHideOutput: 'Скрыть вывод',
|
||||
jobNoOutput: 'Пока нет вывода',
|
||||
jobNotReadYet: 'Ожидание, пока модель прочитает вывод этой задачи (после выполнения job_output вывод появится здесь)',
|
||||
jobOutputTruncated: 'Вывод обрезан',
|
||||
@@ -398,7 +364,6 @@ export const ru: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'Многоуровневый граф узлов с масштабированием и панорамированием',
|
||||
settingsViewModeTree: 'Дерево',
|
||||
settingsViewModeTreeDesc: 'Классическое дерево с отступами, навигация с клавиатуры',
|
||||
tasksWorkflowMember: 'Участник рабочего процесса',
|
||||
tasksFoldCompleted: '✓ {count} завершено',
|
||||
tasksFoldExpand: 'Развернуть завершённые узлы',
|
||||
tasksFoldCollapse: 'Свернуть завершённые узлы',
|
||||
@@ -419,7 +384,6 @@ export const ru: Record<string, string> = {
|
||||
tasksStateError: 'Ошибка',
|
||||
teamBoard: 'Доска задач команды',
|
||||
teamChip: 'Команда: {members} участников · {tasks} задач',
|
||||
teamMembers: 'Участники',
|
||||
teamTasksEmpty: 'Общих задач пока нет',
|
||||
teamTaskCreate: 'Новая задача',
|
||||
teamTaskSubject: 'Тема',
|
||||
|
||||
@@ -61,29 +61,16 @@ export const sv: Record<string, string> = {
|
||||
openWithSettingsRemove: 'Ta bort',
|
||||
openWithSettingsInvalidHint: 'Editorer med saknat namn eller en mall utan {path} / scheme:// visas inte i menyn',
|
||||
newTab: 'Ny flik',
|
||||
openExplorer: 'Utforskare',
|
||||
brokenSymlink: 'Bruten symbolisk länk',
|
||||
openGit: 'Git-panel',
|
||||
newTerminal: 'Ny terminal',
|
||||
terminalLimit: 'Terminalgräns nådd (3)',
|
||||
close: 'Stäng',
|
||||
closeOtherTabs: 'Stäng andra flikar',
|
||||
closeLeftTabs: 'Stäng flikar till vänster',
|
||||
closeRightTabs: 'Stäng flikar till höger',
|
||||
floatDropHint: 'Släpp för att öppna i ett fritt fönster',
|
||||
dockToSidebar: 'Tillbaka till sidopanelen',
|
||||
pinTerminal: 'Fäst Terminal',
|
||||
pinAgentTerminal: 'Fäst Agent-terminal',
|
||||
pinToWorkspace: 'Fäst på arbetsyta',
|
||||
pinToGlobal: 'Fäst globalt',
|
||||
unpinTerminal: 'Ta bort fästning',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'UI-terminal',
|
||||
pinnedTerminalKindAgent: 'Agent-terminal',
|
||||
pinnedTerminalScopeWorkspace: 'Fäst på arbetsyta',
|
||||
pinnedTerminalScopeGlobal: 'Fäst globalt',
|
||||
pinnedRailLabel: 'Fästa terminaler',
|
||||
closePinnedTerminal: 'Stäng terminal',
|
||||
collapseBottomPanel: 'Komprimera bottenpanel',
|
||||
expandBottomPanel: 'Expandera bottenpanel',
|
||||
terminalError: 'Terminalanslutning misslyckades',
|
||||
@@ -115,10 +102,6 @@ export const sv: Record<string, string> = {
|
||||
loading: 'Laddar…',
|
||||
error: 'Kunde inte ladda',
|
||||
retry: 'Försök igen',
|
||||
splitLeft: 'Dela vänster',
|
||||
splitRight: 'Dela höger',
|
||||
splitUp: 'Dela upp',
|
||||
splitDown: 'Dela ner',
|
||||
notRepo: 'Denna katalog är inte ett Git-arkiv',
|
||||
noChanges: 'Inga ändringar',
|
||||
statusTruncated: 'För många ändringar; endast de första 2000 posterna visas',
|
||||
@@ -128,7 +111,6 @@ export const sv: Record<string, string> = {
|
||||
unstageAll: 'Avköa alla',
|
||||
commitPlaceholder: 'Commit-meddelande (Ctrl+Enter)',
|
||||
commit: 'Commit',
|
||||
commitError: 'Commit misslyckades',
|
||||
branch: 'Gren',
|
||||
worktree: 'Arbetsträd',
|
||||
checkoutError: 'Grenbyte misslyckades',
|
||||
@@ -152,7 +134,6 @@ export const sv: Record<string, string> = {
|
||||
diffDeleted: 'Borttagen',
|
||||
diffRenamed: 'Omdöpt',
|
||||
diffExpand: 'Expandera {count} fler rader',
|
||||
diffCollapse: 'Komprimera',
|
||||
discard: 'Förkasta ändringar',
|
||||
discardTitle: 'Förkasta ändringar',
|
||||
discardDesc: 'Detta förkastar arbetskopians ändringar av ”{path}” (kan inte ångras).',
|
||||
@@ -173,18 +154,14 @@ export const sv: Record<string, string> = {
|
||||
loadMore: 'Ladda fler',
|
||||
historyLoadError: 'Kunde inte ladda mer historik',
|
||||
produced: 'Producerat',
|
||||
producedOpen: 'Öppna i sidopanelen',
|
||||
disconnected: 'Terminalen frånkopplad, ansluter igen…',
|
||||
exited: 'Terminalprocess avslutad',
|
||||
noSession: 'Välj en konversation för att använda sidopanelen',
|
||||
pluginNotLoaded: 'Plugin inte laddad; flik otillgänglig:',
|
||||
hiddenFiles: 'Dolda filer',
|
||||
parent: 'Överordnad katalog',
|
||||
copied: 'Kopierades',
|
||||
copy: 'Kopiera',
|
||||
newFile: 'Ny fil',
|
||||
openEditor: 'Öppna editor',
|
||||
gitDetail: 'Visa ändringsdetaljer',
|
||||
referenceFile: '@fil',
|
||||
addToConversation: 'Lägg till i konversation',
|
||||
copyRelative: 'Kopiera relativ sökväg',
|
||||
@@ -228,7 +205,6 @@ export const sv: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'Full kontroll: injicera egen CSS (kan åsidosätta inbyggda stilar) och sätt titelfältets förskjutningsavstånd',
|
||||
settingsSchemeDetectedSuffix: 'upptäckt',
|
||||
settingsCustomCssTitle: 'Anpassad CSS',
|
||||
settingsCustomCssDesc: 'Stilar tillagda på slutet av sidan (senare i kaskaden vinner vid oavgjort; använd !important för att åsidosätta JS-skrivna inline-variabler)',
|
||||
settingsCustomCssPlaceholder: '/* t.ex. reservera 36px för ett skal med egenritat titelfält */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'Kunde inte spara',
|
||||
settingsConflict: 'Inställningen ändrades i ett annat fönster — vänligen försök igen',
|
||||
@@ -251,7 +227,6 @@ export const sv: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'Terminalens teckenstorlek',
|
||||
settingsFontSizeDesc: 'Terminalens teckenstorlek i px (9–32, standard 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Skalsökväg',
|
||||
settingsShellDesc: 'Skal som startas för UI- och modellterminaler (absolut sökväg ellerbart körbart namn). Tomt behåller den äldre ordningen: yaml config.shell → $SHELL / inloggningsskal / Windows powershell.exe. Gäller terminaler som öppnas senare',
|
||||
settingsShellPlaceholder: 't.ex. /bin/zsh (tomt = auto)',
|
||||
@@ -293,19 +268,14 @@ export const sv: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'Sajten förbjuder att visas inuti andra sidor (X-Frame-Options / frame-ancestors), så den kan inte ladda i sidopanelen. Öppna den direkt i er webbläsare i stället.',
|
||||
browserEmbedAnyway: 'Ladda ändå',
|
||||
subagent: 'Uppgifter',
|
||||
openSubagent: 'Uppgifter',
|
||||
subagentMainAgent: 'Huvudagent',
|
||||
subagentEmpty: 'Inga subagenter',
|
||||
subagentEmptyDesc: 'Subagenter skapade under huvudagenten visas här',
|
||||
subagentRunning: 'Kör',
|
||||
subagentInactive: 'Inaktiv',
|
||||
subagentModeOneShot: 'Engångs',
|
||||
subagentModeContinuable: 'Fortsättbar',
|
||||
subagentCount: '{count} subagenter',
|
||||
subagentCountRunning: '{count} subagenter · {running} kör',
|
||||
subagentDiagCorrupt: 'Korrupt',
|
||||
subagentDiagUnsupported: 'Stöds ej',
|
||||
subagentDiagUnavailable: 'Otillgänglig',
|
||||
subagentThinking: 'Tänker…',
|
||||
sideChat: 'Sidochatt (beta)',
|
||||
sideChatNew: 'Ny tråd',
|
||||
@@ -326,10 +296,7 @@ export const sv: Record<string, string> = {
|
||||
sideChatThink: 'Tänker',
|
||||
sideChatInjection: 'Kontext injicerad',
|
||||
sideChatSend: 'Skicka',
|
||||
sideChatCancel: 'Stoppa',
|
||||
sideChatCancelTitle: 'Avbryt den pågående vändan (köat arbete behålls)',
|
||||
sideChatClose: 'Stäng tråd',
|
||||
sideChatCloseTitle: 'Frigör trådens agent (historik behålls)',
|
||||
sideChatError: 'Sidochattsfel: {message}',
|
||||
sideChatTurnUsage: 'In {input} tok · Ut {output} tok',
|
||||
sideChatBlockCollapse: 'Fäll ihop',
|
||||
@@ -365,7 +332,6 @@ export const sv: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes}m {seconds}s',
|
||||
jobDurationHours: '{hours}t {minutes}m',
|
||||
jobViewOutput: 'Visa utdata',
|
||||
jobHideOutput: 'Dölj utdata',
|
||||
jobNoOutput: 'Ingen utdata än',
|
||||
jobNotReadYet: 'Väntar på att modellen ska läsa detta jobb; dess utdata visas här när modellen kör job_output',
|
||||
jobOutputTruncated: 'Utdata avkortad',
|
||||
@@ -383,7 +349,6 @@ export const sv: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'Lagerindelad nodgraf med zoom och panorering',
|
||||
settingsViewModeTree: 'Träd',
|
||||
settingsViewModeTreeDesc: 'Klassiskt indragsträd, navigerbart med tangentbord',
|
||||
tasksWorkflowMember: 'Arbetsflödesmedlem',
|
||||
tasksFoldCompleted: '✓ {count} klara',
|
||||
tasksFoldExpand: 'Visa färdiga noder',
|
||||
tasksFoldCollapse: 'Dölj färdiga noder',
|
||||
@@ -404,7 +369,6 @@ export const sv: Record<string, string> = {
|
||||
tasksStateError: 'Fel',
|
||||
teamBoard: 'Teamuppgiftstavla',
|
||||
teamChip: 'Team {members} medlemmar · {tasks} uppgifter',
|
||||
teamMembers: 'Medlemmar',
|
||||
teamTasksEmpty: 'Inga delade uppgifter än',
|
||||
teamTaskCreate: 'Ny uppgift',
|
||||
teamTaskSubject: 'Ämne',
|
||||
|
||||
@@ -78,29 +78,16 @@ export const th: Record<string, string> = {
|
||||
openWithSettingsRemove: 'ลบ',
|
||||
openWithSettingsInvalidHint: 'ตัวแก้ไขที่ไม่มีชื่อหรือเทมเพลตที่ไม่มี {path} / scheme:// จะไม่ปรากฏในเมนู',
|
||||
newTab: 'Tab ใหม่',
|
||||
openExplorer: 'ตัวสำรวจ',
|
||||
brokenSymlink: 'Symlink เสีย',
|
||||
openGit: 'พาเนล Git',
|
||||
newTerminal: 'เทอร์มินัลใหม่',
|
||||
terminalLimit: 'ถึงขีดจำกัดเทอร์มินัลแล้ว (3)',
|
||||
close: 'ปิด',
|
||||
closeOtherTabs: 'ปิด Tab อื่น',
|
||||
closeLeftTabs: 'ปิด Tab ด้านซ้าย',
|
||||
closeRightTabs: 'ปิด Tab ด้านขวา',
|
||||
floatDropHint: 'ปล่อยเพื่อเปิดในหน้าต่างอิสระ',
|
||||
dockToSidebar: 'กลับไปที่แถบข้าง',
|
||||
pinTerminal: 'ปักหมุดเทอร์มินัล',
|
||||
pinAgentTerminal: 'ปักหมุดเทอร์มินัล Agent',
|
||||
pinToWorkspace: 'ปักหมุดไปยังพื้นที่ทำงาน',
|
||||
pinToGlobal: 'ปักหมุดแบบ Global',
|
||||
unpinTerminal: 'ยกเลิกการปักหมุด',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'เทอร์มินัล UI',
|
||||
pinnedTerminalKindAgent: 'เทอร์มินัล Agent',
|
||||
pinnedTerminalScopeWorkspace: 'ปักหมุดไปยังพื้นที่ทำงาน',
|
||||
pinnedTerminalScopeGlobal: 'ปักหมุดแบบ Global',
|
||||
pinnedRailLabel: 'เทอร์มินัลที่ปักหมุด',
|
||||
closePinnedTerminal: 'ปิดเทอร์มินัล',
|
||||
collapseBottomPanel: 'ย่อพาเนลด้านล่าง',
|
||||
expandBottomPanel: 'ขยายพาเนลด้านล่าง',
|
||||
terminalError: 'การเชื่อมต่อเทอร์มินัลล้มเหลว',
|
||||
@@ -132,10 +119,6 @@ export const th: Record<string, string> = {
|
||||
loading: 'กำลังโหลด…',
|
||||
error: 'โหลดล้มเหลว',
|
||||
retry: 'ลองอีกครั้ง',
|
||||
splitLeft: 'แยกซ้าย',
|
||||
splitRight: 'แยกขวา',
|
||||
splitUp: 'แยกขึ้น',
|
||||
splitDown: 'แยกลง',
|
||||
notRepo: 'ไดเรกทอรีนี้ไม่ใช่ git repository',
|
||||
noChanges: 'ไม่มีการเปลี่ยนแปลง',
|
||||
statusTruncated: 'การเปลี่ยนแปลงมากเกินไป แสดงเพียง 2000 รายการแรก',
|
||||
@@ -145,7 +128,6 @@ export const th: Record<string, string> = {
|
||||
unstageAll: 'Unstage ทั้งหมด',
|
||||
commitPlaceholder: 'ข้อความ commit (Ctrl+Enter)',
|
||||
commit: 'Commit',
|
||||
commitError: 'Commit ล้มเหลว',
|
||||
branch: 'Branch',
|
||||
worktree: 'เวิร์กทรี',
|
||||
checkoutError: 'สลับ branch ล้มเหลว',
|
||||
@@ -169,7 +151,6 @@ export const th: Record<string, string> = {
|
||||
diffDeleted: 'ลบ',
|
||||
diffRenamed: 'เปลี่ยนชื่อ',
|
||||
diffExpand: 'ขยายอีก {count} บรรทัด',
|
||||
diffCollapse: 'ย่อ',
|
||||
discard: 'ยกเลิกการเปลี่ยนแปลง',
|
||||
discardTitle: 'ยกเลิกการเปลี่ยนแปลง',
|
||||
discardDesc: 'จะยกเลิกการเปลี่ยนแปลง worktree ของ "{path}" (ไม่สามารถกู้คืนได้)',
|
||||
@@ -190,18 +171,14 @@ export const th: Record<string, string> = {
|
||||
loadMore: 'โหลดเพิ่มเติม',
|
||||
historyLoadError: 'โหลดประวัติเพิ่มเติมล้มเหลว',
|
||||
produced: 'ผลลัพธ์ที่สร้าง',
|
||||
producedOpen: 'เปิดในแถบด้านข้าง',
|
||||
disconnected: 'เทอร์มินัลถูกตัดการเชื่อมต่อ กำลังเชื่อมต่อใหม่…',
|
||||
exited: 'กระบวนการเทอร์มินัลออกแล้ว',
|
||||
noSession: 'เลือกแชทเพื่อใช้แถบด้านข้าง',
|
||||
pluginNotLoaded: 'ปลั๊กอินไม่ได้โหลด; tab ไม่พร้อมใช้งาน:',
|
||||
hiddenFiles: 'ไฟล์ที่ซ่อนอยู่',
|
||||
parent: 'ไดเรกทอรีหลัก',
|
||||
copied: 'คัดลอกแล้ว',
|
||||
copy: 'คัดลอก',
|
||||
newFile: 'ไฟล์ใหม่',
|
||||
openEditor: 'เปิดตัวแก้ไข',
|
||||
gitDetail: 'ดูรายละเอียดการเปลี่ยนแปลง',
|
||||
referenceFile: '@ไฟล์',
|
||||
addToConversation: 'เพิ่มไปยังแชท',
|
||||
copyRelative: 'คัดลอกพาธสัมพัทธ์',
|
||||
@@ -245,7 +222,6 @@ export const th: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'ควบคุมเต็ม: ฉีด CSS ที่กำหนดเอง (สามารถแทนที่สไตล์ built-in) และตั้งระยะการเลื่อนไตเติลบาร์',
|
||||
settingsSchemeDetectedSuffix: 'ตรวจพบแล้ว',
|
||||
settingsCustomCssTitle: 'CSS ที่กำหนดเอง',
|
||||
settingsCustomCssDesc: 'สไตล์ที่เพิ่มต่อท้ายหน้า (ที่มาทีหลังใน cascade ชนะ; ใช้ !important เพื่อแทนที่ตัวแปร inline ที่เขียนโดย JS)',
|
||||
settingsCustomCssPlaceholder: '/* เช่น สำรอง 36px สำหรับเชลล์ที่มีไตเติลบาร์ที่วาดเอง */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'บันทึกล้มเหลว',
|
||||
settingsConflict: 'การตั้งค่าถูกเปลี่ยนในหน้าต่างอื่น — โปรดลองอีกครั้ง',
|
||||
@@ -268,7 +244,6 @@ export const th: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'ขนาดฟอนต์เทอร์มินัล',
|
||||
settingsFontSizeDesc: 'ขนาดฟอนต์เทอร์มินัลเป็น px (9–32, ค่าเริ่มต้น 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'พาธ Shell',
|
||||
settingsShellDesc: 'Shell ที่เรียกสำหรับเทอร์มินัล UI และโมเดล (พาธ absolute หรือ executable ลำพัง) ว่างจะคงลำดับเดิม: yaml config.shell → $SHELL / login shell / Windows powershell.exe มีผลกับเทอร์มินัลที่เปิดภายหลัง',
|
||||
settingsShellPlaceholder: 'เช่น /bin/zsh (ว่าง = อัตโนมัติ)',
|
||||
@@ -310,19 +285,14 @@ export const th: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'ไซต์ห้ามไม่ให้แสดงภายในหน้าอื่น (X-Frame-Options / frame-ancestors) จึงไม่สามารถโหลดในแถบด้านข้างได้ เปิดโดยตรงในเบราว์เซอร์ของคุณแทน',
|
||||
browserEmbedAnyway: 'โหลดต่อไป',
|
||||
subagent: 'งาน',
|
||||
openSubagent: 'งาน',
|
||||
subagentMainAgent: 'ตัวแทนหลัก',
|
||||
subagentEmpty: 'ไม่มีตัวแทนย่อย',
|
||||
subagentEmptyDesc: 'ตัวแทนย่อยที่สร้างภายใต้ตัวแทนหลักจะปรากฏที่นี่',
|
||||
subagentRunning: 'กำลังทำงาน',
|
||||
subagentInactive: 'ไม่ได้ทำงาน',
|
||||
subagentModeOneShot: 'ครั้งเดียว',
|
||||
subagentModeContinuable: 'ทำต่อได้',
|
||||
subagentCount: '{count} ตัวแทนย่อย',
|
||||
subagentCountRunning: '{count} ตัวแทนย่อย · {running} กำลังทำงาน',
|
||||
subagentDiagCorrupt: 'เสียหาย',
|
||||
subagentDiagUnsupported: 'ไม่รองรับ',
|
||||
subagentDiagUnavailable: 'ไม่พร้อมใช้งาน',
|
||||
subagentThinking: 'กำลังคิด…',
|
||||
sideChat: 'แชทด้านข้าง (เบต้า)',
|
||||
sideChatNew: 'เธรดใหม่',
|
||||
@@ -343,10 +313,7 @@ export const th: Record<string, string> = {
|
||||
sideChatThink: 'กำลังคิด',
|
||||
sideChatInjection: 'แทรกบริบทแล้ว',
|
||||
sideChatSend: 'ส่ง',
|
||||
sideChatCancel: 'หยุด',
|
||||
sideChatCancelTitle: 'ยกเลิกการทำงานรอบปัจจุบัน (งานในคิวยังคงอยู่)',
|
||||
sideChatClose: 'ปิดเธรด',
|
||||
sideChatCloseTitle: 'ปล่อยตัวแทนของเธรด (ประวัติยังคงอยู่)',
|
||||
sideChatError: 'ข้อผิดพลาดแชทด้านข้าง: {message}',
|
||||
sideChatTurnUsage: 'อินพุต {input} tok · เอาต์พุต {output} tok',
|
||||
sideChatBlockCollapse: 'ย่อ',
|
||||
@@ -382,7 +349,6 @@ export const th: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes} นาที {seconds} วิ',
|
||||
jobDurationHours: '{hours} ชม. {minutes} นาที',
|
||||
jobViewOutput: 'ดูเอาต์พุต',
|
||||
jobHideOutput: 'ซ่อนเอาต์พุต',
|
||||
jobNoOutput: 'ยังไม่มีเอาต์พุต',
|
||||
jobNotReadYet: 'รอให้โมเดลอ่านงานนี้; เอาต์พุตจะปรากฏที่นี่เมื่อโมเดลเรียก job_output',
|
||||
jobOutputTruncated: 'เอาต์พุตถูกตัดทิ้ง',
|
||||
@@ -400,7 +366,6 @@ export const th: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'กราฟโหนดแบบชั้น ซูมและเลื่อนได้',
|
||||
settingsViewModeTree: 'มุมมองต้นไม้',
|
||||
settingsViewModeTreeDesc: 'ต้นไม้แบบเยื้องคลาสสิก นำทางด้วยคีย์บอร์ดได้',
|
||||
tasksWorkflowMember: 'สมาชิกเวิร์กโฟลว์',
|
||||
tasksFoldCompleted: '✓ เสร็จแล้ว {count}',
|
||||
tasksFoldExpand: 'ขยายโหนดที่เสร็จแล้ว',
|
||||
tasksFoldCollapse: 'ย่อโหนดที่เสร็จแล้ว',
|
||||
@@ -421,7 +386,6 @@ export const th: Record<string, string> = {
|
||||
tasksStateError: 'ข้อผิดพลาด',
|
||||
teamBoard: 'บอร์ดงานของทีม',
|
||||
teamChip: 'ทีม {members} สมาชิก · {tasks} งาน',
|
||||
teamMembers: 'สมาชิก',
|
||||
teamTasksEmpty: 'ยังไม่มีงานที่แชร์',
|
||||
teamTaskCreate: 'งานใหม่',
|
||||
teamTaskSubject: 'หัวข้อ',
|
||||
|
||||
@@ -78,29 +78,16 @@ export const tr: Record<string, string> = {
|
||||
openWithSettingsRemove: 'Kaldır',
|
||||
openWithSettingsInvalidHint: 'Adı eksik veya {path}/scheme:// içermeyen şablonlu düzenleyiciler menüde gösterilmez',
|
||||
newTab: 'Yeni sekme',
|
||||
openExplorer: 'Gezgin',
|
||||
brokenSymlink: 'Bozuk sembolik bağ',
|
||||
openGit: 'Git paneli',
|
||||
newTerminal: 'Yeni terminal',
|
||||
terminalLimit: 'Terminal sınırına ulaşıldı (3)',
|
||||
close: 'Kapat',
|
||||
closeOtherTabs: 'Diğer sekmeleri kapat',
|
||||
closeLeftTabs: 'Soldaki sekmeleri kapat',
|
||||
closeRightTabs: 'Sağdaki sekmeleri kapat',
|
||||
floatDropHint: 'Serbest pencerede açmak için bırakın',
|
||||
dockToSidebar: 'Kenar çubuğuna geri dön',
|
||||
pinTerminal: 'Terminali Sabitle',
|
||||
pinAgentTerminal: 'Agent Terminalini Sabitle',
|
||||
pinToWorkspace: 'Çalışma Alanına Sabitle',
|
||||
pinToGlobal: 'Genel Olarak Sabitle',
|
||||
unpinTerminal: 'Sabitlemeyi Kaldır',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'UI Terminali',
|
||||
pinnedTerminalKindAgent: 'Agent Terminali',
|
||||
pinnedTerminalScopeWorkspace: 'Çalışma alanına sabitlendi',
|
||||
pinnedTerminalScopeGlobal: 'Genel olarak sabitlendi',
|
||||
pinnedRailLabel: 'Sabitlenmiş Terminaller',
|
||||
closePinnedTerminal: 'Terminali Kapat',
|
||||
collapseBottomPanel: 'Alt paneli daralt',
|
||||
expandBottomPanel: 'Alt paneli genişlet',
|
||||
terminalError: 'Terminal bağlantısı başarısız',
|
||||
@@ -132,10 +119,6 @@ export const tr: Record<string, string> = {
|
||||
loading: 'Yükleniyor…',
|
||||
error: 'Yükleme başarısız',
|
||||
retry: 'Yeniden dene',
|
||||
splitLeft: 'Sola böl',
|
||||
splitRight: 'Sağa böl',
|
||||
splitUp: 'Yukarı böl',
|
||||
splitDown: 'Aşağı böl',
|
||||
notRepo: 'Bu dizin bir git deposu değil',
|
||||
noChanges: 'Değişiklik yok',
|
||||
statusTruncated: 'Çok fazla değişiklik var; yalnızca ilk 2000 giriş gösteriliyor',
|
||||
@@ -145,7 +128,6 @@ export const tr: Record<string, string> = {
|
||||
unstageAll: 'Tümünü sahnelemeden kaldır',
|
||||
commitPlaceholder: 'İşleme iletisi (Ctrl+Enter)',
|
||||
commit: 'İşle',
|
||||
commitError: 'İşleme başarısız',
|
||||
branch: 'Dal',
|
||||
worktree: 'Çalışma ağacı',
|
||||
checkoutError: 'Dal değiştirme başarısız',
|
||||
@@ -169,7 +151,6 @@ export const tr: Record<string, string> = {
|
||||
diffDeleted: 'Silindi',
|
||||
diffRenamed: 'Yeniden adlandırıldı',
|
||||
diffExpand: '{count} satır daha göster',
|
||||
diffCollapse: 'Daralt',
|
||||
discard: 'Değişiklikleri at',
|
||||
discardTitle: 'Değişiklikleri at',
|
||||
discardDesc: 'Bu, «{path}» öğesinin çalışma ağacı değişikliklerini atar (geri alınamaz).',
|
||||
@@ -190,18 +171,14 @@ export const tr: Record<string, string> = {
|
||||
loadMore: 'Daha fazla yükle',
|
||||
historyLoadError: 'Daha fazla geçmiş yüklenemedi',
|
||||
produced: 'Üretilenler',
|
||||
producedOpen: 'Kenar çubuğunda aç',
|
||||
disconnected: 'Terminal bağlantısı kesildi, yeniden bağlanılıyor…',
|
||||
exited: 'Terminal süreci sonlandı',
|
||||
noSession: 'Kenar çubuğunu kullanmak için bir oturum seçin',
|
||||
pluginNotLoaded: 'Eklenti yüklenmedi; sekme kullanılamıyor:',
|
||||
hiddenFiles: 'Gizli dosyalar',
|
||||
parent: 'Üst dizin',
|
||||
copied: 'Kopyalandı',
|
||||
copy: 'Kopyala',
|
||||
newFile: 'Yeni dosya',
|
||||
openEditor: 'Düzenleyiciyi aç',
|
||||
gitDetail: 'Değişiklik ayrıntılarını görüntüle',
|
||||
referenceFile: '@dosya',
|
||||
addToConversation: 'Sohbete ekle',
|
||||
copyRelative: 'Göreli yolu kopyala',
|
||||
@@ -245,7 +222,6 @@ export const tr: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'Tam denetim: özel CSS enjekte et (yerleşik stilleri geçersiz kılabilir) ve başlık çubuğu kaydırma mesafesini ayarla',
|
||||
settingsSchemeDetectedSuffix: 'algılandı',
|
||||
settingsCustomCssTitle: 'Özel CSS',
|
||||
settingsCustomCssDesc: 'Sayfanın sonuna eklenen stiller (basamakta sonra yazılan kazanır; JS ile yazılmış satır içi değişkenleri geçersiz kılmak için !important kullanın)',
|
||||
settingsCustomCssPlaceholder: '/* örn. özel çizili başlık çubuğu olan bir kabuk için 36px ayır */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'Kaydetme başarısız',
|
||||
settingsConflict: 'Ayar başka bir pencerede değiştirildi — lütfen yeniden deneyin',
|
||||
@@ -268,7 +244,6 @@ export const tr: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'Terminal yazı boyutu',
|
||||
settingsFontSizeDesc: 'px cinsinden terminal yazı boyutu (9–32, varsayılan 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Kabuk yolu',
|
||||
settingsShellDesc: 'Arayüz ve model terminalleri için başlatılan kabuk (mutlak yol veya yalın yürütülebilir). Boş, eski sırayı korur: yaml config.shell → $SHELL / oturum açma kabuğu / Windows powershell.exe. Sonradan açılan terminaller için geçerli',
|
||||
settingsShellPlaceholder: 'ör. /bin/zsh (boş = otomatik)',
|
||||
@@ -310,19 +285,14 @@ export const tr: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'Site başka sayfalar içinde gösterilmeyi yasaklıyor (X-Frame-Options / frame-ancestors), bu yüzden kenar çubuğunda yüklenemiyor. Bunun yerine doğrudan tarayıcınızda açın.',
|
||||
browserEmbedAnyway: 'Yine de yükle',
|
||||
subagent: 'Görevler',
|
||||
openSubagent: 'Görevler',
|
||||
subagentMainAgent: 'Ana aracı',
|
||||
subagentEmpty: 'Alt aracı yok',
|
||||
subagentEmptyDesc: 'Ana aracının altında doğan alt aracılar burada görünür',
|
||||
subagentRunning: 'Çalışıyor',
|
||||
subagentInactive: 'Etkin değil',
|
||||
subagentModeOneShot: 'Tek seferlik',
|
||||
subagentModeContinuable: 'Sürdürülebilir',
|
||||
subagentCount: '{count} alt aracı',
|
||||
subagentCountRunning: '{count} alt aracı · {running} çalışıyor',
|
||||
subagentDiagCorrupt: 'Bozuk',
|
||||
subagentDiagUnsupported: 'Desteklenmiyor',
|
||||
subagentDiagUnavailable: 'Kullanılamıyor',
|
||||
subagentThinking: 'Düşünüyor…',
|
||||
sideChat: 'Yan sohbet (beta)',
|
||||
sideChatNew: 'Yeni iş parçacığı',
|
||||
@@ -343,10 +313,7 @@ export const tr: Record<string, string> = {
|
||||
sideChatThink: 'Düşünme',
|
||||
sideChatInjection: 'Bağlam enjekte edildi',
|
||||
sideChatSend: 'Gönder',
|
||||
sideChatCancel: 'Durdur',
|
||||
sideChatCancelTitle: 'Geçerli turu durdur (sıradaki iş korunur)',
|
||||
sideChatClose: 'İş parçacığını kapat',
|
||||
sideChatCloseTitle: 'İş parçacığının aracısını serbest bırak (geçmiş korunur)',
|
||||
sideChatError: 'Yan sohbet hatası: {message}',
|
||||
sideChatTurnUsage: 'Giriş {input} tok · Çıkış {output} tok',
|
||||
sideChatBlockCollapse: 'Daralt',
|
||||
@@ -382,7 +349,6 @@ export const tr: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes} dk {seconds} sn',
|
||||
jobDurationHours: '{hours} sa {minutes} dk',
|
||||
jobViewOutput: 'Çıkışı görüntüle',
|
||||
jobHideOutput: 'Çıkışı gizle',
|
||||
jobNoOutput: 'Henüz çıkış yok',
|
||||
jobNotReadYet: 'Modelin bu işin çıkışını okuması bekleniyor; model job_output çalıştırdıktan sonra çıkış burada görünür',
|
||||
jobOutputTruncated: 'Çıkış kırpıldı',
|
||||
@@ -400,7 +366,6 @@ export const tr: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'Yakınlaştırma ve kaydırma ile katmanlı düğüm grafiği',
|
||||
settingsViewModeTree: 'Ağaç',
|
||||
settingsViewModeTreeDesc: 'Klasik girintili ağaç, klavye ile gezilebilir',
|
||||
tasksWorkflowMember: 'İş akışı üyesi',
|
||||
tasksFoldCompleted: '✓ {count} tamamlandı',
|
||||
tasksFoldExpand: 'Tamamlanan düğümleri genişlet',
|
||||
tasksFoldCollapse: 'Tamamlanan düğümleri daralt',
|
||||
@@ -421,7 +386,6 @@ export const tr: Record<string, string> = {
|
||||
tasksStateError: 'Hata',
|
||||
teamBoard: 'Takım görev panosu',
|
||||
teamChip: 'Takım {members} üye · {tasks} görev',
|
||||
teamMembers: 'Üyeler',
|
||||
teamTasksEmpty: 'Henüz paylaşılan görev yok',
|
||||
teamTaskCreate: 'Yeni görev',
|
||||
teamTaskSubject: 'Konu',
|
||||
|
||||
@@ -78,29 +78,16 @@ export const vi: Record<string, string> = {
|
||||
openWithSettingsRemove: 'Xóa',
|
||||
openWithSettingsInvalidHint: 'Trình soạn thảo thiếu tên hoặc mẫu (cần chứa {path} và bắt đầu bằng scheme://) sẽ không xuất hiện trong menu',
|
||||
newTab: 'Tab mới',
|
||||
openExplorer: 'Trình khám phá',
|
||||
brokenSymlink: 'Symlink hỏng',
|
||||
openGit: 'Panel Git',
|
||||
newTerminal: 'Terminal mới',
|
||||
terminalLimit: 'Đã đạt giới hạn terminal (3)',
|
||||
close: 'Đóng',
|
||||
closeOtherTabs: 'Đóng các tab khác',
|
||||
closeLeftTabs: 'Đóng tab bên trái',
|
||||
closeRightTabs: 'Đóng tab bên phải',
|
||||
floatDropHint: 'Thả để mở trong cửa sổ tự do',
|
||||
dockToSidebar: 'Quay lại thanh bên',
|
||||
pinTerminal: 'Ghim Terminal',
|
||||
pinAgentTerminal: 'Ghim Terminal Agent',
|
||||
pinToWorkspace: 'Ghim vào Workspace',
|
||||
pinToGlobal: 'Ghim Toàn cục',
|
||||
unpinTerminal: 'Bỏ ghim',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'Terminal UI',
|
||||
pinnedTerminalKindAgent: 'Terminal Agent',
|
||||
pinnedTerminalScopeWorkspace: 'Đã ghim vào workspace',
|
||||
pinnedTerminalScopeGlobal: 'Đã ghim toàn cục',
|
||||
pinnedRailLabel: 'Terminal đã ghim',
|
||||
closePinnedTerminal: 'Đóng Terminal',
|
||||
collapseBottomPanel: 'Thu gọn panel dưới',
|
||||
expandBottomPanel: 'Mở rộng panel dưới',
|
||||
terminalError: 'Kết nối terminal thất bại',
|
||||
@@ -132,10 +119,6 @@ export const vi: Record<string, string> = {
|
||||
loading: 'Đang tải…',
|
||||
error: 'Tải thất bại',
|
||||
retry: 'Thử lại',
|
||||
splitLeft: 'Chia bên trái',
|
||||
splitRight: 'Chia bên phải',
|
||||
splitUp: 'Chia lên trên',
|
||||
splitDown: 'Chia xuống dưới',
|
||||
notRepo: 'Thư mục hiện tại không phải repo git',
|
||||
noChanges: 'Không có thay đổi',
|
||||
statusTruncated: 'Quá nhiều thay đổi; chỉ hiển thị 2000 mục đầu tiên',
|
||||
@@ -145,7 +128,6 @@ export const vi: Record<string, string> = {
|
||||
unstageAll: 'Unstage tất cả',
|
||||
commitPlaceholder: 'Thông điệp commit (Ctrl+Enter)',
|
||||
commit: 'Commit',
|
||||
commitError: 'Commit thất bại',
|
||||
branch: 'Branch',
|
||||
worktree: 'Worktree',
|
||||
checkoutError: 'Chuyển branch thất bại',
|
||||
@@ -169,7 +151,6 @@ export const vi: Record<string, string> = {
|
||||
diffDeleted: 'Xóa',
|
||||
diffRenamed: 'Đổi tên',
|
||||
diffExpand: 'Mở rộng {count} dòng còn lại',
|
||||
diffCollapse: 'Thu gọn',
|
||||
discard: 'Bỏ thay đổi',
|
||||
discardTitle: 'Bỏ thay đổi',
|
||||
discardDesc: 'Sẽ hủy các thay đổi worktree của «{path}» (không thể khôi phục).',
|
||||
@@ -190,18 +171,14 @@ export const vi: Record<string, string> = {
|
||||
loadMore: 'Tải thêm',
|
||||
historyLoadError: 'Tải thêm lịch sử thất bại',
|
||||
produced: 'Đã tạo',
|
||||
producedOpen: 'Mở trong thanh bên',
|
||||
disconnected: 'Terminal mất kết nối, đang kết nối lại…',
|
||||
exited: 'Tiến trình terminal đã thoát',
|
||||
noSession: 'Chọn một phiên để dùng thanh bên',
|
||||
pluginNotLoaded: 'Plugin chưa tải, tab tạm không khả dụng:',
|
||||
hiddenFiles: 'Tệp ẩn',
|
||||
parent: 'Thư mục cha',
|
||||
copied: 'Đã sao chép',
|
||||
copy: 'Sao chép',
|
||||
newFile: 'Tệp mới',
|
||||
openEditor: 'Mở trình soạn thảo',
|
||||
gitDetail: 'Xem chi tiết thay đổi',
|
||||
referenceFile: '@tệp',
|
||||
addToConversation: 'Thêm vào cuộc trò chuyện',
|
||||
copyRelative: 'Sao chép đường dẫn tương đối',
|
||||
@@ -245,7 +222,6 @@ export const vi: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: 'Toàn quyền kiểm soát: chèn CSS tùy chỉnh (có thể ghi đè style built-in), và chỉ định khoảng dịch chuyển thanh tiêu đề',
|
||||
settingsSchemeDetectedSuffix: 'đã phát hiện',
|
||||
settingsCustomCssTitle: 'CSS tùy chỉnh',
|
||||
settingsCustomCssDesc: 'Style追加 vào cuối trang (cùng ưu tiên thì viết sau thắng; ghi đè biến inline JS cần !important)',
|
||||
settingsCustomCssPlaceholder: '/* vd: dành sẵn 36px cho shell tự vẽ thanh tiêu đề */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'Lưu thất bại',
|
||||
settingsConflict: 'Cài đặt đã bị sửa bởi cửa sổ khác, vui lòng thử lại',
|
||||
@@ -268,7 +244,6 @@ export const vi: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: 'Cỡ chữ terminal',
|
||||
settingsFontSizeDesc: 'Cỡ chữ terminal (9–32, mặc định 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Đường dẫn shell',
|
||||
settingsShellDesc: 'Shell khởi động cho terminal UI và mô hình (đường dẫn tuyệt đối hoặc tên thực thi). Để trống sẽ phân tích theo thứ tự: yaml config.shell → $SHELL / login shell / powershell.exe trên Windows. Áp dụng cho terminal mở sau đó',
|
||||
settingsShellPlaceholder: 'vd: /bin/zsh (để trống = tự động)',
|
||||
@@ -310,19 +285,14 @@ export const vi: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: 'Trang này cấm hiển thị trong trang khác qua X-Frame-Options / frame-ancestors, không thể tải trong thanh bên. Mở trực tiếp trong trình duyệt',
|
||||
browserEmbedAnyway: 'Vẫn tải',
|
||||
subagent: 'Quản lý tác vụ',
|
||||
openSubagent: 'Quản lý tác vụ',
|
||||
subagentMainAgent: 'Tác nhân chính',
|
||||
subagentEmpty: 'Không có tác nhân con',
|
||||
subagentEmptyDesc: 'Tác nhân con do tác nhân chính tạo ra sẽ hiển thị ở đây',
|
||||
subagentRunning: 'Đang chạy',
|
||||
subagentInactive: 'Nghỉ',
|
||||
subagentModeOneShot: 'Một lần',
|
||||
subagentModeContinuable: 'Có thể tiếp tục',
|
||||
subagentCount: '{count} tác nhân con',
|
||||
subagentCountRunning: '{count} tác nhân con · {running} đang chạy',
|
||||
subagentDiagCorrupt: 'Bị hỏng',
|
||||
subagentDiagUnsupported: 'Không hỗ trợ',
|
||||
subagentDiagUnavailable: 'Không khả dụng',
|
||||
subagentThinking: 'Đang suy nghĩ…',
|
||||
sideChat: 'Chat bên (beta)',
|
||||
sideChatNew: 'Luồng mới',
|
||||
@@ -343,10 +313,7 @@ export const vi: Record<string, string> = {
|
||||
sideChatThink: 'Suy nghĩ',
|
||||
sideChatInjection: 'Đã tiêm ngữ cảnh',
|
||||
sideChatSend: 'Gửi',
|
||||
sideChatCancel: 'Dừng',
|
||||
sideChatCancelTitle: 'Hủy vòng hiện tại (giữ hàng đợi)',
|
||||
sideChatClose: 'Đóng luồng',
|
||||
sideChatCloseTitle: 'Giải phóng agent của luồng (lịch sử được giữ)',
|
||||
sideChatError: 'Lỗi chat bên: {message}',
|
||||
sideChatTurnUsage: 'Vào {input} tok · Ra {output} tok',
|
||||
sideChatBlockCollapse: 'Thu gọn',
|
||||
@@ -382,7 +349,6 @@ export const vi: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes}m {seconds}s',
|
||||
jobDurationHours: '{hours}h {minutes}m',
|
||||
jobViewOutput: 'Xem đầu ra',
|
||||
jobHideOutput: 'Ẩn đầu ra',
|
||||
jobNoOutput: 'Chưa có đầu ra',
|
||||
jobNotReadYet: 'Đang chờ mô hình đọc đầu ra tác vụ này (sau khi mô hình chạy job_output, đầu ra sẽ hiển thị ở đây)',
|
||||
jobOutputTruncated: 'Đầu ra quá dài, đã cắt bớt',
|
||||
@@ -400,7 +366,6 @@ export const vi: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: 'Đồ thị nút phân tầng với thu phóng và di chuyển',
|
||||
settingsViewModeTree: 'Cây',
|
||||
settingsViewModeTreeDesc: 'Cây thụt lề cổ điển, điều hướng được bằng bàn phím',
|
||||
tasksWorkflowMember: 'Thành viên quy trình',
|
||||
tasksFoldCompleted: '✓ {count} hoàn thành',
|
||||
tasksFoldExpand: 'Mở rộng các nút đã hoàn thành',
|
||||
tasksFoldCollapse: 'Thu gọn các nút đã hoàn thành',
|
||||
@@ -421,7 +386,6 @@ export const vi: Record<string, string> = {
|
||||
tasksStateError: 'Lỗi',
|
||||
teamBoard: 'Bảng tác vụ nhóm',
|
||||
teamChip: 'Nhóm {members} thành viên · {tasks} tác vụ',
|
||||
teamMembers: 'Thành viên',
|
||||
teamTasksEmpty: 'Chưa có tác vụ dùng chung',
|
||||
teamTaskCreate: 'Tác vụ mới',
|
||||
teamTaskSubject: 'Chủ đề',
|
||||
|
||||
@@ -93,29 +93,16 @@ export const zhHK: Record<string, string> = {
|
||||
openWithSettingsRemove: '刪除',
|
||||
openWithSettingsInvalidHint: '名稱或範本(需含 {path} 且以 scheme:// 開頭)未填寫的編輯器不會出現在選單中',
|
||||
newTab: '新增標籤',
|
||||
openExplorer: '檔案總管',
|
||||
brokenSymlink: '失效的符號連結',
|
||||
openGit: 'Git 面板',
|
||||
newTerminal: '新終端',
|
||||
terminalLimit: '終端數量已達上限 (3)',
|
||||
close: '關閉',
|
||||
closeOtherTabs: '關閉其他標籤',
|
||||
closeLeftTabs: '關閉左側標籤',
|
||||
closeRightTabs: '關閉右側標籤',
|
||||
floatDropHint: '放開以在自由視窗中開啟',
|
||||
dockToSidebar: '返回側邊欄',
|
||||
pinTerminal: '固定終端',
|
||||
pinAgentTerminal: '固定 Agent 終端',
|
||||
pinToWorkspace: '固定到工作區',
|
||||
pinToGlobal: '固定到全域',
|
||||
unpinTerminal: '取消固定',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'UI 終端',
|
||||
pinnedTerminalKindAgent: 'Agent 終端',
|
||||
pinnedTerminalScopeWorkspace: '固定到工作區',
|
||||
pinnedTerminalScopeGlobal: '固定到全域',
|
||||
pinnedRailLabel: '固定終端',
|
||||
closePinnedTerminal: '關閉終端',
|
||||
collapseBottomPanel: '收起底部面板',
|
||||
expandBottomPanel: '展開底部面板',
|
||||
terminalError: '終端連線失敗',
|
||||
@@ -147,10 +134,6 @@ export const zhHK: Record<string, string> = {
|
||||
loading: '載入中…',
|
||||
error: '載入失敗',
|
||||
retry: '重試',
|
||||
splitLeft: '向左分欄',
|
||||
splitRight: '向右分欄',
|
||||
splitUp: '向上分欄',
|
||||
splitDown: '向下分欄',
|
||||
notRepo: '目前目錄不是 git 倉庫',
|
||||
noChanges: '沒有變更',
|
||||
statusTruncated: '變更過多,僅顯示前 2000 條',
|
||||
@@ -160,7 +143,6 @@ export const zhHK: Record<string, string> = {
|
||||
unstageAll: '全部取消暫存',
|
||||
commitPlaceholder: '提交訊息 (Ctrl+Enter)',
|
||||
commit: '提交',
|
||||
commitError: '提交失敗',
|
||||
branch: '分支',
|
||||
worktree: '工作樹',
|
||||
checkoutError: '切換分支失敗',
|
||||
@@ -184,7 +166,6 @@ export const zhHK: Record<string, string> = {
|
||||
diffDeleted: '刪除',
|
||||
diffRenamed: '重新命名',
|
||||
diffExpand: '展開其餘 {count} 行',
|
||||
diffCollapse: '收起',
|
||||
discard: '放棄變更',
|
||||
discardTitle: '放棄變更',
|
||||
discardDesc: '將丟棄「{path}」的工作區修改(不可復原)。',
|
||||
@@ -205,18 +186,14 @@ export const zhHK: Record<string, string> = {
|
||||
loadMore: '載入更多',
|
||||
historyLoadError: '載入更多歷史失敗',
|
||||
produced: '本次產出',
|
||||
producedOpen: '在側邊欄中開啟',
|
||||
disconnected: '終端連線斷開,重新連線中…',
|
||||
exited: '終端程序已退出',
|
||||
noSession: '選擇一個工作階段以使用側邊欄',
|
||||
pluginNotLoaded: '插件未載入,標籤暫不可用:',
|
||||
hiddenFiles: '隱藏檔案',
|
||||
parent: '上層目錄',
|
||||
copied: '已複製',
|
||||
copy: '複製',
|
||||
newFile: '新檔案',
|
||||
openEditor: '開啟編輯器',
|
||||
gitDetail: '檢視變更詳情',
|
||||
referenceFile: '@檔案',
|
||||
addToConversation: '新增到對話',
|
||||
copyRelative: '複製相對位址',
|
||||
@@ -260,7 +237,6 @@ export const zhHK: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: '完全由你控制:注入自訂 CSS(可覆寫內建樣式),並指定標題欄下移距離',
|
||||
settingsSchemeDetectedSuffix: '已偵測',
|
||||
settingsCustomCssTitle: '自訂 CSS',
|
||||
settingsCustomCssDesc: '附加到頁面末尾的樣式(同優先級下後寫勝出;覆寫 JS 內聯變數需用 !important)',
|
||||
settingsCustomCssPlaceholder: '/* 例:為自繪標題欄的殼預留 36px */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: '儲存失敗',
|
||||
settingsConflict: '設定已被其他視窗修改,請重試',
|
||||
@@ -283,7 +259,6 @@ export const zhHK: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: '終端字型大小',
|
||||
settingsFontSizeDesc: '終端字型大小(9–32,預設 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Shell 路徑',
|
||||
settingsShellDesc: 'UI 與模型終端啟動的 shell(絕對路徑或可執行名)。留空按既有順序解析:yaml 的 config.shell → $SHELL / 登入 shell / Windows 的 powershell.exe。對之後開啟的終端生效',
|
||||
settingsShellPlaceholder: '如 /bin/zsh(留空自動解析)',
|
||||
@@ -325,19 +300,14 @@ export const zhHK: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: '該網站透過 X-Frame-Options / frame-ancestors 禁止在其它頁面中顯示,無法在側邊欄內載入。可在瀏覽器中直接開啟',
|
||||
browserEmbedAnyway: '仍然載入',
|
||||
subagent: '任務管理',
|
||||
openSubagent: '任務管理',
|
||||
subagentMainAgent: '主代理',
|
||||
subagentEmpty: '暫無子代理',
|
||||
subagentEmptyDesc: '目前主代理派生的子代理將顯示在這裡',
|
||||
subagentRunning: '執行中',
|
||||
subagentInactive: '閒置',
|
||||
subagentModeOneShot: '一次性',
|
||||
subagentModeContinuable: '可續接',
|
||||
subagentCount: '{count} 個子代理',
|
||||
subagentCountRunning: '{count} 個子代理 · {running} 執行中',
|
||||
subagentDiagCorrupt: '目錄損壞',
|
||||
subagentDiagUnsupported: '不支援的條目',
|
||||
subagentDiagUnavailable: '不可用',
|
||||
subagentThinking: '思考中…',
|
||||
sideChat: '側邊對話(beta)',
|
||||
sideChatNew: '新增對話',
|
||||
@@ -358,10 +328,7 @@ export const zhHK: Record<string, string> = {
|
||||
sideChatThink: '思考過程',
|
||||
sideChatInjection: '已注入上下文',
|
||||
sideChatSend: '發送',
|
||||
sideChatCancel: '停止',
|
||||
sideChatCancelTitle: '中止目前回合(保留佇列)',
|
||||
sideChatClose: '關閉執行緒',
|
||||
sideChatCloseTitle: '釋放執行緒的 agent(歷史保留)',
|
||||
sideChatError: '側邊對話出錯:{message}',
|
||||
sideChatTurnUsage: '輸入 {input} tok · 輸出 {output} tok',
|
||||
sideChatBlockCollapse: '收起',
|
||||
@@ -397,7 +364,6 @@ export const zhHK: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes} 分 {seconds} 秒',
|
||||
jobDurationHours: '{hours} 小時 {minutes} 分',
|
||||
jobViewOutput: '檢視輸出',
|
||||
jobHideOutput: '收起輸出',
|
||||
jobNoOutput: '暫無輸出',
|
||||
jobNotReadYet: '等待模型讀取該任務的輸出(模型執行 job_output 後,輸出會顯示在這裡)',
|
||||
jobOutputTruncated: '輸出過長,已截斷顯示',
|
||||
@@ -415,7 +381,6 @@ export const zhHK: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: '分層節點圖,可縮放平移',
|
||||
settingsViewModeTree: '樹狀圖',
|
||||
settingsViewModeTreeDesc: '經典縮排樹,可用鍵盤導航',
|
||||
tasksWorkflowMember: '工作流成員',
|
||||
tasksFoldCompleted: '✓ {count} 已完成',
|
||||
tasksFoldExpand: '展開已完成的節點',
|
||||
tasksFoldCollapse: '收起已完成的節點',
|
||||
@@ -436,7 +401,6 @@ export const zhHK: Record<string, string> = {
|
||||
tasksStateError: '出錯',
|
||||
teamBoard: '團隊任務板',
|
||||
teamChip: '團隊 {members} 成員 · {tasks} 任務',
|
||||
teamMembers: '成員',
|
||||
teamTasksEmpty: '暫無共用任務',
|
||||
teamTaskCreate: '新增任務',
|
||||
teamTaskSubject: '標題',
|
||||
|
||||
@@ -93,29 +93,16 @@ export const zhMO: Record<string, string> = {
|
||||
openWithSettingsRemove: '刪除',
|
||||
openWithSettingsInvalidHint: '名稱或範本(需含 {path} 且以 scheme:// 開頭)未填寫的編輯器不會出現在選單中',
|
||||
newTab: '新增標籤',
|
||||
openExplorer: '檔案總管',
|
||||
brokenSymlink: '失效的符號連結',
|
||||
openGit: 'Git 面板',
|
||||
newTerminal: '新終端',
|
||||
terminalLimit: '終端數量已達上限 (3)',
|
||||
close: '關閉',
|
||||
closeOtherTabs: '關閉其他標籤',
|
||||
closeLeftTabs: '關閉左側標籤',
|
||||
closeRightTabs: '關閉右側標籤',
|
||||
floatDropHint: '放開以在自由視窗中開啟',
|
||||
dockToSidebar: '返回側邊欄',
|
||||
pinTerminal: '固定終端',
|
||||
pinAgentTerminal: '固定 Agent 終端',
|
||||
pinToWorkspace: '固定到工作區',
|
||||
pinToGlobal: '固定到全域',
|
||||
unpinTerminal: '取消固定',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'UI 終端',
|
||||
pinnedTerminalKindAgent: 'Agent 終端',
|
||||
pinnedTerminalScopeWorkspace: '固定到工作區',
|
||||
pinnedTerminalScopeGlobal: '固定到全域',
|
||||
pinnedRailLabel: '固定終端',
|
||||
closePinnedTerminal: '關閉終端',
|
||||
collapseBottomPanel: '收起底部面板',
|
||||
expandBottomPanel: '展開底部面板',
|
||||
terminalError: '終端連線失敗',
|
||||
@@ -147,10 +134,6 @@ export const zhMO: Record<string, string> = {
|
||||
loading: '載入中…',
|
||||
error: '載入失敗',
|
||||
retry: '重試',
|
||||
splitLeft: '向左分欄',
|
||||
splitRight: '向右分欄',
|
||||
splitUp: '向上分欄',
|
||||
splitDown: '向下分欄',
|
||||
notRepo: '目前目錄不是 git 倉庫',
|
||||
noChanges: '沒有變更',
|
||||
statusTruncated: '變更過多,僅顯示前 2000 條',
|
||||
@@ -160,7 +143,6 @@ export const zhMO: Record<string, string> = {
|
||||
unstageAll: '全部取消暫存',
|
||||
commitPlaceholder: '提交訊息 (Ctrl+Enter)',
|
||||
commit: '提交',
|
||||
commitError: '提交失敗',
|
||||
branch: '分支',
|
||||
worktree: '工作樹',
|
||||
checkoutError: '切換分支失敗',
|
||||
@@ -184,7 +166,6 @@ export const zhMO: Record<string, string> = {
|
||||
diffDeleted: '刪除',
|
||||
diffRenamed: '重新命名',
|
||||
diffExpand: '展開其餘 {count} 行',
|
||||
diffCollapse: '收起',
|
||||
discard: '放棄變更',
|
||||
discardTitle: '放棄變更',
|
||||
discardDesc: '將丟棄「{path}」的工作區修改(不可復原)。',
|
||||
@@ -205,18 +186,14 @@ export const zhMO: Record<string, string> = {
|
||||
loadMore: '載入更多',
|
||||
historyLoadError: '載入更多歷史失敗',
|
||||
produced: '本次產出',
|
||||
producedOpen: '在側邊欄中開啟',
|
||||
disconnected: '終端連線斷開,重新連線中…',
|
||||
exited: '終端程序已退出',
|
||||
noSession: '選擇一個工作階段以使用側邊欄',
|
||||
pluginNotLoaded: '插件未載入,標籤暫不可用:',
|
||||
hiddenFiles: '隱藏檔案',
|
||||
parent: '上層目錄',
|
||||
copied: '已複製',
|
||||
copy: '複製',
|
||||
newFile: '新檔案',
|
||||
openEditor: '開啟編輯器',
|
||||
gitDetail: '檢視變更詳情',
|
||||
referenceFile: '@檔案',
|
||||
addToConversation: '新增到對話',
|
||||
copyRelative: '複製相對位址',
|
||||
@@ -260,7 +237,6 @@ export const zhMO: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: '完全由你控制:注入自訂 CSS(可覆寫內建樣式),並指定標題欄下移距離',
|
||||
settingsSchemeDetectedSuffix: '已偵測',
|
||||
settingsCustomCssTitle: '自訂 CSS',
|
||||
settingsCustomCssDesc: '附加到頁面末尾的樣式(同優先級下後寫勝出;覆寫 JS 內聯變數需用 !important)',
|
||||
settingsCustomCssPlaceholder: '/* 例:為自繪標題欄的殼預留 36px */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: '儲存失敗',
|
||||
settingsConflict: '設定已被其他視窗修改,請重試',
|
||||
@@ -283,7 +259,6 @@ export const zhMO: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: '終端字型大小',
|
||||
settingsFontSizeDesc: '終端字型大小(9–32,預設 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Shell 路徑',
|
||||
settingsShellDesc: 'UI 與模型終端啟動的 shell(絕對路徑或可執行名)。留空按既有順序解析:yaml 的 config.shell → $SHELL / 登入 shell / Windows 的 powershell.exe。對之後開啟的終端生效',
|
||||
settingsShellPlaceholder: '如 /bin/zsh(留空自動解析)',
|
||||
@@ -325,19 +300,14 @@ export const zhMO: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: '該網站透過 X-Frame-Options / frame-ancestors 禁止在其它頁面中顯示,無法在側邊欄內載入。可在瀏覽器中直接開啟',
|
||||
browserEmbedAnyway: '仍然載入',
|
||||
subagent: '任務管理',
|
||||
openSubagent: '任務管理',
|
||||
subagentMainAgent: '主代理',
|
||||
subagentEmpty: '暫無子代理',
|
||||
subagentEmptyDesc: '目前主代理派生的子代理將顯示在這裡',
|
||||
subagentRunning: '執行中',
|
||||
subagentInactive: '閒置',
|
||||
subagentModeOneShot: '一次性',
|
||||
subagentModeContinuable: '可續接',
|
||||
subagentCount: '{count} 個子代理',
|
||||
subagentCountRunning: '{count} 個子代理 · {running} 執行中',
|
||||
subagentDiagCorrupt: '目錄損壞',
|
||||
subagentDiagUnsupported: '不支援的條目',
|
||||
subagentDiagUnavailable: '不可用',
|
||||
subagentThinking: '思考中…',
|
||||
sideChat: '側邊對話(beta)',
|
||||
sideChatNew: '新增對話',
|
||||
@@ -358,10 +328,7 @@ export const zhMO: Record<string, string> = {
|
||||
sideChatThink: '思考過程',
|
||||
sideChatInjection: '已注入上下文',
|
||||
sideChatSend: '發送',
|
||||
sideChatCancel: '停止',
|
||||
sideChatCancelTitle: '中止目前回合(保留佇列)',
|
||||
sideChatClose: '關閉執行緒',
|
||||
sideChatCloseTitle: '釋放執行緒的 agent(歷史保留)',
|
||||
sideChatError: '側邊對話出錯:{message}',
|
||||
sideChatTurnUsage: '輸入 {input} tok · 輸出 {output} tok',
|
||||
sideChatBlockCollapse: '收起',
|
||||
@@ -397,7 +364,6 @@ export const zhMO: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes} 分 {seconds} 秒',
|
||||
jobDurationHours: '{hours} 小時 {minutes} 分',
|
||||
jobViewOutput: '檢視輸出',
|
||||
jobHideOutput: '收起輸出',
|
||||
jobNoOutput: '暫無輸出',
|
||||
jobNotReadYet: '等待模型讀取該任務的輸出(模型執行 job_output 後,輸出會顯示在這裡)',
|
||||
jobOutputTruncated: '輸出過長,已截斷顯示',
|
||||
@@ -415,7 +381,6 @@ export const zhMO: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: '分層節點圖,可縮放平移',
|
||||
settingsViewModeTree: '樹狀圖',
|
||||
settingsViewModeTreeDesc: '經典縮排樹,可用鍵盤導航',
|
||||
tasksWorkflowMember: '工作流成員',
|
||||
tasksFoldCompleted: '✓ {count} 已完成',
|
||||
tasksFoldExpand: '展開已完成的節點',
|
||||
tasksFoldCollapse: '收起已完成的節點',
|
||||
@@ -436,7 +401,6 @@ export const zhMO: Record<string, string> = {
|
||||
tasksStateError: '出錯',
|
||||
teamBoard: '團隊任務板',
|
||||
teamChip: '團隊 {members} 成員 · {tasks} 任務',
|
||||
teamMembers: '成員',
|
||||
teamTasksEmpty: '暫無共用任務',
|
||||
teamTaskCreate: '新增任務',
|
||||
teamTaskSubject: '標題',
|
||||
|
||||
@@ -93,29 +93,16 @@ export const zhTW: Record<string, string> = {
|
||||
openWithSettingsRemove: '刪除',
|
||||
openWithSettingsInvalidHint: '名稱或範本(需含 {path} 且以 scheme:// 開頭)未填寫的編輯器不會出現在選單中',
|
||||
newTab: '新增標籤',
|
||||
openExplorer: '檔案總管',
|
||||
brokenSymlink: '失效的符號連結',
|
||||
openGit: 'Git 面板',
|
||||
newTerminal: '新終端',
|
||||
terminalLimit: '終端數量已達上限 (3)',
|
||||
close: '關閉',
|
||||
closeOtherTabs: '關閉其他標籤',
|
||||
closeLeftTabs: '關閉左側標籤',
|
||||
closeRightTabs: '關閉右側標籤',
|
||||
floatDropHint: '放開以在自由視窗中開啟',
|
||||
dockToSidebar: '返回側邊欄',
|
||||
pinTerminal: '固定終端',
|
||||
pinAgentTerminal: '固定 Agent 終端',
|
||||
pinToWorkspace: '固定到工作區',
|
||||
pinToGlobal: '固定到全域',
|
||||
unpinTerminal: '取消固定',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'UI 終端',
|
||||
pinnedTerminalKindAgent: 'Agent 終端',
|
||||
pinnedTerminalScopeWorkspace: '固定到工作區',
|
||||
pinnedTerminalScopeGlobal: '固定到全域',
|
||||
pinnedRailLabel: '固定終端',
|
||||
closePinnedTerminal: '關閉終端',
|
||||
collapseBottomPanel: '收起底部面板',
|
||||
expandBottomPanel: '展開底部面板',
|
||||
terminalError: '終端連線失敗',
|
||||
@@ -147,10 +134,6 @@ export const zhTW: Record<string, string> = {
|
||||
loading: '載入中…',
|
||||
error: '載入失敗',
|
||||
retry: '重試',
|
||||
splitLeft: '向左分欄',
|
||||
splitRight: '向右分欄',
|
||||
splitUp: '向上分欄',
|
||||
splitDown: '向下分欄',
|
||||
notRepo: '目前目錄不是 git 倉庫',
|
||||
noChanges: '沒有變更',
|
||||
statusTruncated: '變更過多,僅顯示前 2000 條',
|
||||
@@ -160,7 +143,6 @@ export const zhTW: Record<string, string> = {
|
||||
unstageAll: '全部取消暫存',
|
||||
commitPlaceholder: '提交訊息 (Ctrl+Enter)',
|
||||
commit: '提交',
|
||||
commitError: '提交失敗',
|
||||
branch: '分支',
|
||||
worktree: '工作樹',
|
||||
checkoutError: '切換分支失敗',
|
||||
@@ -184,7 +166,6 @@ export const zhTW: Record<string, string> = {
|
||||
diffDeleted: '刪除',
|
||||
diffRenamed: '重新命名',
|
||||
diffExpand: '展開其餘 {count} 行',
|
||||
diffCollapse: '收起',
|
||||
discard: '放棄變更',
|
||||
discardTitle: '放棄變更',
|
||||
discardDesc: '將丟棄「{path}」的工作區修改(不可復原)。',
|
||||
@@ -205,18 +186,14 @@ export const zhTW: Record<string, string> = {
|
||||
loadMore: '載入更多',
|
||||
historyLoadError: '載入更多歷史失敗',
|
||||
produced: '本次產出',
|
||||
producedOpen: '在側邊欄中開啟',
|
||||
disconnected: '終端連線斷開,重新連線中…',
|
||||
exited: '終端程序已退出',
|
||||
noSession: '選擇一個工作階段以使用側邊欄',
|
||||
pluginNotLoaded: '插件未載入,標籤暫不可用:',
|
||||
hiddenFiles: '隱藏檔案',
|
||||
parent: '上層目錄',
|
||||
copied: '已複製',
|
||||
copy: '複製',
|
||||
newFile: '新檔案',
|
||||
openEditor: '開啟編輯器',
|
||||
gitDetail: '檢視變更詳情',
|
||||
referenceFile: '@檔案',
|
||||
addToConversation: '新增到對話',
|
||||
copyRelative: '複製相對位址',
|
||||
@@ -260,7 +237,6 @@ export const zhTW: Record<string, string> = {
|
||||
settingsSchemeCustomDesc: '完全由你控制:注入自訂 CSS(可覆寫內建樣式),並指定標題欄下移距離',
|
||||
settingsSchemeDetectedSuffix: '已偵測',
|
||||
settingsCustomCssTitle: '自訂 CSS',
|
||||
settingsCustomCssDesc: '附加到頁面末尾的樣式(同優先級下後寫勝出;覆寫 JS 內聯變數需用 !important)',
|
||||
settingsCustomCssPlaceholder: '/* 例:為自繪標題欄的殼預留 36px */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: '儲存失敗',
|
||||
settingsConflict: '設定已被其他視窗修改,請重試',
|
||||
@@ -283,7 +259,6 @@ export const zhTW: Record<string, string> = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: '終端字型大小',
|
||||
settingsFontSizeDesc: '終端字型大小(9–32,預設 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Shell 路徑',
|
||||
settingsShellDesc: 'UI 與模型終端啟動的 shell(絕對路徑或可執行名)。留空按既有順序解析:yaml 的 config.shell → $SHELL / 登入 shell / Windows 的 powershell.exe。對之後開啟的終端生效',
|
||||
settingsShellPlaceholder: '如 /bin/zsh(留空自動解析)',
|
||||
@@ -325,19 +300,14 @@ export const zhTW: Record<string, string> = {
|
||||
browserEmbedBlockedDesc: '該網站透過 X-Frame-Options / frame-ancestors 禁止在其它頁面中顯示,無法在側邊欄內載入。可在瀏覽器中直接開啟',
|
||||
browserEmbedAnyway: '仍然載入',
|
||||
subagent: '任務管理',
|
||||
openSubagent: '任務管理',
|
||||
subagentMainAgent: '主代理',
|
||||
subagentEmpty: '暫無子代理',
|
||||
subagentEmptyDesc: '目前主代理派生的子代理將顯示在這裡',
|
||||
subagentRunning: '執行中',
|
||||
subagentInactive: '閒置',
|
||||
subagentModeOneShot: '一次性',
|
||||
subagentModeContinuable: '可續接',
|
||||
subagentCount: '{count} 個子代理',
|
||||
subagentCountRunning: '{count} 個子代理 · {running} 執行中',
|
||||
subagentDiagCorrupt: '目錄損壞',
|
||||
subagentDiagUnsupported: '不支援的條目',
|
||||
subagentDiagUnavailable: '不可用',
|
||||
subagentThinking: '思考中…',
|
||||
sideChat: '側邊對話(beta)',
|
||||
sideChatNew: '新增對話',
|
||||
@@ -358,10 +328,7 @@ export const zhTW: Record<string, string> = {
|
||||
sideChatThink: '思考過程',
|
||||
sideChatInjection: '已注入上下文',
|
||||
sideChatSend: '發送',
|
||||
sideChatCancel: '停止',
|
||||
sideChatCancelTitle: '中止目前回合(保留佇列)',
|
||||
sideChatClose: '關閉執行緒',
|
||||
sideChatCloseTitle: '釋放執行緒的 agent(歷史保留)',
|
||||
sideChatError: '側邊對話出錯:{message}',
|
||||
sideChatTurnUsage: '輸入 {input} tok · 輸出 {output} tok',
|
||||
sideChatBlockCollapse: '收起',
|
||||
@@ -397,7 +364,6 @@ export const zhTW: Record<string, string> = {
|
||||
jobDurationMinutes: '{minutes} 分 {seconds} 秒',
|
||||
jobDurationHours: '{hours} 小時 {minutes} 分',
|
||||
jobViewOutput: '檢視輸出',
|
||||
jobHideOutput: '收起輸出',
|
||||
jobNoOutput: '暫無輸出',
|
||||
jobNotReadYet: '等待模型讀取該任務的輸出(模型執行 job_output 後,輸出會顯示在這裡)',
|
||||
jobOutputTruncated: '輸出過長,已截斷顯示',
|
||||
@@ -415,7 +381,6 @@ export const zhTW: Record<string, string> = {
|
||||
settingsViewModeGraphDesc: '分層節點圖,可縮放平移',
|
||||
settingsViewModeTree: '樹狀圖',
|
||||
settingsViewModeTreeDesc: '經典縮排樹,可用鍵盤導航',
|
||||
tasksWorkflowMember: '工作流成員',
|
||||
tasksFoldCompleted: '✓ {count} 已完成',
|
||||
tasksFoldExpand: '展開已完成的節點',
|
||||
tasksFoldCollapse: '收起已完成的節點',
|
||||
@@ -436,7 +401,6 @@ export const zhTW: Record<string, string> = {
|
||||
tasksStateError: '出錯',
|
||||
teamBoard: '團隊任務板',
|
||||
teamChip: '團隊 {members} 成員 · {tasks} 任務',
|
||||
teamMembers: '成員',
|
||||
teamTasksEmpty: '暫無共用任務',
|
||||
teamTaskCreate: '新增任務',
|
||||
teamTaskSubject: '標題',
|
||||
|
||||
@@ -90,29 +90,16 @@ export const zh = {
|
||||
openWithSettingsRemove: '删除',
|
||||
openWithSettingsInvalidHint: '名称或模板(需含 {path} 且以 scheme:// 开头)未填写的编辑器不会出现在菜单中',
|
||||
newTab: '新建标签页',
|
||||
openExplorer: '资源管理器',
|
||||
brokenSymlink: '失效的软链接',
|
||||
openGit: 'Git 面板',
|
||||
newTerminal: '新终端',
|
||||
terminalLimit: '终端数量已达上限 (3)',
|
||||
close: '关闭',
|
||||
closeOtherTabs: '关闭其他页签',
|
||||
closeLeftTabs: '关闭左侧页签',
|
||||
closeRightTabs: '关闭右侧页签',
|
||||
floatDropHint: '松开以在自由窗口中打开',
|
||||
dockToSidebar: '回到侧边栏',
|
||||
pinTerminal: '固定终端',
|
||||
pinAgentTerminal: '固定 Agent 终端',
|
||||
pinToWorkspace: '固定到工作区',
|
||||
pinToGlobal: '固定到全局',
|
||||
unpinTerminal: '取消固定',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'UI 终端',
|
||||
pinnedTerminalKindAgent: 'Agent 终端',
|
||||
pinnedTerminalScopeWorkspace: '固定到工作区',
|
||||
pinnedTerminalScopeGlobal: '固定到全局',
|
||||
pinnedRailLabel: '固定终端',
|
||||
closePinnedTerminal: '关闭终端',
|
||||
collapseBottomPanel: '折叠底部面板',
|
||||
expandBottomPanel: '展开底部面板',
|
||||
terminalError: '终端连接失败',
|
||||
@@ -143,10 +130,6 @@ export const zh = {
|
||||
loading: '加载中…',
|
||||
error: '加载失败',
|
||||
retry: '重试',
|
||||
splitLeft: '向左分栏',
|
||||
splitRight: '向右分栏',
|
||||
splitUp: '向上分栏',
|
||||
splitDown: '向下分栏',
|
||||
notRepo: '当前目录不是 git 仓库',
|
||||
noChanges: '没有变更',
|
||||
statusTruncated: '变更过多,仅显示前 2000 条',
|
||||
@@ -156,7 +139,6 @@ export const zh = {
|
||||
unstageAll: '全部取消暂存',
|
||||
commitPlaceholder: '提交信息 (Ctrl+Enter)',
|
||||
commit: '提交',
|
||||
commitError: '提交失败',
|
||||
branch: '分支',
|
||||
worktree: '工作树',
|
||||
checkoutError: '切换分支失败',
|
||||
@@ -180,7 +162,6 @@ export const zh = {
|
||||
diffDeleted: '删除',
|
||||
diffRenamed: '重命名',
|
||||
diffExpand: '展开其余 {count} 行',
|
||||
diffCollapse: '收起',
|
||||
discard: '放弃更改',
|
||||
discardTitle: '放弃更改',
|
||||
discardDesc: '将丢弃「{path}」的工作区修改(不可恢复)。',
|
||||
@@ -201,19 +182,15 @@ export const zh = {
|
||||
loadMore: '加载更多',
|
||||
historyLoadError: '加载更多历史失败',
|
||||
produced: '本次产出',
|
||||
producedOpen: '在侧边栏中打开',
|
||||
showInFolder: '在文件夹中显示',
|
||||
disconnected: '终端连接断开,重连中…',
|
||||
exited: '终端进程已退出',
|
||||
noSession: '选择一个会话以使用侧边栏',
|
||||
pluginNotLoaded: '插件未加载,标签页暂不可用:',
|
||||
hiddenFiles: '隐藏文件',
|
||||
parent: '上级目录',
|
||||
copied: '已复制',
|
||||
copy: '复制',
|
||||
newFile: '新文件',
|
||||
openEditor: '打开编辑器',
|
||||
gitDetail: '查看变更详情',
|
||||
referenceFile: '@文件',
|
||||
addToConversation: '添加到对话',
|
||||
copyRelative: '复制相对地址',
|
||||
@@ -257,7 +234,6 @@ export const zh = {
|
||||
settingsSchemeCustomDesc: '完全由你控制:注入自定义 CSS(可覆盖内置样式),并指定标题栏下移距离',
|
||||
settingsSchemeDetectedSuffix: '已检测',
|
||||
settingsCustomCssTitle: '自定义 CSS',
|
||||
settingsCustomCssDesc: '追加到页面末尾的样式(同优先级下后写胜出;覆盖 JS 内联变量需用 !important)',
|
||||
settingsCustomCssPlaceholder: '/* 例:为自绘标题栏的壳预留 36px */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: '保存失败',
|
||||
settingsConflict: '设置已被其他窗口修改,请重试',
|
||||
@@ -280,7 +256,6 @@ export const zh = {
|
||||
settingsFontFamilyPlaceholder: '"JetBrains Mono", monospace',
|
||||
settingsFontSizeTitle: '终端字号',
|
||||
settingsFontSizeDesc: '终端字号(9–32,默认 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsShellTitle: 'Shell 路径',
|
||||
settingsShellDesc: 'UI 与模型终端启动的 shell(绝对路径或可执行名)。留空按既有顺序解析:yaml 的 config.shell → $SHELL / 登录 shell / Windows 的 powershell.exe。对之后打开的终端生效',
|
||||
settingsShellPlaceholder: '如 /bin/zsh(留空自动解析)',
|
||||
@@ -322,19 +297,14 @@ export const zh = {
|
||||
browserEmbedBlockedDesc: '该站点通过 X-Frame-Options / frame-ancestors 禁止在其它页面中显示,无法在侧边栏内加载。可在浏览器中直接打开',
|
||||
browserEmbedAnyway: '仍然加载',
|
||||
subagent: '任务管理',
|
||||
openSubagent: '任务管理',
|
||||
subagentMainAgent: '主代理',
|
||||
subagentEmpty: '暂无子代理',
|
||||
subagentEmptyDesc: '当前主代理派生的子代理将显示在这里',
|
||||
subagentRunning: '运行中',
|
||||
subagentInactive: '空闲',
|
||||
subagentModeOneShot: '一次性',
|
||||
subagentModeContinuable: '可续接',
|
||||
subagentCount: '{count} 个子代理',
|
||||
subagentCountRunning: '{count} 个子代理 · {running} 运行中',
|
||||
subagentDiagCorrupt: '目录损坏',
|
||||
subagentDiagUnsupported: '不支持的条目',
|
||||
subagentDiagUnavailable: '不可用',
|
||||
subagentThinking: '思考中…',
|
||||
sideChat: '侧边对话(beta)',
|
||||
sideChatNew: '新建对话',
|
||||
@@ -355,10 +325,7 @@ export const zh = {
|
||||
sideChatThink: '思考过程',
|
||||
sideChatInjection: '已注入上下文',
|
||||
sideChatSend: '发送',
|
||||
sideChatCancel: '停止',
|
||||
sideChatCancelTitle: '中止当前回合(保留队列)',
|
||||
sideChatClose: '关闭线程',
|
||||
sideChatCloseTitle: '释放线程的 agent(历史保留)',
|
||||
sideChatError: '侧边对话出错:{message}',
|
||||
sideChatTurnUsage: '输入 {input} tok · 输出 {output} tok',
|
||||
sideChatBlockCollapse: '收起',
|
||||
@@ -394,7 +361,6 @@ export const zh = {
|
||||
jobDurationMinutes: '{minutes} 分 {seconds} 秒',
|
||||
jobDurationHours: '{hours} 小时 {minutes} 分',
|
||||
jobViewOutput: '查看输出',
|
||||
jobHideOutput: '收起输出',
|
||||
jobNoOutput: '暂无输出',
|
||||
jobNotReadYet: '等待模型读取该任务的输出(模型执行 job_output 后,输出会显示在这里)',
|
||||
jobOutputTruncated: '输出过长,已截断显示',
|
||||
@@ -412,7 +378,6 @@ export const zh = {
|
||||
settingsViewModeGraphDesc: '分层节点图,可缩放平移',
|
||||
settingsViewModeTree: '树状图',
|
||||
settingsViewModeTreeDesc: '经典缩进树,键盘可导航',
|
||||
tasksWorkflowMember: '工作流成员',
|
||||
tasksFoldCompleted: '✓ {count} 已完成',
|
||||
tasksFoldExpand: '展开已完成的节点',
|
||||
tasksFoldCollapse: '折叠已完成的节点',
|
||||
@@ -433,7 +398,6 @@ export const zh = {
|
||||
tasksStateError: '出错',
|
||||
teamBoard: '团队任务板',
|
||||
teamChip: '团队 {members} 成员 · {tasks} 任务',
|
||||
teamMembers: '成员',
|
||||
teamTasksEmpty: '暂无共享任务',
|
||||
teamTaskCreate: '新建任务',
|
||||
teamTaskSubject: '标题',
|
||||
@@ -597,29 +561,16 @@ export const en: Record<keyof typeof zh, string> = {
|
||||
openWithSettingsRemove: 'Remove',
|
||||
openWithSettingsInvalidHint: 'Editors with a missing name or a template without {path} / scheme:// are not shown in the menu',
|
||||
newTab: 'New tab',
|
||||
openExplorer: 'Explorer',
|
||||
brokenSymlink: 'Broken symlink',
|
||||
openGit: 'Git panel',
|
||||
newTerminal: 'New terminal',
|
||||
terminalLimit: 'Terminal limit reached (3)',
|
||||
close: 'Close',
|
||||
closeOtherTabs: 'Close Other Tabs',
|
||||
closeLeftTabs: 'Close Tabs to the Left',
|
||||
closeRightTabs: 'Close Tabs to the Right',
|
||||
floatDropHint: 'Release to open in a free window',
|
||||
dockToSidebar: 'Dock Back to Sidebar',
|
||||
pinTerminal: 'Pin Terminal',
|
||||
pinAgentTerminal: 'Pin Agent Terminal',
|
||||
pinToWorkspace: 'Pin to Workspace',
|
||||
pinToGlobal: 'Pin Globally',
|
||||
unpinTerminal: 'Unpin',
|
||||
pinnedTerminalTooltip: '{kind} · {scope} · {cwd}',
|
||||
pinnedTerminalKindUi: 'UI Terminal',
|
||||
pinnedTerminalKindAgent: 'Agent Terminal',
|
||||
pinnedTerminalScopeWorkspace: 'Pinned to workspace',
|
||||
pinnedTerminalScopeGlobal: 'Pinned globally',
|
||||
pinnedRailLabel: 'Pinned Terminals',
|
||||
closePinnedTerminal: 'Close Terminal',
|
||||
collapseBottomPanel: 'Collapse bottom panel',
|
||||
expandBottomPanel: 'Expand bottom panel',
|
||||
terminalError: 'Terminal connection failed',
|
||||
@@ -650,10 +601,6 @@ export const en: Record<keyof typeof zh, string> = {
|
||||
loading: 'Loading…',
|
||||
error: 'Failed to load',
|
||||
retry: 'Retry',
|
||||
splitLeft: 'Split left',
|
||||
splitRight: 'Split right',
|
||||
splitUp: 'Split up',
|
||||
splitDown: 'Split down',
|
||||
notRepo: 'This directory is not a git repository',
|
||||
noChanges: 'No changes',
|
||||
statusTruncated: 'Too many changes; showing the first 2,000 entries',
|
||||
@@ -663,7 +610,6 @@ export const en: Record<keyof typeof zh, string> = {
|
||||
unstageAll: 'Unstage all',
|
||||
commitPlaceholder: 'Commit message (Ctrl+Enter)',
|
||||
commit: 'Commit',
|
||||
commitError: 'Commit failed',
|
||||
branch: 'Branch',
|
||||
worktree: 'Worktree',
|
||||
checkoutError: 'Branch switch failed',
|
||||
@@ -687,7 +633,6 @@ export const en: Record<keyof typeof zh, string> = {
|
||||
diffDeleted: 'Deleted',
|
||||
diffRenamed: 'Renamed',
|
||||
diffExpand: 'Expand {count} more rows',
|
||||
diffCollapse: 'Collapse',
|
||||
discard: 'Discard changes',
|
||||
discardTitle: 'Discard changes',
|
||||
discardDesc: 'This discards the worktree changes of "{path}" (not recoverable).',
|
||||
@@ -708,19 +653,15 @@ export const en: Record<keyof typeof zh, string> = {
|
||||
loadMore: 'Load more',
|
||||
historyLoadError: 'Failed to load more history',
|
||||
produced: 'Produced',
|
||||
producedOpen: 'Open in sidebar',
|
||||
showInFolder: 'Show in folder',
|
||||
disconnected: 'Terminal disconnected, reconnecting…',
|
||||
exited: 'Terminal process exited',
|
||||
noSession: 'Select a conversation to use the sidebar',
|
||||
pluginNotLoaded: 'Plugin not loaded; tab unavailable:',
|
||||
hiddenFiles: 'Hidden files',
|
||||
parent: 'Parent directory',
|
||||
copied: 'Copied',
|
||||
copy: 'Copy',
|
||||
newFile: 'New file',
|
||||
openEditor: 'Open editor',
|
||||
gitDetail: 'View change details',
|
||||
referenceFile: '@file',
|
||||
addToConversation: 'Add to conversation',
|
||||
copyRelative: 'Copy relative path',
|
||||
@@ -764,7 +705,6 @@ export const en: Record<keyof typeof zh, string> = {
|
||||
settingsSchemeCustomDesc: 'Full control: inject custom CSS (can override built-in styles) and set the title-bar shift distance',
|
||||
settingsSchemeDetectedSuffix: 'detected',
|
||||
settingsCustomCssTitle: 'Custom CSS',
|
||||
settingsCustomCssDesc: 'Styles appended at the end of the page (later in the cascade wins ties; use !important to override JS-written inline variables)',
|
||||
settingsCustomCssPlaceholder: '/* e.g. reserve 36px for a shell with a custom-drawn title bar */\nhtml[data-dsh-title-bar-height="36"] {\n --dsh-title-bar-strip: 36px !important;\n}',
|
||||
settingsSaveFailed: 'Failed to save',
|
||||
settingsConflict: 'The setting changed in another window — please retry',
|
||||
@@ -793,7 +733,6 @@ export const en: Record<keyof typeof zh, string> = {
|
||||
settingsShellArgsDesc: 'Explicit shell arguments, space-separated; when non-empty they fully replace the defaults (same contract as the yaml shellArgs)',
|
||||
settingsShellArgsPlaceholder: 'e.g. -l (empty = defaults)',
|
||||
settingsFontSizeDesc: 'Terminal font size in px (9–32, default 13)',
|
||||
settingsFontSizeSuffix: 'px',
|
||||
settingsTabsTitle: 'Sidebar content',
|
||||
settingsViewersTitle: 'File viewers',
|
||||
settingsGeneralTitle: 'General',
|
||||
@@ -829,19 +768,14 @@ export const en: Record<keyof typeof zh, string> = {
|
||||
browserEmbedBlockedDesc: 'The site forbids being displayed inside other pages (X-Frame-Options / frame-ancestors), so it cannot load in the sidebar. Open it directly in your browser instead.',
|
||||
browserEmbedAnyway: 'Load anyway',
|
||||
subagent: 'Tasks',
|
||||
openSubagent: 'Tasks',
|
||||
subagentMainAgent: 'Main agent',
|
||||
subagentEmpty: 'No subagents',
|
||||
subagentEmptyDesc: 'Subagents spawned under the main agent will appear here',
|
||||
subagentRunning: 'Running',
|
||||
subagentInactive: 'Inactive',
|
||||
subagentModeOneShot: 'One-shot',
|
||||
subagentModeContinuable: 'Continuable',
|
||||
subagentCount: '{count} subagents',
|
||||
subagentCountRunning: '{count} subagents · {running} running',
|
||||
subagentDiagCorrupt: 'Corrupt',
|
||||
subagentDiagUnsupported: 'Unsupported',
|
||||
subagentDiagUnavailable: 'Unavailable',
|
||||
subagentThinking: 'Thinking…',
|
||||
sideChat: 'Side Chat (beta)',
|
||||
sideChatNew: 'New thread',
|
||||
@@ -862,10 +796,7 @@ export const en: Record<keyof typeof zh, string> = {
|
||||
sideChatThink: 'Thinking',
|
||||
sideChatInjection: 'Context injected',
|
||||
sideChatSend: 'Send',
|
||||
sideChatCancel: 'Stop',
|
||||
sideChatCancelTitle: 'Abort the running turn (queued work is kept)',
|
||||
sideChatClose: 'Close thread',
|
||||
sideChatCloseTitle: 'Release the thread\'s agent (history is kept)',
|
||||
sideChatError: 'Side Chat error: {message}',
|
||||
sideChatTurnUsage: 'Input {input} tok · Output {output} tok',
|
||||
sideChatBlockCollapse: 'Collapse',
|
||||
@@ -901,7 +832,6 @@ export const en: Record<keyof typeof zh, string> = {
|
||||
jobDurationMinutes: '{minutes}m {seconds}s',
|
||||
jobDurationHours: '{hours}h {minutes}m',
|
||||
jobViewOutput: 'View output',
|
||||
jobHideOutput: 'Hide output',
|
||||
jobNoOutput: 'No output yet',
|
||||
jobNotReadYet: 'Waiting for the model to read this job; its output appears here once the model runs job_output',
|
||||
jobOutputTruncated: 'Output truncated',
|
||||
@@ -919,7 +849,6 @@ export const en: Record<keyof typeof zh, string> = {
|
||||
settingsViewModeGraphDesc: 'Layered node graph with zoom and pan',
|
||||
settingsViewModeTree: 'Tree',
|
||||
settingsViewModeTreeDesc: 'Classic indentation tree, keyboard navigable',
|
||||
tasksWorkflowMember: 'Workflow member',
|
||||
tasksFoldCompleted: '✓ {count} completed',
|
||||
tasksFoldExpand: 'Expand the completed nodes',
|
||||
tasksFoldCollapse: 'Collapse the completed nodes',
|
||||
@@ -940,7 +869,6 @@ export const en: Record<keyof typeof zh, string> = {
|
||||
tasksStateError: 'Error',
|
||||
teamBoard: 'Team task board',
|
||||
teamChip: 'Team {members} members · {tasks} tasks',
|
||||
teamMembers: 'Members',
|
||||
teamTasksEmpty: 'No shared tasks yet',
|
||||
teamTaskCreate: 'New task',
|
||||
teamTaskSubject: 'Subject',
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
/**
|
||||
* Graph-only styles of the workflow graph (TasksGraph.tsx) — the two pieces
|
||||
* the page sheet (tasks-graph.module.css) does not carry:
|
||||
* tasks-graph.module.css does not carry:
|
||||
*
|
||||
* - the card title, clamped to TWO lines (the 68px card reserve in
|
||||
* tasks-graph-layout.ts is sized for that second line: a single ellipsized
|
||||
* line left too few CJK characters to tell two siblings apart), and
|
||||
* - the card title, clamped to TWO lines (the card reserve in
|
||||
* tasks-graph-layout.ts is sized for exactly that clamp and for the token's
|
||||
* 18px title line: a single ellipsized line left too few CJK characters to
|
||||
* tell two siblings apart), and
|
||||
* - the hydration hint drawn over an empty canvas.
|
||||
*
|
||||
* Everything else the graph wears (the dotted canvas, the bezier edges, the
|
||||
* node cards, the control cluster) stays in the page sheet — one source of
|
||||
* truth per rule.
|
||||
* node cards, the control cluster) stays in tasks-graph.module.css — one source
|
||||
* of truth per rule.
|
||||
*
|
||||
* Skin contract: colors resolve to `--dsw-alias-*`, type to `--dsw-font-*` —
|
||||
* tokens only, no literal, no palette class, no shadow on a static panel.
|
||||
@@ -18,8 +19,11 @@
|
||||
/* Card line 1 of an agent / run node. `-webkit-box` + `-webkit-line-clamp` is
|
||||
* the only way to cap WRAPPED text with an ellipsis, and `overflow-wrap:
|
||||
* anywhere` keeps an unbroken run id from forcing one wide line. The recipe
|
||||
* mirrors the page sheet's node title (12px strong) so only the truncation
|
||||
* differs; the untruncated text stays in the element's `title`. */
|
||||
* mirrors the tree row title in tasks-graph.module.css (12px strong) so only
|
||||
* the truncation differs; the untruncated text stays in the element's `title`.
|
||||
* The clamp count and the token's 18px line are PAIRED with the layout's
|
||||
* `NODE_TITLE_LINES` / `NODE_TITLE_LINE_H`: the card reserves that block, so
|
||||
* changing either side alone leaves the card taller or shorter than its box. */
|
||||
.nodeTitle {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
@@ -33,7 +37,7 @@
|
||||
}
|
||||
|
||||
/* The fold aggregate carries a count, not a name: it recedes one rung in both
|
||||
* weight and ink (the page sheet's plain title). */
|
||||
* weight and ink (the plain-ink node title). */
|
||||
.nodeTitlePlain {
|
||||
font: var(--dsw-font-xxs-12);
|
||||
color: var(--dsw-alias-label-secondary);
|
||||
|
||||
@@ -12,16 +12,58 @@
|
||||
import type { TasksNode } from './tasks-model.ts'
|
||||
import { tasksEdges } from './tasks-model.ts'
|
||||
|
||||
/** Geometry constants of the canvas (px, pre-scale). Metrics follow the
|
||||
* approved Variant-D mockup, whose design target is the NARROW native right
|
||||
* sidebar (~360px): a 132px card fits two per row plus the gutter. */
|
||||
/** Geometry constants of the canvas (px, pre-scale). The design target is the
|
||||
* NARROW native right sidebar (~360px): a 176px card fits two per row plus
|
||||
* the gutter. */
|
||||
export const GRAPH_NODE_W = 176
|
||||
/** Two title lines plus the mono meta line: the card clamps long agent names
|
||||
* to two lines instead of ellipsizing them to a couple of characters, so the
|
||||
* reserved height covers that (see NODE_TITLE in TasksGraph.tsx). */
|
||||
export const GRAPH_NODE_H = 68
|
||||
/** Extra height of an agent node carrying a live line. */
|
||||
export const GRAPH_LIVE_H = 14
|
||||
|
||||
/**
|
||||
* The card's heights are the SUM OF THE ROWS THE CARD RENDERS, in the real
|
||||
* metrics of the page's type scale (the same numbers the rules in
|
||||
* tasks-graph.module.css / tasks-canvas.module.css are written with). They are
|
||||
* derived rather than hand-tuned because the card is a fixed-geometry box: its
|
||||
* height is `auto` with `min-height: box.h`, so an under-reserved card does not
|
||||
* stay inside the box the layout handed it — it RENDERS TALLER, and everything
|
||||
* the layout derives from `box.h` (the row pitch, the phase frames, the canvas
|
||||
* extent) then disagrees with the pixels on screen.
|
||||
*
|
||||
* Measured on the rendered page: a running teammate card carrying a two-line
|
||||
* title, its meta, a live row and a task line renders 100px while the base
|
||||
* reserve handed it 68 — `min-height` cannot hold it down, so the card ate
|
||||
* 32px of the 53px gutter to the next row and poked out of its phase frame.
|
||||
*/
|
||||
const NODE_EDGE_H = 1
|
||||
const NODE_PAD_Y = 6
|
||||
/** Both edges' 1px outline plus the vertical padding (`.node` box-sizing). */
|
||||
const NODE_CHROME_H = 2 * (NODE_PAD_Y + NODE_EDGE_H)
|
||||
/** One title line — `--dsw-font-xxs-strong-12` (12px/18px). */
|
||||
const NODE_TITLE_LINE_H = 18
|
||||
/** Title lines the card reserves: the clamp in tasks-canvas.module.css. */
|
||||
const NODE_TITLE_LINES = 2
|
||||
/** The mono meta line — `--dsw-font-xxxs-11` (11px/14px) plus its 2px lead. */
|
||||
const NODE_META_H = 14 + 2
|
||||
/** One live row: LiveLine's 10px/1.3 tool row (or its meta-styled fallback)
|
||||
* plus the 3px lead. */
|
||||
const NODE_LIVE_H = 13 + 3
|
||||
/** LiveLine's flattened text row — a 10px line whose box measures 14px, plus
|
||||
* its 2px lead — which a tail carrying both a tool call and text renders
|
||||
* UNDER the tool row. */
|
||||
const NODE_LIVE_TAIL_H = 14 + 2
|
||||
/** The shared-task row: its 10px/1.3 line plus the 3px lead, sized for the
|
||||
* `+N` chip's own 1px outline (the tallest shape the row can take). */
|
||||
const NODE_TASK_H = 15 + 3
|
||||
|
||||
/** TWO title lines plus the mono meta line: long agent names are clamped to
|
||||
* two lines instead of ellipsizing to a couple of characters (see NODE_TITLE
|
||||
* in TasksGraph.tsx), so the reserve covers that second line. */
|
||||
export const GRAPH_NODE_H = NODE_CHROME_H + NODE_TITLE_LINES * NODE_TITLE_LINE_H + NODE_META_H
|
||||
/** Extra height of a RUNNING agent node: the live row it always shows (a
|
||||
* running node without activity yet renders LiveLine's "thinking" fallback). */
|
||||
export const GRAPH_LIVE_H = NODE_LIVE_H
|
||||
/** Extra height of a running node whose tail carries text as well as a tool. */
|
||||
export const GRAPH_LIVE_TAIL_H = NODE_LIVE_TAIL_H
|
||||
/** Extra height of an agent node carrying a shared-task line (team members). */
|
||||
export const GRAPH_TASK_H = NODE_TASK_H
|
||||
|
||||
/**
|
||||
* The readability floor the fit honours: the canvas may shrink to this scale
|
||||
@@ -32,7 +74,8 @@ export const GRAPH_FIT_MIN_SCALE = 0.78
|
||||
export const GRAPH_GAP_X = 28
|
||||
export const GRAPH_GAP_Y = 53
|
||||
export const GRAPH_PAD = 16
|
||||
/** The row stride (one row of cards plus the vertical gutter). */
|
||||
/** The row stride (one row of cards plus the vertical gutter). Every card
|
||||
* shape must fit inside it — see {@link nodeHeight} for the tallest one. */
|
||||
export const GRAPH_ROW_STRIDE = GRAPH_NODE_H + GRAPH_LIVE_H + GRAPH_GAP_Y
|
||||
|
||||
/** One laid-out node. */
|
||||
@@ -58,13 +101,29 @@ export interface LayoutOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* The display height of one node. Every RUNNING agent reserves the live-line
|
||||
* row: a running node without activity yet still renders the "thinking" line
|
||||
* (LiveLine's fallback), so reserving only when data arrived would clip it.
|
||||
* The display height of one node: the base card plus one reserved row per
|
||||
* line the card will actually render, so the pixels and the box agree (see
|
||||
* the constants above for what a mismatch costs).
|
||||
*
|
||||
* - a RUNNING agent always reserves the live row: without activity yet it
|
||||
* still renders the "thinking" line (LiveLine's fallback), and a tail that
|
||||
* arrived with a tool call reserves its text row too;
|
||||
* - an agent owning shared tasks (a team member) reserves the task row —
|
||||
* without it a two-line title, the meta and the task row render 16px below
|
||||
* the reserved box.
|
||||
*
|
||||
* The tallest shape therefore is base + live + live-tail + task, which stays
|
||||
* inside {@link GRAPH_ROW_STRIDE} (rows can never overlap).
|
||||
*/
|
||||
function nodeHeight(node: TasksNode): number {
|
||||
if (node.kind === 'agent' && node.state === 'running') return GRAPH_NODE_H + GRAPH_LIVE_H
|
||||
return GRAPH_NODE_H
|
||||
if (node.kind !== 'agent') return GRAPH_NODE_H
|
||||
let height = GRAPH_NODE_H
|
||||
if (node.state === 'running') {
|
||||
height += GRAPH_LIVE_H
|
||||
if (node.live?.tool !== undefined && node.live.text !== undefined) height += GRAPH_LIVE_TAIL_H
|
||||
}
|
||||
if ((node.tasks?.length ?? 0) > 0) height += GRAPH_TASK_H
|
||||
return height
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+500
-102
File diff suppressed because it is too large
Load Diff
@@ -2,28 +2,44 @@
|
||||
* Unit tests for the layered graph layout: parent centering, depth rows, the
|
||||
* sibling-band WRAP that keeps a narrow sidebar readable (and the row
|
||||
* reservation that stops a wrapped band from landing on a sibling's
|
||||
* children), the live-line height, and the width-aware solver.
|
||||
* children), the PER-SHAPE card height (the live rows and the shared-task row
|
||||
* a card renders are reserved, so a card never renders outside its box), and
|
||||
* the width-aware solver.
|
||||
*/
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
GRAPH_GAP_Y,
|
||||
GRAPH_LIVE_H,
|
||||
GRAPH_LIVE_TAIL_H,
|
||||
GRAPH_NODE_H,
|
||||
GRAPH_NODE_W,
|
||||
GRAPH_PAD,
|
||||
GRAPH_ROW_STRIDE,
|
||||
GRAPH_TASK_H,
|
||||
bandColsFor,
|
||||
layoutTasksGraph,
|
||||
layoutTasksGraphForWidth,
|
||||
} from '../src/client/tasks-graph-layout.ts'
|
||||
import type { TasksAgentNode, TasksNode } from '../src/client/tasks-model.ts'
|
||||
import type { TasksAgentNode, TasksNode, TasksNodeTask } from '../src/client/tasks-model.ts'
|
||||
|
||||
/** An agent node. */
|
||||
function agent(id: string, parentId?: string, live = false): TasksAgentNode {
|
||||
/** One shared task as the card's task line shows it. */
|
||||
function task(id: string): TasksNodeTask {
|
||||
return { id, subject: id, status: 'in_progress', ready: true }
|
||||
}
|
||||
|
||||
/** An agent node. `live` gives it a text-only tail; `extra` shapes the card
|
||||
* further (a settled state, a tool call, owned shared tasks). */
|
||||
function agent(
|
||||
id: string,
|
||||
parentId?: string,
|
||||
live = false,
|
||||
extra: Partial<TasksAgentNode> = {},
|
||||
): TasksAgentNode {
|
||||
return {
|
||||
kind: 'agent', id, ...(parentId === undefined ? {} : { parentId }),
|
||||
label: id, state: 'running', activity: 'running', current: false,
|
||||
...(live ? { live: { text: 'x' } } : {}),
|
||||
...extra,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +82,50 @@ describe('layoutTasksGraph', () => {
|
||||
expect(layout.height).toBeGreaterThan(2 * (GRAPH_NODE_H + GRAPH_GAP_Y))
|
||||
})
|
||||
|
||||
it('reserves the shared-task row a teammate card renders', () => {
|
||||
// A non-running teammate with a task line renders two title lines + the
|
||||
// meta line + the task row; the base card alone reserves 16px less, and
|
||||
// the card (height auto) renders that much outside its own box — which is
|
||||
// what the edges and the phase frames are placed from.
|
||||
const nodes: TasksNode[] = [
|
||||
agent('root'),
|
||||
agent('mate', 'root', false, { state: 'idle', tasks: [task('t1')] }),
|
||||
]
|
||||
const layout = layoutTasksGraph(nodes)
|
||||
expect(layout.boxes.get('mate')?.h).toBe(GRAPH_NODE_H + GRAPH_TASK_H)
|
||||
// Without tasks the card keeps the base shape.
|
||||
const plain = layoutTasksGraph([agent('root'), agent('mate', 'root', false, { state: 'idle' })])
|
||||
expect(plain.boxes.get('mate')?.h).toBe(GRAPH_NODE_H)
|
||||
})
|
||||
|
||||
it('reserves the live tail row only when the tail carries a tool AND text', () => {
|
||||
const nodes: TasksNode[] = [
|
||||
agent('root'),
|
||||
agent('tool-only', 'root', false, { live: { tool: { name: 'read', args: 'x' } } }),
|
||||
agent('both', 'root', false, { live: { tool: { name: 'read', args: 'x' }, text: 'y' } }),
|
||||
]
|
||||
const layout = layoutTasksGraph(nodes)
|
||||
// One live row either way (the tool row, or the meta-styled thinking
|
||||
// fallback); the flattened text row is the second one.
|
||||
expect(layout.boxes.get('tool-only')?.h).toBe(GRAPH_NODE_H + GRAPH_LIVE_H)
|
||||
expect(layout.boxes.get('both')?.h).toBe(GRAPH_NODE_H + GRAPH_LIVE_H + GRAPH_LIVE_TAIL_H)
|
||||
})
|
||||
|
||||
it('keeps every card shape inside one row stride', () => {
|
||||
// The stride is the row pitch: a card taller than it would overlap the
|
||||
// next row (and its phase frame).
|
||||
const tallest = GRAPH_NODE_H + GRAPH_LIVE_H + GRAPH_LIVE_TAIL_H + GRAPH_TASK_H
|
||||
expect(GRAPH_ROW_STRIDE).toBeGreaterThanOrEqual(tallest)
|
||||
const nodes: TasksNode[] = [
|
||||
agent('root'),
|
||||
agent('busiest', 'root', false, {
|
||||
live: { tool: { name: 'read', args: 'x' }, text: 'y' }, tasks: [task('t1')],
|
||||
}),
|
||||
]
|
||||
const layout = layoutTasksGraph(nodes)
|
||||
expect(layout.boxes.get('busiest')?.h).toBe(tallest)
|
||||
})
|
||||
|
||||
it('gives every node a box even with a defensive orphan', () => {
|
||||
const nodes: TasksNode[] = [agent('root'), agent('ghost', 'missing')]
|
||||
const layout = layoutTasksGraph(nodes)
|
||||
|
||||
Reference in New Issue
Block a user