fix(settings): a tab-return read never undoes a pick or save made while it was out

- session-ui.js: drop the answer when the case-sync chain moved during the read; settings-ui.js calls _applyServerCaseSettings with ?.
- i18n.js: zh-CN for the failed case-options save toast, case name passed through
- tests: regression for the stale read, zh-CN toast row
This commit is contained in:
Devvyn committed 2026-11-09 14:01:09 +08:00
1 parent bb088bcd3e
commit 607c88afd9
5 files changed
+37 -2

No files matched your search

+5
View File
@@ -1734,6 +1734,11 @@
(_m, what, why) =>
`${what === 'Run mode' ? '运行模式' : '重生预设'}已保存到本设备,但未保存到服务器:${ZH_CN[why] || why}`,
],
// The case-options save (session-ui.js _pushCaseSettings): the case name passes through.
[
/^Options for "([^"]+)" \(until the next sync\) saved on this device, not on the server: ([\s\S]+)$/,
(_m, name, why) => `案例“${name}”的选项已保存到本设备(同步前有效),但未保存到服务器:${ZH_CN[why] || why}`,
],
// A dialog read off a hook-less CLI's screen (src/web/screen-blocked.ts), as the
// notification drawer shows it. The CLI's label passes through.
[/^(.+) is waiting for your answer in the terminal$/, (_m, cli) => `${cli} 正在终端中等待你的回答`],
+3 -1
View File
@@ -3775,11 +3775,13 @@ Object.assign(CodemanApp.prototype, {
if (this.loadAppSettingsFromStorage?.()?.syncCaseState !== true) return;
const seq = (this._caseSyncRefresh = (this._caseSyncRefresh || 0) + 1);
try {
await this._caseSyncChain; // this device's own saves land first, so the copy read next includes them
const chain = this._caseSyncChain;
await chain; // this device's own saves land first, so the copy read next includes them
const res = await fetch('/api/settings');
if (!res.ok) return;
const server = (await res.json())?.data ?? null;
if (seq !== this._caseSyncRefresh || !server) return; // a newer refresh owns the answer
if (this._caseSyncChain !== chain) return; // a save or pick made while the read was out is newer than it
this._adoptServerCaseSyncPreference(server);
if (server.syncCaseState !== true) return;
this._applyServerCaseSettings(server);
+1 -1
View File
@@ -5282,7 +5282,7 @@ Object.assign(CodemanApp.prototype, {
// installs that had saved `false` (agent-skill-default-migration.ts).
if (!('agentSkillEnabled' in appSettings)) delete merged.agentSkillEnabled;
this.saveAppSettingsToStorage(merged);
this._applyServerCaseSettings(settings);
this._applyServerCaseSettings?.(settings);
// Apply notification prefs from server if present (only if localStorage has none)
if (notificationPreferences && this.notificationManager) {