copy(tui): disclose Session Log upload in Chinese welcome
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write apps/cli/README.md
|
||||
README.md: e01989d18d7a1567ea0d62628d207bdebd8e27e1
|
||||
README.zh.md: 4df2b0911059c24baa5f6bec315e7fdf523213f7
|
||||
README.md: 2f7238b3c05f6b76288c5e26b14efd2e64485677
|
||||
README.zh.md: af4004be225307fc3863bf6f227ef95f7ca0c14f
|
||||
|
||||
@@ -12,7 +12,7 @@ The TUI surface:
|
||||
- treats the **invoking directory** as the workspace — sessions, relative paths, and workspace instructions resolve from the cwd (`dsh meta` is the sole exception, below);
|
||||
- tells the agent where its own source lives: after boot it adds a prompt section naming this harness checkout, resolved from the launcher's real path so it holds under a PATH symlink and an arbitrary cwd, so the self-referential `cordis` toolset can read and modify it;
|
||||
- applies the personal overlay from `~/.dsh` (see [app-boot's Personal config](../../packages/ui/app-boot/README.md#personal-config)): `config.yaml` patches the booted tree, while `.env` there is the credential provider's own store (never hoisted into the environment, so keys stay rotatable). Environment precedence is ambient > project `.env`.
|
||||
- presents the [versioned first-run welcome](../../.agents/notes/implemented/feature/2026-07-30-versioned-tui-first-run-welcome.md) through the mounted TUI overlay service when its immutable marker is absent under `DSH_HOME`; only Enter creates that version's marker, while Escape, disposal, or process exit leaves it eligible. The official DeepSeek icon, responsive terminal rasters, bilingual copy, and notice version are static local owners; the overlay never writes a session event or model context.
|
||||
- presents the [versioned first-run welcome](../../.agents/notes/implemented/feature/2026-07-30-versioned-tui-first-run-welcome.md) through the mounted TUI overlay service when its immutable marker is absent under `DSH_HOME`; only Enter creates that version's marker, while Escape, disposal, or process exit leaves it eligible. The official DeepSeek icon, responsive terminal rasters, all-locale Chinese copy, and notice version are static local owners; the overlay never writes a session event or model context.
|
||||
|
||||
`dsh meta` is that same TUI with this harness checkout as the workspace, so working on dsh itself needs no `cd`. It chdirs to the checkout root — resolved from the launcher's real path, the same root the source-path prompt section names — after the environment is settled, so precedence is unchanged while the session cwd and HMR watch root move together. Meta always starts a fresh session and accepts no default-surface options; use ordinary `dsh --resume <id>` to resume a persisted session.
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ TUI 界面:
|
||||
- 将 **调用目录** 视为 workspace:会话、相对路径和 workspace 指令都从 cwd 解析(`dsh meta` 是唯一例外,见下文);
|
||||
- 告知 agent 自身源码所在位置:启动后添加一个命名此 harness checkout 的提示词段。该路径从启动器的真实路径解析,因此在 PATH 符号链接和任意 cwd 下仍然有效,使自指的 `cordis` 工具集可以读取并修改它;
|
||||
- 应用 `~/.dsh` 中的个人覆盖(参见 [app-boot 的个人配置](../../packages/ui/app-boot/README.md#personal-config)):`config.yaml` 修补已启动的树,而那里的 `.env` 是凭据 provider 自己的存储(绝不会被提升进环境,因此密钥始终可轮换)。环境优先级为环境中已有的值 > 项目 `.env`。
|
||||
- 当 `DSH_HOME` 下不存在不可变确认标记时,通过已挂载的 TUI overlay 服务呈现[版本化首次运行欢迎页](../../.agents/notes/implemented/feature/2026-07-30-versioned-tui-first-run-welcome.md);只有 Enter 会创建该版本的标记,Escape、资源释放或进程退出仍保留展示资格。官方 DeepSeek 图标、响应式终端栅格图、双语文案和通知版本均由静态本地文件持有;overlay 不会写入会话事件或模型上下文。
|
||||
- 当 `DSH_HOME` 下不存在不可变确认标记时,通过已挂载的 TUI overlay 服务呈现[版本化首次运行欢迎页](../../.agents/notes/implemented/feature/2026-07-30-versioned-tui-first-run-welcome.md);只有 Enter 会创建该版本的标记,Escape、资源释放或进程退出仍保留展示资格。官方 DeepSeek 图标、响应式终端栅格图、所有 locale 共用的中文文案和通知版本均由静态本地文件持有;overlay 不会写入会话事件或模型上下文。
|
||||
|
||||
`dsh meta` 是以本 harness checkout 为 workspace 的同一个 TUI,因此开发 dsh 自身无需 `cd`。它在环境确定之后才 chdir 到 checkout 根目录(从启动器的真实路径解析,与源码路径提示词段所指的根目录相同),因此环境优先级不变,而会话 cwd 与 HMR 监视根目录会一并移动。Meta 始终创建新会话,不接受默认界面的任何选项;恢复已持久化会话应使用普通的 `dsh --resume <id>`。
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Centrally owned version and bilingual copy for the shipped TUI first-run notice.
|
||||
* Centrally owned version and all-locale Chinese copy for the shipped TUI first-run notice.
|
||||
*
|
||||
* A material wording change increments {@link TUI_FIRST_RUN_WELCOME_NOTICE_VERSION}
|
||||
* so every Harness home presents the revised notice once.
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/** Copy version persisted after the user explicitly continues. */
|
||||
export const TUI_FIRST_RUN_WELCOME_NOTICE_VERSION = 2
|
||||
export const TUI_FIRST_RUN_WELCOME_NOTICE_VERSION = 3
|
||||
|
||||
/** Locale-shaped text rendered by the first-run welcome overlay. */
|
||||
export interface TuiFirstRunWelcomeNoticeCopy {
|
||||
@@ -25,37 +25,24 @@ export interface TuiFirstRunWelcomeNoticeCopy {
|
||||
readonly saveError: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete notice copy. The shipped TUI currently presents the supplied
|
||||
* Simplified Chinese locale; English remains its reviewed locale counterpart.
|
||||
*/
|
||||
/** Complete Chinese notice used for every locale. */
|
||||
const TUI_FIRST_RUN_WELCOME_CHINESE_COPY = Object.freeze<TuiFirstRunWelcomeNoticeCopy>({
|
||||
title: 'DeepSeek Harness',
|
||||
paragraphs: Object.freeze([
|
||||
'感谢您愿意拨冗试用 DeepSeek Harness。当前版本仍处于内部测试阶段,功能仍待完善,体验难免有些粗糙。',
|
||||
'“如切如磋,如琢如磨。” 产品的成长,离不开一次次真实的碰撞与坦诚的反馈。您在真实使用中发现的问题,也可能促使我们重新审视,甚至推翻已有的设计。',
|
||||
'为了帮助我们更准确地还原您真实使用中的问题,内测版本默认会上传所有 Session Log;如需关闭,可以【关闭方式待补充】。另外,如果您有任何反馈与建议,请在企业微信群中留言告诉我们。每一条反馈,都会帮助我们把它打磨得更好。',
|
||||
]),
|
||||
continueLabel: '继续',
|
||||
scrollHint: '↑/↓ 滚动',
|
||||
saving: '正在保存确认…',
|
||||
saveError: '无法保存确认,请按 Enter 重试。',
|
||||
})
|
||||
|
||||
/** Locale map whose entries deliberately share the single Chinese owner copy. */
|
||||
export const TUI_FIRST_RUN_WELCOME_NOTICE_COPY = Object.freeze({
|
||||
'zh-CN': Object.freeze<TuiFirstRunWelcomeNoticeCopy>({
|
||||
title: 'DeepSeek Harness',
|
||||
paragraphs: Object.freeze([
|
||||
'感谢您愿意拨冗试用 DeepSeek Harness。',
|
||||
'目前的版本仍处于内部测试阶段,功能仍待完善,体验难免有些粗糙。',
|
||||
'“如切如磋,如琢如磨。” 产品的成长,离不开一次次真实的碰撞与坦诚的反馈。您在真实使用中发现的问题,也可能促使我们重新审视,甚至推翻已有的设计。',
|
||||
'我们尤其希望听见那些失败、困惑与不顺手的时刻——如果您有任何反馈与建议,请在企业微信群中留言告诉我们。每一条反馈,都会帮助我们把它打磨得更好。',
|
||||
]),
|
||||
continueLabel: '继续',
|
||||
scrollHint: '↑/↓ 滚动',
|
||||
saving: '正在保存确认…',
|
||||
saveError: '无法保存确认,请按 Enter 重试。',
|
||||
}),
|
||||
en: Object.freeze<TuiFirstRunWelcomeNoticeCopy>({
|
||||
title: 'DeepSeek Harness',
|
||||
paragraphs: Object.freeze([
|
||||
'Thank you for taking the time to try DeepSeek Harness.',
|
||||
'This release is still in internal testing. Features remain unfinished, and the experience will inevitably feel somewhat rough.',
|
||||
'“As one cuts and files, as one carves and polishes.” A product grows through real encounters and candid feedback. Problems you discover in real use may lead us to re-examine, or even overturn, existing designs.',
|
||||
'We especially want to hear about moments of failure, confusion, and friction. If you have any feedback or suggestions, please leave a message in the company WeChat group and let us know. Every piece of feedback helps us refine it.',
|
||||
]),
|
||||
continueLabel: 'Continue',
|
||||
scrollHint: '↑/↓ Scroll',
|
||||
saving: 'Saving acknowledgement…',
|
||||
saveError: 'Could not save the acknowledgement. Press Enter to retry.',
|
||||
}),
|
||||
'zh-CN': TUI_FIRST_RUN_WELCOME_CHINESE_COPY,
|
||||
en: TUI_FIRST_RUN_WELCOME_CHINESE_COPY,
|
||||
})
|
||||
|
||||
/** Locale presented by the shipped first-run notice. */
|
||||
|
||||
@@ -169,8 +169,8 @@ export function tuiFirstRunWelcomeArtTier(
|
||||
viewportRows: number,
|
||||
): TuiFirstRunWelcomeArtTier | undefined {
|
||||
if (innerWidth >= 96 && viewportRows >= 23) return 'full'
|
||||
if (innerWidth >= 64 && viewportRows >= 18) return 'compact'
|
||||
if (innerWidth >= 48 && viewportRows >= 14) return 'minimal'
|
||||
if (innerWidth >= 80 && viewportRows >= 34) return 'compact'
|
||||
if (innerWidth >= 64 && viewportRows >= 14) return 'minimal'
|
||||
return undefined
|
||||
}
|
||||
|
||||
|
||||
@@ -10,52 +10,52 @@ overlay 120x30 rows=20
|
||||
style 0-0 dim
|
||||
style 9-38 fg=blue
|
||||
style 119-119 dim
|
||||
3| "│ ▄███████████████▄ ████▄ ▄▄▄▄██ 感谢您愿意拨冗试用 DeepSeek Harness。 │"
|
||||
3| "│ ▄███████████████▄ ████▄ ▄▄▄▄██ 感谢您愿意拨冗试用 DeepSeek Harness。当前版本仍处于内部测试阶段,功能 │"
|
||||
style 0-0 dim
|
||||
style 4-43 fg=blue
|
||||
style 119-119 dim
|
||||
4| "│ ▄███████████████████▄ ████████████▀ │"
|
||||
4| "│ ▄███████████████████▄ ████████████▀ 仍待完善,体验难免有些粗糙。 │"
|
||||
style 0-0 dim
|
||||
style 4-43 fg=blue
|
||||
style 119-119 dim
|
||||
5| "│ ▄██████████████████████▄ ▀█████████▀ 目前的版本仍处于内部测试阶段,功能仍待完善,体验难免有些粗糙。 │"
|
||||
5| "│ ▄██████████████████████▄ ▀█████████▀ │"
|
||||
style 0-0 dim
|
||||
style 4-42 fg=blue
|
||||
style 119-119 dim
|
||||
6| "│ ▄███▀█████████████████████▄ ████▀▀ │"
|
||||
6| "│ ▄███▀█████████████████████▄ ████▀▀ “如切如磋,如琢如磨。” │"
|
||||
style 0-0 dim
|
||||
style 6-41 fg=blue
|
||||
style 119-119 dim
|
||||
7| "│ ███ ▀▀█████████▀▀▀█████████▀ “如切如磋,如琢如磨。” │"
|
||||
style 0-0 dim
|
||||
style 7-40 fg=blue
|
||||
style 49-70 bold
|
||||
style 119-119 dim
|
||||
8| "│ ███ ▀███████▀█ ▀███████ │"
|
||||
7| "│ ███ ▀▀█████████▀▀▀█████████▀ │"
|
||||
style 0-0 dim
|
||||
style 7-40 fg=blue
|
||||
style 119-119 dim
|
||||
8| "│ ███ ▀███████▀█ ▀███████ 产品的成长,离不开一次次真实的碰撞与坦诚的反馈。您在真实使用中发现的 │"
|
||||
style 0-0 dim
|
||||
style 7-39 fg=blue
|
||||
style 119-119 dim
|
||||
9| "│ ███▄ ▀███████▄ ▀█████▀ 产品的成长,离不开一次次真实的碰撞与坦诚的反馈。您在真实使用中发现的 │"
|
||||
9| "│ ███▄ ▀███████▄ ▀█████▀ 问题,也可能促使我们重新审视,甚至推翻已有的设计。 │"
|
||||
style 0-0 dim
|
||||
style 7-39 fg=blue
|
||||
style 119-119 dim
|
||||
10| "│ ▀███ ▀██████████████ 问题,也可能促使我们重新审视,甚至推翻已有的设计。 │"
|
||||
10| "│ ▀███ ▀██████████████ │"
|
||||
style 0-0 dim
|
||||
style 8-39 fg=blue
|
||||
style 119-119 dim
|
||||
11| "│ ▀███▄ ▀███████████▀ │"
|
||||
11| "│ ▀███▄ ▀███████████▀ 为了帮助我们更准确地还原您真实使用中的问题,内测版本默认会上传所有 │"
|
||||
style 0-0 dim
|
||||
style 8-38 fg=blue
|
||||
style 119-119 dim
|
||||
12| "│ ▀███▄ ▄▄▄ ▀████████▀ 我们尤其希望听见那些失败、困惑与不顺手的时刻——如果您有任何反馈与建议 │"
|
||||
12| "│ ▀███▄ ▄▄▄ ▀████████▀ Session Log;如需关闭,可以【关闭方式待补充】。另外,如果您有任何反馈 │"
|
||||
style 0-0 dim
|
||||
style 9-38 fg=blue
|
||||
style 119-119 dim
|
||||
13| "│ █████▄ ███▄▄ ▀█████▄▄ ,请在企业微信群中留言告诉我们。每一条反馈,都会帮助我们把它打磨得更 │"
|
||||
13| "│ █████▄ ███▄▄ ▀█████▄▄ 与建议,请在企业微信群中留言告诉我们。每一条反馈,都会帮助我们把它打 │"
|
||||
style 0-0 dim
|
||||
style 9-38 fg=blue
|
||||
style 119-119 dim
|
||||
14| "│ ▀█████████████▄▄▄▄█▀█████▀ 好。 │"
|
||||
14| "│ ▀█████████████▄▄▄▄█▀█████▀ 磨得更好。 │"
|
||||
style 0-0 dim
|
||||
style 8-39 fg=blue
|
||||
style 119-119 dim
|
||||
|
||||
@@ -10,7 +10,7 @@ overlay 160x30 rows=20
|
||||
style 0-0 dim
|
||||
style 9-38 fg=blue
|
||||
style 159-159 dim
|
||||
3| "│ ▄███████████████▄ ████▄ ▄▄▄▄██ 感谢您愿意拨冗试用 DeepSeek Harness。 │"
|
||||
3| "│ ▄███████████████▄ ████▄ ▄▄▄▄██ 感谢您愿意拨冗试用 DeepSeek Harness。当前版本仍处于内部测试阶段,功能仍待完善,体验难免有些粗糙。 │"
|
||||
style 0-0 dim
|
||||
style 4-43 fg=blue
|
||||
style 159-159 dim
|
||||
@@ -18,40 +18,40 @@ overlay 160x30 rows=20
|
||||
style 0-0 dim
|
||||
style 4-43 fg=blue
|
||||
style 159-159 dim
|
||||
5| "│ ▄██████████████████████▄ ▀█████████▀ 目前的版本仍处于内部测试阶段,功能仍待完善,体验难免有些粗糙。 │"
|
||||
5| "│ ▄██████████████████████▄ ▀█████████▀ “如切如磋,如琢如磨。” │"
|
||||
style 0-0 dim
|
||||
style 4-42 fg=blue
|
||||
style 49-70 bold
|
||||
style 159-159 dim
|
||||
6| "│ ▄███▀█████████████████████▄ ████▀▀ │"
|
||||
style 0-0 dim
|
||||
style 6-41 fg=blue
|
||||
style 159-159 dim
|
||||
7| "│ ███ ▀▀█████████▀▀▀█████████▀ “如切如磋,如琢如磨。” │"
|
||||
7| "│ ███ ▀▀█████████▀▀▀█████████▀ 产品的成长,离不开一次次真实的碰撞与坦诚的反馈。您在真实使用中发现的问题,也可能促使我们重新审视,甚至推翻已 │"
|
||||
style 0-0 dim
|
||||
style 7-40 fg=blue
|
||||
style 49-70 bold
|
||||
style 159-159 dim
|
||||
8| "│ ███ ▀███████▀█ ▀███████ │"
|
||||
8| "│ ███ ▀███████▀█ ▀███████ 有的设计。 │"
|
||||
style 0-0 dim
|
||||
style 7-39 fg=blue
|
||||
style 159-159 dim
|
||||
9| "│ ███▄ ▀███████▄ ▀█████▀ 产品的成长,离不开一次次真实的碰撞与坦诚的反馈。您在真实使用中发现的问题,也可能促使我们重新审视,甚至推翻已 │"
|
||||
9| "│ ███▄ ▀███████▄ ▀█████▀ │"
|
||||
style 0-0 dim
|
||||
style 7-39 fg=blue
|
||||
style 159-159 dim
|
||||
10| "│ ▀███ ▀██████████████ 有的设计。 │"
|
||||
10| "│ ▀███ ▀██████████████ 为了帮助我们更准确地还原您真实使用中的问题,内测版本默认会上传所有 Session Log;如需关闭,可以【关闭方式待补 │"
|
||||
style 0-0 dim
|
||||
style 8-39 fg=blue
|
||||
style 159-159 dim
|
||||
11| "│ ▀███▄ ▀███████████▀ │"
|
||||
11| "│ ▀███▄ ▀███████████▀ 充】。另外,如果您有任何反馈与建议,请在企业微信群中留言告诉我们。每一条反馈,都会帮助我们把它打磨得更好。 │"
|
||||
style 0-0 dim
|
||||
style 8-38 fg=blue
|
||||
style 159-159 dim
|
||||
12| "│ ▀███▄ ▄▄▄ ▀████████▀ 我们尤其希望听见那些失败、困惑与不顺手的时刻——如果您有任何反馈与建议,请在企业微信群中留言告诉我们。每一条反 │"
|
||||
12| "│ ▀███▄ ▄▄▄ ▀████████▀ │"
|
||||
style 0-0 dim
|
||||
style 9-38 fg=blue
|
||||
style 159-159 dim
|
||||
13| "│ █████▄ ███▄▄ ▀█████▄▄ 馈,都会帮助我们把它打磨得更好。 │"
|
||||
13| "│ █████▄ ███▄▄ ▀█████▄▄ │"
|
||||
style 0-0 dim
|
||||
style 9-38 fg=blue
|
||||
style 159-159 dim
|
||||
|
||||
@@ -8,13 +8,13 @@ overlay 60x12 rows=10
|
||||
2| "│ │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
3| "│ 感谢您愿意拨冗试用 DeepSeek Harness。 │"
|
||||
3| "│ 感谢您愿意拨冗试用 DeepSeek Harness。当前版本仍处于内部 │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
4| "│ │"
|
||||
4| "│ 测试阶段,功能仍待完善,体验难免有些粗糙。 │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
5| "│ 目前的版本仍处于内部测试阶段,功能仍待完善,体验难免有些 │"
|
||||
5| "│ │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
6| "├──────────────────────────────────────────────────────────┤"
|
||||
|
||||
@@ -1,90 +1,61 @@
|
||||
overlay 60x30 rows=27
|
||||
overlay 60x30 rows=20
|
||||
0| "╭──────────────────────────────────────────────────────────╮"
|
||||
style 0-59 dim
|
||||
1| "│ ▄▄▄▄▄▄ ▄▄ │"
|
||||
style 0-0 dim
|
||||
style 23-36 fg=blue
|
||||
style 59-59 dim
|
||||
2| "│ ▄████████▄ ▀████▀ │"
|
||||
style 0-0 dim
|
||||
style 21-38 fg=blue
|
||||
style 59-59 dim
|
||||
3| "│ █▀▀▀▀███████▄██▀ │"
|
||||
style 0-0 dim
|
||||
style 22-37 fg=blue
|
||||
style 59-59 dim
|
||||
4| "│ █▄ ▀███ ▀███ │"
|
||||
style 0-0 dim
|
||||
style 22-36 fg=blue
|
||||
style 59-59 dim
|
||||
5| "│ ▀█▄ ▀█████ │"
|
||||
style 0-0 dim
|
||||
style 23-36 fg=blue
|
||||
style 59-59 dim
|
||||
6| "│ ▀█▄▄ █▄▄▀███▄ │"
|
||||
style 0-0 dim
|
||||
style 23-36 fg=blue
|
||||
style 59-59 dim
|
||||
7| "│ ▀▀▀▀▀▀ │"
|
||||
style 0-0 dim
|
||||
style 25-34 fg=blue
|
||||
style 59-59 dim
|
||||
8| "│ │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
9| "│ DeepSeek Harness │"
|
||||
1| "│ DeepSeek Harness │"
|
||||
style 0-0 dim
|
||||
style 22-37 fg=blue bold
|
||||
style 59-59 dim
|
||||
10| "│ │"
|
||||
2| "│ │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
11| "│ 感谢您愿意拨冗试用 DeepSeek Harness。 │"
|
||||
3| "│ 感谢您愿意拨冗试用 DeepSeek Harness。当前版本仍处于内部 │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
12| "│ │"
|
||||
4| "│ 测试阶段,功能仍待完善,体验难免有些粗糙。 │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
13| "│ 目前的版本仍处于内部测试阶段,功能仍待完善,体验难免有些 │"
|
||||
5| "│ │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
14| "│ 粗糙。 │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
15| "│ │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
16| "│ “如切如磋,如琢如磨。” │"
|
||||
6| "│ “如切如磋,如琢如磨。” │"
|
||||
style 0-0 dim
|
||||
style 2-23 bold
|
||||
style 59-59 dim
|
||||
17| "│ │"
|
||||
7| "│ │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
18| "│ 产品的成长,离不开一次次真实的碰撞与坦诚的反馈。您在真实 │"
|
||||
8| "│ 产品的成长,离不开一次次真实的碰撞与坦诚的反馈。您在真实 │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
19| "│ 使用中发现的问题,也可能促使我们重新审视,甚至推翻已有的 │"
|
||||
9| "│ 使用中发现的问题,也可能促使我们重新审视,甚至推翻已有的 │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
20| "│ 设计。 │"
|
||||
10| "│ 设计。 │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
21| "│ │"
|
||||
11| "│ │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
22| "│ 我们尤其希望听见那些失败、困惑与不顺手的时刻——如果您有任 │"
|
||||
12| "│ 为了帮助我们更准确地还原您真实使用中的问题,内测版本默认 │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
23| "├──────────────────────────────────────────────────────────┤"
|
||||
13| "│ 会上传所有 Session Log;如需关闭,可以【关闭方式待补充】 │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
14| "│ 。另外,如果您有任何反馈与建议,请在企业微信群中留言告诉 │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
15| "│ 我们。每一条反馈,都会帮助我们把它打磨得更好。 │"
|
||||
style 0-0 dim
|
||||
style 59-59 dim
|
||||
16| "├──────────────────────────────────────────────────────────┤"
|
||||
style 0-59 dim
|
||||
24| "│ Enter 继续 │"
|
||||
17| "│ Enter 继续 │"
|
||||
style 0-0 dim
|
||||
style 24-34 fg=bright-magenta bold
|
||||
style 59-59 dim
|
||||
25| "│ ↑/↓ 滚动 ↓ │"
|
||||
18| "│ │"
|
||||
style 0-0 dim
|
||||
style 24-35 dim
|
||||
style 59-59 dim
|
||||
26| "╰──────────────────────────────────────────────────────────╯"
|
||||
19| "╰──────────────────────────────────────────────────────────╯"
|
||||
style 0-59 dim
|
||||
|
||||
@@ -1,93 +1,86 @@
|
||||
overlay 80x30 rows=27
|
||||
overlay 80x30 rows=26
|
||||
0| "╭──────────────────────────────────────────────────────────────────────────────╮"
|
||||
style 0-79 dim
|
||||
1| "│ ▄▄▄▄▄▄▄██▀ █▄ ▄ │"
|
||||
1| "│ ▄▄▄▄▄▄ ▄▄ │"
|
||||
style 0-0 dim
|
||||
style 26-53 fg=blue
|
||||
style 33-46 fg=blue
|
||||
style 79-79 dim
|
||||
2| "│ ▄███████████▄▄ ███▄▄████ │"
|
||||
2| "│ ▄████████▄ ▀████▀ │"
|
||||
style 0-0 dim
|
||||
style 26-53 fg=blue
|
||||
style 31-48 fg=blue
|
||||
style 79-79 dim
|
||||
3| "│ ████████████████▄ ▀██████▀ │"
|
||||
3| "│ █▀▀▀▀███████▄██▀ │"
|
||||
style 0-0 dim
|
||||
style 26-52 fg=blue
|
||||
style 32-47 fg=blue
|
||||
style 79-79 dim
|
||||
4| "│ ██▀▀▀▀▀████████████▄▄██▀ │"
|
||||
4| "│ █▄ ▀███ ▀███ │"
|
||||
style 0-0 dim
|
||||
style 28-51 fg=blue
|
||||
style 32-46 fg=blue
|
||||
style 79-79 dim
|
||||
5| "│ ██ ▀█████▄ ▀█████ │"
|
||||
5| "│ ▀█▄ ▀█████ │"
|
||||
style 0-0 dim
|
||||
style 28-50 fg=blue
|
||||
style 33-46 fg=blue
|
||||
style 79-79 dim
|
||||
6| "│ ██▄ ▀████▄ ▄████ │"
|
||||
6| "│ ▀█▄▄ █▄▄▀███▄ │"
|
||||
style 0-0 dim
|
||||
style 28-50 fg=blue
|
||||
style 33-46 fg=blue
|
||||
style 79-79 dim
|
||||
7| "│ ██▄ ████████▀ │"
|
||||
7| "│ ▀▀▀▀▀▀ │"
|
||||
style 0-0 dim
|
||||
style 29-50 fg=blue
|
||||
style 35-44 fg=blue
|
||||
style 79-79 dim
|
||||
8| "│ ██▄ ▄▄ ▀█████▀ │"
|
||||
style 0-0 dim
|
||||
style 29-49 fg=blue
|
||||
style 79-79 dim
|
||||
9| "│ ▀███▄▄▄███▄ ████▄▄ │"
|
||||
style 0-0 dim
|
||||
style 29-50 fg=blue
|
||||
style 79-79 dim
|
||||
10| "│ ▀▀▀███████▀▀ │"
|
||||
style 0-0 dim
|
||||
style 31-47 fg=blue
|
||||
style 79-79 dim
|
||||
11| "│ │"
|
||||
8| "│ │"
|
||||
style 0-0 dim
|
||||
style 79-79 dim
|
||||
12| "│ DeepSeek Harness │"
|
||||
9| "│ DeepSeek Harness │"
|
||||
style 0-0 dim
|
||||
style 32-47 fg=blue bold
|
||||
style 79-79 dim
|
||||
10| "│ │"
|
||||
style 0-0 dim
|
||||
style 79-79 dim
|
||||
11| "│ 感谢您愿意拨冗试用 DeepSeek Harness。当前版本仍处于内部测试阶段,功能仍待完 │"
|
||||
style 0-0 dim
|
||||
style 79-79 dim
|
||||
12| "│ 善,体验难免有些粗糙。 │"
|
||||
style 0-0 dim
|
||||
style 79-79 dim
|
||||
13| "│ │"
|
||||
style 0-0 dim
|
||||
style 79-79 dim
|
||||
14| "│ 感谢您愿意拨冗试用 DeepSeek Harness。 │"
|
||||
14| "│ “如切如磋,如琢如磨。” │"
|
||||
style 0-0 dim
|
||||
style 2-23 bold
|
||||
style 79-79 dim
|
||||
15| "│ │"
|
||||
style 0-0 dim
|
||||
style 79-79 dim
|
||||
16| "│ 目前的版本仍处于内部测试阶段,功能仍待完善,体验难免有些粗糙。 │"
|
||||
16| "│ 产品的成长,离不开一次次真实的碰撞与坦诚的反馈。您在真实使用中发现的问题,也 │"
|
||||
style 0-0 dim
|
||||
style 79-79 dim
|
||||
17| "│ │"
|
||||
17| "│ 可能促使我们重新审视,甚至推翻已有的设计。 │"
|
||||
style 0-0 dim
|
||||
style 79-79 dim
|
||||
18| "│ “如切如磋,如琢如磨。” │"
|
||||
style 0-0 dim
|
||||
style 2-23 bold
|
||||
style 79-79 dim
|
||||
19| "│ │"
|
||||
18| "│ │"
|
||||
style 0-0 dim
|
||||
style 79-79 dim
|
||||
20| "│ 产品的成长,离不开一次次真实的碰撞与坦诚的反馈。您在真实使用中发现的问题,也 │"
|
||||
19| "│ 为了帮助我们更准确地还原您真实使用中的问题,内测版本默认会上传所有 Session │"
|
||||
style 0-0 dim
|
||||
style 79-79 dim
|
||||
21| "│ 可能促使我们重新审视,甚至推翻已有的设计。 │"
|
||||
20| "│ Log;如需关闭,可以【关闭方式待补充】。另外,如果您有任何反馈与建议,请在企 │"
|
||||
style 0-0 dim
|
||||
style 79-79 dim
|
||||
22| "│ │"
|
||||
21| "│ 业微信群中留言告诉我们。每一条反馈,都会帮助我们把它打磨得更好。 │"
|
||||
style 0-0 dim
|
||||
style 79-79 dim
|
||||
23| "├──────────────────────────────────────────────────────────────────────────────┤"
|
||||
22| "├──────────────────────────────────────────────────────────────────────────────┤"
|
||||
style 0-79 dim
|
||||
24| "│ Enter 继续 │"
|
||||
23| "│ Enter 继续 │"
|
||||
style 0-0 dim
|
||||
style 34-44 fg=bright-magenta bold
|
||||
style 79-79 dim
|
||||
25| "│ ↑/↓ 滚动 ↓ │"
|
||||
24| "│ │"
|
||||
style 0-0 dim
|
||||
style 34-45 dim
|
||||
style 79-79 dim
|
||||
26| "╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||
25| "╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||
style 0-79 dim
|
||||
|
||||
@@ -60,6 +60,7 @@ function hostFixture(rows: number): {
|
||||
}
|
||||
|
||||
const copy = TUI_FIRST_RUN_WELCOME_NOTICE_COPY[TUI_FIRST_RUN_WELCOME_NOTICE_LOCALE]
|
||||
const openingSentence = `${copy.paragraphs[0]!.split('。', 1)[0]}。`
|
||||
const temporaryHomes: string[] = []
|
||||
|
||||
function withoutWhitespace(value: string): string {
|
||||
@@ -124,15 +125,17 @@ describe('TUI first-run welcome composition', () => {
|
||||
expect(createHash('sha256').update(icon).digest('hex'))
|
||||
.toBe('deba5f98a5c1796e20fcac3149bcd7eb8a32f0bdd04d048819400b1f28bd1439')
|
||||
expect(createHash('sha256').update(copy.paragraphs.join('\n')).digest('hex'))
|
||||
.toBe('e1b8ea95d9f8af276c4b2b76fff23fa068bdad61b5d4a10300600ed47572900d')
|
||||
.toBe('54389347f93109c7cb17baa4312ae55eaefe77cbbf2ffe3e7579a4538e9f5738')
|
||||
expect(TUI_FIRST_RUN_WELCOME_NOTICE_COPY.en).toBe(copy)
|
||||
})
|
||||
|
||||
it.each([
|
||||
{ columns: 60, inner: 50, rows: 30, tier: 'minimal' },
|
||||
{ columns: 80, inner: 68, rows: 30, tier: 'compact' },
|
||||
{ columns: 60, inner: 50, rows: 30, tier: undefined },
|
||||
{ columns: 80, inner: 68, rows: 30, tier: 'minimal' },
|
||||
{ columns: 100, inner: 84, rows: 34, tier: 'compact' },
|
||||
{ columns: 120, inner: 104, rows: 30, tier: 'full' },
|
||||
{ columns: 160, inner: 140, rows: 30, tier: 'full' },
|
||||
] as const)('renders the $tier composition at $columns columns without overdraw', ({ inner, rows, tier }) => {
|
||||
] as const)('renders the responsive composition at $columns columns without overdraw', ({ inner, rows, tier }) => {
|
||||
const fixture = hostFixture(rows)
|
||||
const component = new TuiFirstRunWelcomeComponent(fixture.host, copy, async () => {})
|
||||
const renderWidth = inner + 4
|
||||
@@ -140,7 +143,17 @@ describe('TUI first-run welcome composition', () => {
|
||||
|
||||
expect(tuiFirstRunWelcomeArtTier(inner, rows)).toBe(tier)
|
||||
expect(lines.every(line => tuiVisibleWidth(line) <= renderWidth)).toBe(true)
|
||||
expect(lines.join('\n')).toContain(TUI_FIRST_RUN_WELCOME_WHALE[tier].unicode[0]!.trim())
|
||||
if (tier === undefined) {
|
||||
expect(lines.join('\n')).not.toMatch(/[▀▄█]/u)
|
||||
} else {
|
||||
expect(lines.join('\n')).toContain(TUI_FIRST_RUN_WELCOME_WHALE[tier].unicode[0]!.trim())
|
||||
}
|
||||
const rendered = lines.join('\n')
|
||||
const placeholder = copy.paragraphs.at(-1)!.match(/【[^】]+】/u)![0]
|
||||
expect(rendered).not.toContain(copy.scrollHint)
|
||||
expect(rendered).toContain(copy.paragraphs.at(-1)!.match(/[A-Za-z]+ [A-Za-z]+/u)![0])
|
||||
expect(rendered).toContain(placeholder.slice(0, 3))
|
||||
expect(rendered).toContain(placeholder.slice(-3))
|
||||
expect(lines.join('\n')).toContain(`Enter ${copy.continueLabel}`)
|
||||
expect(lines.length).toBeLessThanOrEqual(Math.floor(rows * 0.9))
|
||||
expect(lines.length).toBeGreaterThan(5)
|
||||
@@ -151,12 +164,12 @@ describe('TUI first-run welcome composition', () => {
|
||||
const component = new TuiFirstRunWelcomeComponent(fixture.host, copy, async () => {})
|
||||
const initial = component.render(54).join('\n')
|
||||
expect(tuiFirstRunWelcomeArtTier(50, 10)).toBeUndefined()
|
||||
expect(initial).toContain(copy.paragraphs[0])
|
||||
expect(initial).toContain(openingSentence)
|
||||
expect(initial).toContain(`Enter ${copy.continueLabel}`)
|
||||
|
||||
component.handleInput('\x1b[F')
|
||||
const end = component.render(54).join('\n')
|
||||
expect(withoutWhitespace(end)).toContain(withoutWhitespace(copy.paragraphs.at(-1)!.slice(-10)))
|
||||
expect(withoutWhitespace(end)).toContain(withoutWhitespace(copy.paragraphs.at(-1)!.slice(-7)))
|
||||
expect(end).toContain(`Enter ${copy.continueLabel}`)
|
||||
|
||||
for (const key of ['\x1b[A', '\x1b[B', '\x1b[5~', '\x1b[6~', '\x1b[H', 'x']) {
|
||||
@@ -173,11 +186,20 @@ describe('TUI first-run welcome composition', () => {
|
||||
expect(lines.every(line => tuiVisibleWidth(line) <= 6)).toBe(true)
|
||||
})
|
||||
|
||||
it('keeps the side-by-side composition aligned when prose outgrows the full raster', () => {
|
||||
const fixture = hostFixture(40)
|
||||
const longCopy = { ...copy, paragraphs: [copy.paragraphs.join(' ').repeat(4)] }
|
||||
const component = new TuiFirstRunWelcomeComponent(fixture.host, longCopy, async () => {})
|
||||
const lines = component.render(100)
|
||||
expect(lines.length).toBeGreaterThan(TUI_FIRST_RUN_WELCOME_WHALE.full.unicode.length)
|
||||
expect(lines.every(line => tuiVisibleWidth(line) <= 100)).toBe(true)
|
||||
})
|
||||
|
||||
it('renders the bit-equivalent ASCII icon fallback for an explicitly non-Unicode terminal', () => {
|
||||
const fixture = hostFixture(30)
|
||||
const component = new TuiFirstRunWelcomeComponent(fixture.host, copy, async () => {}, true)
|
||||
const rendered = component.render(72).join('\n')
|
||||
expect(rendered).toContain(TUI_FIRST_RUN_WELCOME_WHALE.compact.ascii[0]!.trim())
|
||||
expect(rendered).toContain(TUI_FIRST_RUN_WELCOME_WHALE.minimal.ascii[0]!.trim())
|
||||
expect(rendered).not.toMatch(/[▀▄█]/u)
|
||||
})
|
||||
|
||||
@@ -264,6 +286,6 @@ describe('TUI first-run welcome composition', () => {
|
||||
|
||||
apply(ctx, { dshHome: home, asciiArt: true })
|
||||
expect(request?.create(fixture.host).render(72).join('\n'))
|
||||
.toContain(TUI_FIRST_RUN_WELCOME_WHALE.compact.ascii[0]!.trim())
|
||||
.toContain(TUI_FIRST_RUN_WELCOME_WHALE.minimal.ascii[0]!.trim())
|
||||
})
|
||||
})
|
||||
|
||||
@@ -172,6 +172,7 @@ function smoke(overrides: Partial<TuiPtySmokeOptions> & {
|
||||
}
|
||||
|
||||
const firstRunCopy = TUI_FIRST_RUN_WELCOME_NOTICE_COPY[TUI_FIRST_RUN_WELCOME_NOTICE_LOCALE]
|
||||
const firstRunOpeningSentence = `${firstRunCopy.paragraphs[0]!.split('。', 1)[0]}。`
|
||||
|
||||
/** Keep only the overlay rows, excluding platform-specific scrollback and the underlying TUI. */
|
||||
function overlaySnapshot(snapshot: string, columns: number, rows: number): string {
|
||||
@@ -220,11 +221,11 @@ const SELECT_PRO_MODEL = [
|
||||
|
||||
describe('dsh TUI keyless smoke (real Loader tree in a PTY)', () => {
|
||||
it.each([
|
||||
{ columns: 60, tier: 'minimal' },
|
||||
{ columns: 80, tier: 'compact' },
|
||||
{ columns: 60, tier: undefined },
|
||||
{ columns: 80, tier: 'minimal' },
|
||||
{ columns: 120, tier: 'full' },
|
||||
{ columns: 160, tier: 'full' },
|
||||
] as const)('renders and acknowledges the $tier first-run composition at $columns columns', async ({ columns, tier }) => {
|
||||
] as const)('renders and acknowledges the responsive first-run composition at $columns columns', async ({ columns, tier }) => {
|
||||
const output = await smoke({
|
||||
label: `dsh first-run welcome ${String(columns)} columns`,
|
||||
tempDirPrefix: `dsh-tui-welcome-${String(columns)}-`,
|
||||
@@ -251,9 +252,13 @@ describe('dsh TUI keyless smoke (real Loader tree in a PTY)', () => {
|
||||
}
|
||||
},
|
||||
})
|
||||
await expect(await firstRunFrameSnapshot(output, firstRunCopy.paragraphs[0]!, columns, 30))
|
||||
await expect(await firstRunFrameSnapshot(output, firstRunOpeningSentence, columns, 30))
|
||||
.toMatchFileSnapshot(join(firstRunSnapshots, `${String(columns)}-columns.expected.txt`))
|
||||
expect(output).toContain(TUI_FIRST_RUN_WELCOME_WHALE[tier].unicode[0]!.trim())
|
||||
if (tier === undefined) {
|
||||
expect(output).not.toContain(TUI_FIRST_RUN_WELCOME_WHALE.minimal.unicode[0]!.trim())
|
||||
} else {
|
||||
expect(output).toContain(TUI_FIRST_RUN_WELCOME_WHALE[tier].unicode[0]!.trim())
|
||||
}
|
||||
expect(output).toContain(`Enter ${firstRunCopy.continueLabel}`)
|
||||
}, PTY_SMOKE_TEST_TIMEOUT_MS)
|
||||
|
||||
@@ -267,7 +272,7 @@ describe('dsh TUI keyless smoke (real Loader tree in a PTY)', () => {
|
||||
columns: 60,
|
||||
rows: 12,
|
||||
actions: [
|
||||
{ waitFor: firstRunCopy.paragraphs[0]!, send: '\x1b[F' },
|
||||
{ waitFor: firstRunOpeningSentence, send: '\x1b[F' },
|
||||
{
|
||||
waitFor: `Enter ${firstRunCopy.continueLabel}`,
|
||||
occurrence: 2,
|
||||
@@ -276,10 +281,10 @@ describe('dsh TUI keyless smoke (real Loader tree in a PTY)', () => {
|
||||
},
|
||||
],
|
||||
})
|
||||
await expect(await firstRunFrameSnapshot(output, firstRunCopy.paragraphs[0]!, 60, 12))
|
||||
await expect(await firstRunFrameSnapshot(output, firstRunOpeningSentence, 60, 12))
|
||||
.toMatchFileSnapshot(join(firstRunSnapshots, '60-columns-low-height.expected.txt'))
|
||||
expect(output).toContain(firstRunCopy.title)
|
||||
expect(output).toContain(firstRunCopy.paragraphs[0])
|
||||
expect(output).toContain(firstRunOpeningSentence)
|
||||
expect(output).toContain('企业微信群')
|
||||
expect(output).toContain(`Enter ${firstRunCopy.continueLabel}`)
|
||||
expect(output).not.toContain(TUI_FIRST_RUN_WELCOME_WHALE.minimal.unicode[0]!.trim())
|
||||
@@ -310,7 +315,7 @@ describe('dsh TUI keyless smoke (real Loader tree in a PTY)', () => {
|
||||
expectedExitCode: process.platform === 'win32' ? 0 : -15,
|
||||
actions: [{ waitFor: 'main-session-', signal: 'SIGTERM' }],
|
||||
})
|
||||
expect(second).not.toContain(firstRunCopy.paragraphs[0])
|
||||
expect(second).not.toContain(firstRunOpeningSentence)
|
||||
expect(second).not.toContain(`Enter ${firstRunCopy.continueLabel}`)
|
||||
} finally {
|
||||
await rm(cwd, { recursive: true, force: true })
|
||||
@@ -327,7 +332,7 @@ describe('dsh TUI keyless smoke (real Loader tree in a PTY)', () => {
|
||||
configPath: scriptedConfigPath,
|
||||
showFirstRunWelcome: true,
|
||||
expectedExitCode: -15,
|
||||
actions: [{ waitFor: firstRunCopy.paragraphs[0]!, signal: 'SIGTERM' }],
|
||||
actions: [{ waitFor: firstRunOpeningSentence, signal: 'SIGTERM' }],
|
||||
inspect: async (workspace) => {
|
||||
expect(await hasTuiFirstRunWelcomeAcknowledgement(join(workspace, '.dsh'))).toBe(false)
|
||||
},
|
||||
@@ -344,7 +349,7 @@ describe('dsh TUI keyless smoke (real Loader tree in a PTY)', () => {
|
||||
{ waitFor: `Enter ${firstRunCopy.continueLabel}`, send: '\r', signalAfterMs: 2_000 },
|
||||
],
|
||||
})
|
||||
expect(next).toContain(firstRunCopy.paragraphs[0])
|
||||
expect(next).toContain(firstRunOpeningSentence)
|
||||
} finally {
|
||||
await rm(cwd, { recursive: true, force: true })
|
||||
}
|
||||
@@ -557,7 +562,7 @@ describe('dsh CLI keyless smoke (apps/cli through the same PTY)', () => {
|
||||
expect(appended).not.toContainEqual(expect.objectContaining({ type: 'turn/start' }))
|
||||
},
|
||||
})
|
||||
expect(output).toContain(firstRunCopy.paragraphs[0])
|
||||
expect(output).toContain(firstRunOpeningSentence)
|
||||
expect(output).toContain('Resume selector design — DeepSeek Harness')
|
||||
}, PTY_SMOKE_TEST_TIMEOUT_MS)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user