dsh-config-manager 0.1.62 → 0.1.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/README.zh-CN.md +10 -0
- package/lib/client.d.ts +1 -1
- package/lib/client.js +326 -327
- package/lib/index.js +1 -1
- package/lib/ui/backup-schedule.d.ts +4 -2
- package/lib/ui/backup-schedule.js +9 -6
- package/package.json +1 -1
- package/src/client/locales.ts +2 -2
- package/src/client/overview/OverviewPanel.tsx +1 -1
- package/src/index.ts +1 -1
- package/src/ui/backup-schedule.test.ts +12 -2
- package/src/ui/backup-schedule.ts +10 -7
- package/src/utils/env-lock.test.ts +37 -6
package/README.md
CHANGED
|
@@ -515,6 +515,18 @@ Yes. The import wizard asks for the export-time encryption password and verifies
|
|
|
515
515
|
5. **Encrypted backups**: a lost password means the `secrets.enc` can't be decrypted (by design — keep your password safe)
|
|
516
516
|
6. **Snapshot restore is offline and honest**: entries the offline engine can't restore (settings namespaces / patch lines when the snapshot has no whole-file backup, workspace records stored in DSH storages) are reported as skipped with a pointer to online rollback; credential **values** are never auto-written (manual re-entry hint only); old snapshots without a plugin baseline only get a hint to remove added plugins manually
|
|
517
517
|
|
|
518
|
+
## 🙏 Contributors
|
|
519
|
+
|
|
520
|
+
- **lux-liang (Jialiang Liang)** — [PR #44](https://github.com/xiajiajun516/dsh-config-manager/pull/44): independently fixed the
|
|
521
|
+
issue #43 "Back up now" false-success bug. Two details from that patch were more robust than the mainline implementation and
|
|
522
|
+
have been adopted into `main`: (1) when `failed` comes back with an empty / whitespace-only error text, fall back to the
|
|
523
|
+
generic message instead of rendering a dangling "Backup failed:"; (2) an unknown `skipReason` is mapped to a localized
|
|
524
|
+
message rather than echoing the raw machine token. Because that PR was closed as superseded, **his commits never landed and
|
|
525
|
+
he does not appear in GitHub's Contributors graph** — so he is credited here.
|
|
526
|
+
- **Bug reports**: `zhyx1996` (#38 sync "Export secrets" did nothing), `IPF-Sinon` (#39 the `.credentials.yaml` `refs:` block
|
|
527
|
+
was not recognized — they also implemented and machine-tested a fix in their own fork), `zerginlaw` (#43 "Back up now"
|
|
528
|
+
silently no-oped while toasting success). Each report drove one fix.
|
|
529
|
+
|
|
518
530
|
> Maintainers & developers: see [DEVELOPERS.md](DEVELOPERS.md) for build, testing, auto-publishing and full technical notes.
|
|
519
531
|
|
|
520
532
|
---
|
package/README.zh-CN.md
CHANGED
|
@@ -454,6 +454,16 @@ dsh-config-manager backup --sections skills,self # 收窄范围
|
|
|
454
454
|
6. **快照恢复是离线的、诚实的**:离线引擎无法恢复的条目(快照无整文件备份时的 settings namespace / patch 行、存在 DSH storages 里的 workspace 记录)会如实列为跳过并指向在线回滚;凭据**值**绝不自动改写(只提示人工补录);无插件基线的旧快照只提示人工核对新增插件
|
|
455
455
|
7. **本地源插件(`link:` / `file:`)随备份打包**:导出时执行 `npm pack` 把本地开发中的插件打成 tarball 一并备份,导入时解包到 `$DSH_HOME/dsh-config-manager/local-plugins/` 后按 `file:` 安装。因此:① 备份体积会随本地插件的体积增大(单插件超过 100 MB 会被跳过并告警,建议先发布到 registry / git 再备份);② 插件**源码**会进入备份(与「密钥永不进备份」不冲突——密钥仍被排除,这里进的是代码);③ 打包需要本机有可用的 `npm`,无 npm 时该插件退化为原行为(保留原 spec,换机后仍需手工安装)
|
|
456
456
|
|
|
457
|
+
## 🙏 贡献者
|
|
458
|
+
|
|
459
|
+
- **lux-liang (Jialiang Liang)** —— [PR #44](https://github.com/xiajiajun516/dsh-config-manager/pull/44):独立修复了 issue #43
|
|
460
|
+
「立即备份」假报成功的问题。其中两点比主线实现更稳,已采纳进 `main`:① `failed` 且宿主错误文本为空 / 全空白时
|
|
461
|
+
回退通用文案(否则会渲染出「备份失败:」这种半截提示);② 未知 `skipReason` 归一为本地化说明,不把机器 token
|
|
462
|
+
摆到用户面前。他的提交未合并(该 PR 作为 superseded 关闭),因此**不会出现在 GitHub 的 Contributors 图上** ——
|
|
463
|
+
名单在此登记。
|
|
464
|
+
- **问题报告**:`zhyx1996`(#38 同步「导出密钥」未生效)、`IPF-Sinon`(#39 凭据 `refs:` 块未被识别,并在自己的 fork
|
|
465
|
+
上完成实现与真机验证)、`zerginlaw`(#43「立即备份」空转却提示成功)—— 这三条报告各自驱动了一个修复。
|
|
466
|
+
|
|
457
467
|
> 维护者与开发者:构建、测试、自动发布与完整技术说明见 [DEVELOPERS.md](DEVELOPERS.md)。
|
|
458
468
|
|
|
459
469
|
---
|
package/lib/client.d.ts
CHANGED
|
@@ -2627,7 +2627,7 @@ declare const zh$3: {
|
|
|
2627
2627
|
readonly 'overview.quick.backupSkippedRunning': '已跳过:上一次备份仍在进行中';
|
|
2628
2628
|
readonly 'overview.quick.backupSkippedConflict': '已跳过:另一项任务正在执行(防重)';
|
|
2629
2629
|
readonly 'overview.quick.backupSkippedLocked': '已跳过:环境锁被占用(另一项任务进行中,或存在需回收的残留锁)';
|
|
2630
|
-
readonly 'overview.quick.backupSkippedOther': '
|
|
2630
|
+
readonly 'overview.quick.backupSkippedOther': '已跳过:备份服务当前无法执行(详情见宿主日志)';
|
|
2631
2631
|
readonly 'overview.quick.backupFailed': '备份失败:{message}';
|
|
2632
2632
|
readonly 'overview.quick.sync': '远程同步';
|
|
2633
2633
|
readonly 'overview.activity.title': '最近活动';
|
package/lib/client.js
CHANGED
|
@@ -4348,8 +4348,11 @@ function backupDraftDirty(draft, saved) {
|
|
|
4348
4348
|
* (见 src/index.ts 的 backup-schedule/run 路由),所以**不能**用「有没有抛异常」判成败 ——
|
|
4349
4349
|
* 那会把「定时备份未启用 → 一个备份文件都没产出」读成「备份完成」。
|
|
4350
4350
|
*
|
|
4351
|
-
* 本函数只做语义投影(零文案):success → ok;skipped → 结构化 reason
|
|
4351
|
+
* 本函数只做语义投影(零文案):success → ok;skipped → 结构化 reason(**未知 token 归一为 other**,
|
|
4352
|
+
* 绝不把机器 token 原样摆到用户面前——仓库既有纪律:用户可见文本里不留裸 token);
|
|
4352
4353
|
* 其余(含 failed 与未来新增 status)→ error,fail-safe 地绝不宣称成功。
|
|
4354
|
+
* `failed` 但宿主没给出可用错误文本(undefined / 空串 / 全空白)→ message 为 null,由壳层回退通用文案
|
|
4355
|
+
* (否则会渲染出「备份失败:」这种半截提示)。
|
|
4353
4356
|
*/
|
|
4354
4357
|
function backupRunOutcome(run) {
|
|
4355
4358
|
switch (run.status) {
|
|
@@ -4371,18 +4374,14 @@ function backupRunOutcome(run) {
|
|
|
4371
4374
|
kind: "skipped",
|
|
4372
4375
|
reason: "locked"
|
|
4373
4376
|
};
|
|
4374
|
-
default: return
|
|
4377
|
+
default: return {
|
|
4375
4378
|
kind: "skipped",
|
|
4376
4379
|
reason: "other"
|
|
4377
|
-
} : {
|
|
4378
|
-
kind: "skipped",
|
|
4379
|
-
reason: "other",
|
|
4380
|
-
raw: run.skipReason
|
|
4381
4380
|
};
|
|
4382
4381
|
}
|
|
4383
4382
|
default: return {
|
|
4384
4383
|
kind: "error",
|
|
4385
|
-
message: run.error
|
|
4384
|
+
message: run.error !== void 0 && run.error.trim() !== "" ? run.error : null
|
|
4386
4385
|
};
|
|
4387
4386
|
}
|
|
4388
4387
|
}
|
|
@@ -4810,357 +4809,357 @@ if (typeof document !== "undefined" && document.querySelector("style[data-tag=\"
|
|
|
4810
4809
|
document.head.appendChild(tag);
|
|
4811
4810
|
}
|
|
4812
4811
|
var config_manager_module_css_default = {
|
|
4813
|
-
"
|
|
4814
|
-
"
|
|
4815
|
-
"
|
|
4816
|
-
"
|
|
4817
|
-
"
|
|
4818
|
-
"
|
|
4819
|
-
"
|
|
4820
|
-
"
|
|
4821
|
-
"
|
|
4822
|
-
"stepperStep": "_367UGW_stepperStep",
|
|
4823
|
-
"segGroup": "_367UGW_segGroup",
|
|
4824
|
-
"optionsCard": "_367UGW_optionsCard",
|
|
4812
|
+
"spinnerWrap": "_367UGW_spinnerWrap",
|
|
4813
|
+
"groupNote": "_367UGW_groupNote",
|
|
4814
|
+
"rowDivider": "_367UGW_rowDivider",
|
|
4815
|
+
"pickerFooter": "_367UGW_pickerFooter",
|
|
4816
|
+
"progressBlock": "_367UGW_progressBlock",
|
|
4817
|
+
"wizardCard": "_367UGW_wizardCard",
|
|
4818
|
+
"snapshotList": "_367UGW_snapshotList",
|
|
4819
|
+
"viewBody": "_367UGW_viewBody",
|
|
4820
|
+
"statusMeta": "_367UGW_statusMeta",
|
|
4825
4821
|
"statusDot": "_367UGW_statusDot",
|
|
4822
|
+
"activityRows": "_367UGW_activityRows",
|
|
4823
|
+
"dialogMask": "_367UGW_dialogMask",
|
|
4824
|
+
"statusPulse": "_367UGW_statusPulse",
|
|
4825
|
+
"progressTrack": "_367UGW_progressTrack",
|
|
4826
|
+
"diffCellAdd": "_367UGW_diffCellAdd",
|
|
4827
|
+
"statGrid": "_367UGW_statGrid",
|
|
4828
|
+
"dialogCard": "_367UGW_dialogCard",
|
|
4829
|
+
"ghostButton": "_367UGW_ghostButton",
|
|
4830
|
+
"pickerUnitName": "_367UGW_pickerUnitName",
|
|
4831
|
+
"errorAction": "_367UGW_errorAction",
|
|
4832
|
+
"diffStatAdd": "_367UGW_diffStatAdd",
|
|
4833
|
+
"noticeSlot": "_367UGW_noticeSlot",
|
|
4826
4834
|
"metricGrid": "_367UGW_metricGrid",
|
|
4827
|
-
"
|
|
4828
|
-
"
|
|
4829
|
-
"
|
|
4830
|
-
"
|
|
4831
|
-
"
|
|
4832
|
-
"
|
|
4833
|
-
"
|
|
4835
|
+
"scheduleFacts": "_367UGW_scheduleFacts",
|
|
4836
|
+
"categoryName": "_367UGW_categoryName",
|
|
4837
|
+
"planScroll": "_367UGW_planScroll",
|
|
4838
|
+
"sparseFill": "_367UGW_sparseFill",
|
|
4839
|
+
"progressBadgeCount": "_367UGW_progressBadgeCount",
|
|
4840
|
+
"profileRowTitle": "_367UGW_profileRowTitle",
|
|
4841
|
+
"tableScroll": "_367UGW_tableScroll",
|
|
4842
|
+
"banner": "_367UGW_banner",
|
|
4843
|
+
"progressMeta": "_367UGW_progressMeta",
|
|
4844
|
+
"toolRow": "_367UGW_toolRow",
|
|
4845
|
+
"radioLabel": "_367UGW_radioLabel",
|
|
4846
|
+
"pickerGroup": "_367UGW_pickerGroup",
|
|
4847
|
+
"modeHint": "_367UGW_modeHint",
|
|
4848
|
+
"ovActivityText": "_367UGW_ovActivityText",
|
|
4834
4849
|
"conflictLine": "_367UGW_conflictLine",
|
|
4835
|
-
"ovActivity": "_367UGW_ovActivity",
|
|
4836
|
-
"select": "_367UGW_select",
|
|
4837
|
-
"errorTitle": "_367UGW_errorTitle",
|
|
4838
|
-
"statValueSmall": "_367UGW_statValueSmall",
|
|
4839
|
-
"rowDivider": "_367UGW_rowDivider",
|
|
4840
|
-
"ghostButton": "_367UGW_ghostButton",
|
|
4841
|
-
"errorList": "_367UGW_errorList",
|
|
4842
|
-
"historyMeta": "_367UGW_historyMeta",
|
|
4843
|
-
"restorePlanChevron": "_367UGW_restorePlanChevron",
|
|
4844
|
-
"logLine": "_367UGW_logLine",
|
|
4845
|
-
"kvValue": "_367UGW_kvValue",
|
|
4846
|
-
"pickerModalBody": "_367UGW_pickerModalBody",
|
|
4847
4850
|
"activityRow": "_367UGW_activityRow",
|
|
4848
|
-
"
|
|
4849
|
-
"
|
|
4850
|
-
"
|
|
4851
|
-
"
|
|
4852
|
-
"infoRow": "_367UGW_infoRow",
|
|
4853
|
-
"groupNote": "_367UGW_groupNote",
|
|
4854
|
-
"groupLabel": "_367UGW_groupLabel",
|
|
4855
|
-
"rowActions": "_367UGW_rowActions",
|
|
4856
|
-
"historyRowMain": "_367UGW_historyRowMain",
|
|
4857
|
-
"activityKind": "_367UGW_activityKind",
|
|
4858
|
-
"spinner": "_367UGW_spinner",
|
|
4859
|
-
"hint": "_367UGW_hint",
|
|
4860
|
-
"sectionSize": "_367UGW_sectionSize",
|
|
4861
|
-
"pickerMore": "_367UGW_pickerMore",
|
|
4851
|
+
"pickerSubgroupName": "_367UGW_pickerSubgroupName",
|
|
4852
|
+
"restorePlanGroupHead": "_367UGW_restorePlanGroupHead",
|
|
4853
|
+
"diffCell": "_367UGW_diffCell",
|
|
4854
|
+
"logEmpty": "_367UGW_logEmpty",
|
|
4862
4855
|
"diffCellDel": "_367UGW_diffCellDel",
|
|
4863
|
-
"
|
|
4864
|
-
"
|
|
4865
|
-
"
|
|
4866
|
-
"
|
|
4867
|
-
"
|
|
4868
|
-
"
|
|
4869
|
-
"
|
|
4856
|
+
"fieldLabel": "_367UGW_fieldLabel",
|
|
4857
|
+
"num": "_367UGW_num",
|
|
4858
|
+
"statHealthAction": "_367UGW_statHealthAction",
|
|
4859
|
+
"segGroup": "_367UGW_segGroup",
|
|
4860
|
+
"historyMeta": "_367UGW_historyMeta",
|
|
4861
|
+
"profileRowName": "_367UGW_profileRowName",
|
|
4862
|
+
"restorePlanChevron": "_367UGW_restorePlanChevron",
|
|
4863
|
+
"aboutLinkRow": "_367UGW_aboutLinkRow",
|
|
4864
|
+
"pathNew": "_367UGW_pathNew",
|
|
4865
|
+
"dialogClose": "_367UGW_dialogClose",
|
|
4866
|
+
"statSeg": "_367UGW_statSeg",
|
|
4867
|
+
"sectionDivider": "_367UGW_sectionDivider",
|
|
4870
4868
|
"factValue": "_367UGW_factValue",
|
|
4869
|
+
"pickerToolbar": "_367UGW_pickerToolbar",
|
|
4870
|
+
"factLabel": "_367UGW_factLabel",
|
|
4871
|
+
"sectionName": "_367UGW_sectionName",
|
|
4872
|
+
"factGrid": "_367UGW_factGrid",
|
|
4873
|
+
"sectionSize": "_367UGW_sectionSize",
|
|
4874
|
+
"pickerRoot": "_367UGW_pickerRoot",
|
|
4875
|
+
"pickerSubgroup": "_367UGW_pickerSubgroup",
|
|
4871
4876
|
"profileRow": "_367UGW_profileRow",
|
|
4872
|
-
"
|
|
4873
|
-
"
|
|
4874
|
-
"
|
|
4875
|
-
"
|
|
4876
|
-
"dataTable": "_367UGW_dataTable",
|
|
4877
|
-
"statusText": "_367UGW_statusText",
|
|
4878
|
-
"cellMeta": "_367UGW_cellMeta",
|
|
4879
|
-
"sparseFill": "_367UGW_sparseFill",
|
|
4880
|
-
"conflictList": "_367UGW_conflictList",
|
|
4881
|
-
"diffStatTotal": "_367UGW_diffStatTotal",
|
|
4882
|
-
"diffHunkRow": "_367UGW_diffHunkRow",
|
|
4883
|
-
"conflictId": "_367UGW_conflictId",
|
|
4884
|
-
"snapshotList": "_367UGW_snapshotList",
|
|
4885
|
-
"severityError": "_367UGW_severityError",
|
|
4886
|
-
"sectionTitleBlock": "_367UGW_sectionTitleBlock",
|
|
4887
|
-
"planScroll": "_367UGW_planScroll",
|
|
4888
|
-
"backupFileMeta": "_367UGW_backupFileMeta",
|
|
4889
|
-
"quickGrid": "_367UGW_quickGrid",
|
|
4890
|
-
"dialogBodyScroll": "_367UGW_dialogBodyScroll",
|
|
4891
|
-
"historySummary": "_367UGW_historySummary",
|
|
4892
|
-
"profileRowHeader": "_367UGW_profileRowHeader",
|
|
4893
|
-
"statCard": "_367UGW_statCard",
|
|
4894
|
-
"navTab": "_367UGW_navTab",
|
|
4895
|
-
"statValue": "_367UGW_statValue",
|
|
4896
|
-
"indet": "_367UGW_indet",
|
|
4897
|
-
"errorFooter": "_367UGW_errorFooter",
|
|
4898
|
-
"activityTitle": "_367UGW_activityTitle",
|
|
4877
|
+
"hint": "_367UGW_hint",
|
|
4878
|
+
"authorRow": "_367UGW_authorRow",
|
|
4879
|
+
"shellMain": "_367UGW_shellMain",
|
|
4880
|
+
"dialogWide": "_367UGW_dialogWide",
|
|
4899
4881
|
"toast": "_367UGW_toast",
|
|
4900
|
-
"
|
|
4901
|
-
"
|
|
4902
|
-
"
|
|
4903
|
-
"activityBadge": "_367UGW_activityBadge",
|
|
4904
|
-
"fillViewport": "_367UGW_fillViewport",
|
|
4905
|
-
"pathOld": "_367UGW_pathOld",
|
|
4906
|
-
"consultScroll": "_367UGW_consultScroll",
|
|
4907
|
-
"marketReviewPage": "_367UGW_marketReviewPage",
|
|
4908
|
-
"restorePlanRow": "_367UGW_restorePlanRow",
|
|
4909
|
-
"drawerBody": "_367UGW_drawerBody",
|
|
4910
|
-
"todoRow": "_367UGW_todoRow",
|
|
4911
|
-
"cellMetaNoteText": "_367UGW_cellMetaNoteText",
|
|
4912
|
-
"dialogBody": "_367UGW_dialogBody",
|
|
4913
|
-
"snapshotPickerHint": "_367UGW_snapshotPickerHint",
|
|
4914
|
-
"fillCard": "_367UGW_fillCard",
|
|
4915
|
-
"shellNav": "_367UGW_shellNav",
|
|
4916
|
-
"drawerTitle": "_367UGW_drawerTitle",
|
|
4882
|
+
"pickerModalBody": "_367UGW_pickerModalBody",
|
|
4883
|
+
"historyGroup": "_367UGW_historyGroup",
|
|
4884
|
+
"tableFixed": "_367UGW_tableFixed",
|
|
4917
4885
|
"navDot": "_367UGW_navDot",
|
|
4918
|
-
"
|
|
4919
|
-
"pickerOverlay": "_367UGW_pickerOverlay",
|
|
4886
|
+
"modeTab": "_367UGW_modeTab",
|
|
4920
4887
|
"reportHeadline": "_367UGW_reportHeadline",
|
|
4921
|
-
"
|
|
4922
|
-
"
|
|
4888
|
+
"pickerTreeRow": "_367UGW_pickerTreeRow",
|
|
4889
|
+
"kvRow": "_367UGW_kvRow",
|
|
4890
|
+
"conflictHead": "_367UGW_conflictHead",
|
|
4891
|
+
"cellMetaNote": "_367UGW_cellMetaNote",
|
|
4892
|
+
"pickerAction": "_367UGW_pickerAction",
|
|
4893
|
+
"reasonList": "_367UGW_reasonList",
|
|
4894
|
+
"backupFileMeta": "_367UGW_backupFileMeta",
|
|
4895
|
+
"pickerUnitDetail": "_367UGW_pickerUnitDetail",
|
|
4896
|
+
"errorLine": "_367UGW_errorLine",
|
|
4923
4897
|
"nextStepsGroup": "_367UGW_nextStepsGroup",
|
|
4898
|
+
"errorReason": "_367UGW_errorReason",
|
|
4899
|
+
"infoGrid": "_367UGW_infoGrid",
|
|
4900
|
+
"reportBody": "_367UGW_reportBody",
|
|
4901
|
+
"reportList": "_367UGW_reportList",
|
|
4902
|
+
"optionsHeader": "_367UGW_optionsHeader",
|
|
4903
|
+
"noticeLine": "_367UGW_noticeLine",
|
|
4904
|
+
"errorFooter": "_367UGW_errorFooter",
|
|
4905
|
+
"listHeaderRow": "_367UGW_listHeaderRow",
|
|
4906
|
+
"metricLabel": "_367UGW_metricLabel",
|
|
4907
|
+
"consultScroll": "_367UGW_consultScroll",
|
|
4908
|
+
"quickAction": "_367UGW_quickAction",
|
|
4909
|
+
"navStrip": "_367UGW_navStrip",
|
|
4910
|
+
"activityEmpty": "_367UGW_activityEmpty",
|
|
4911
|
+
"spinner": "_367UGW_spinner",
|
|
4912
|
+
"snapshotPickerRow": "_367UGW_snapshotPickerRow",
|
|
4913
|
+
"diffStatDel": "_367UGW_diffStatDel",
|
|
4924
4914
|
"progressBadge": "_367UGW_progressBadge",
|
|
4925
|
-
"
|
|
4926
|
-
"
|
|
4927
|
-
"
|
|
4928
|
-
"
|
|
4929
|
-
"
|
|
4930
|
-
"
|
|
4931
|
-
"
|
|
4932
|
-
"
|
|
4933
|
-
"
|
|
4915
|
+
"groupHeader": "_367UGW_groupHeader",
|
|
4916
|
+
"copyBtn": "_367UGW_copyBtn",
|
|
4917
|
+
"kvKey": "_367UGW_kvKey",
|
|
4918
|
+
"quickActionSymbol": "_367UGW_quickActionSymbol",
|
|
4919
|
+
"conflictChoices": "_367UGW_conflictChoices",
|
|
4920
|
+
"spin": "_367UGW_spin",
|
|
4921
|
+
"card": "_367UGW_card",
|
|
4922
|
+
"errorList": "_367UGW_errorList",
|
|
4923
|
+
"toastViewport": "_367UGW_toastViewport",
|
|
4924
|
+
"optionsRow": "_367UGW_optionsRow",
|
|
4925
|
+
"scheduleRow": "_367UGW_scheduleRow",
|
|
4926
|
+
"profileRowHeader": "_367UGW_profileRowHeader",
|
|
4927
|
+
"diffNoHead": "_367UGW_diffNoHead",
|
|
4928
|
+
"logHeader": "_367UGW_logHeader",
|
|
4929
|
+
"stepper": "_367UGW_stepper",
|
|
4930
|
+
"dialogBody": "_367UGW_dialogBody",
|
|
4931
|
+
"marketReviewPage": "_367UGW_marketReviewPage",
|
|
4932
|
+
"statCard": "_367UGW_statCard",
|
|
4933
|
+
"activityTime": "_367UGW_activityTime",
|
|
4934
|
+
"dialogBodyScroll": "_367UGW_dialogBodyScroll",
|
|
4934
4935
|
"toastGlyph": "_367UGW_toastGlyph",
|
|
4936
|
+
"mono": "_367UGW_mono",
|
|
4937
|
+
"warnText": "_367UGW_warnText",
|
|
4938
|
+
"historySummary": "_367UGW_historySummary",
|
|
4939
|
+
"segItem": "_367UGW_segItem",
|
|
4940
|
+
"metricCard": "_367UGW_metricCard",
|
|
4941
|
+
"activityBadge": "_367UGW_activityBadge",
|
|
4942
|
+
"syncChannelHead": "_367UGW_syncChannelHead",
|
|
4943
|
+
"infoValue": "_367UGW_infoValue",
|
|
4944
|
+
"stepperStep": "_367UGW_stepperStep",
|
|
4945
|
+
"kindTagError": "_367UGW_kindTagError",
|
|
4935
4946
|
"activityHeader": "_367UGW_activityHeader",
|
|
4936
|
-
"
|
|
4937
|
-
"
|
|
4938
|
-
"
|
|
4939
|
-
"
|
|
4940
|
-
"
|
|
4941
|
-
"
|
|
4942
|
-
"
|
|
4943
|
-
"
|
|
4944
|
-
"
|
|
4945
|
-
"
|
|
4946
|
-
"
|
|
4947
|
-
"sectionGrid": "_367UGW_sectionGrid",
|
|
4947
|
+
"statusText": "_367UGW_statusText",
|
|
4948
|
+
"activitySummary": "_367UGW_activitySummary",
|
|
4949
|
+
"groupItems": "_367UGW_groupItems",
|
|
4950
|
+
"compositionViewport": "_367UGW_compositionViewport",
|
|
4951
|
+
"navTab": "_367UGW_navTab",
|
|
4952
|
+
"todoRow": "_367UGW_todoRow",
|
|
4953
|
+
"pickerCount": "_367UGW_pickerCount",
|
|
4954
|
+
"input": "_367UGW_input",
|
|
4955
|
+
"consultSection": "_367UGW_consultSection",
|
|
4956
|
+
"aboutAuthor": "_367UGW_aboutAuthor",
|
|
4957
|
+
"formError": "_367UGW_formError",
|
|
4948
4958
|
"kbd": "_367UGW_kbd",
|
|
4949
|
-
"
|
|
4950
|
-
"
|
|
4951
|
-
"
|
|
4952
|
-
"
|
|
4953
|
-
"
|
|
4954
|
-
"
|
|
4955
|
-
"
|
|
4956
|
-
"
|
|
4957
|
-
"
|
|
4958
|
-
"
|
|
4959
|
-
"
|
|
4960
|
-
"
|
|
4961
|
-
"dialogHeader": "_367UGW_dialogHeader",
|
|
4962
|
-
"dialogContentCenter": "_367UGW_dialogContentCenter",
|
|
4963
|
-
"backupFileRow": "_367UGW_backupFileRow",
|
|
4964
|
-
"dangerButton": "_367UGW_dangerButton",
|
|
4965
|
-
"aboutLinkRow": "_367UGW_aboutLinkRow",
|
|
4966
|
-
"factCell": "_367UGW_factCell",
|
|
4959
|
+
"metricValue": "_367UGW_metricValue",
|
|
4960
|
+
"marketFilterSearch": "_367UGW_marketFilterSearch",
|
|
4961
|
+
"pickerMore": "_367UGW_pickerMore",
|
|
4962
|
+
"conflictList": "_367UGW_conflictList",
|
|
4963
|
+
"activitySummaryText": "_367UGW_activitySummaryText",
|
|
4964
|
+
"groupLabel": "_367UGW_groupLabel",
|
|
4965
|
+
"progressBadgeSection": "_367UGW_progressBadgeSection",
|
|
4966
|
+
"conflictPrefix": "_367UGW_conflictPrefix",
|
|
4967
|
+
"pathIssueKind": "_367UGW_pathIssueKind",
|
|
4968
|
+
"backupFileList": "_367UGW_backupFileList",
|
|
4969
|
+
"errorTitle": "_367UGW_errorTitle",
|
|
4970
|
+
"groupCard": "_367UGW_groupCard",
|
|
4967
4971
|
"kindTagInfo": "_367UGW_kindTagInfo",
|
|
4968
|
-
"
|
|
4969
|
-
"modeTab": "_367UGW_modeTab",
|
|
4970
|
-
"logJumpButton": "_367UGW_logJumpButton",
|
|
4971
|
-
"ovMain": "_367UGW_ovMain",
|
|
4972
|
-
"progressBadgeCount": "_367UGW_progressBadgeCount",
|
|
4973
|
-
"diffPane": "_367UGW_diffPane",
|
|
4972
|
+
"activityKind": "_367UGW_activityKind",
|
|
4974
4973
|
"progressDetail": "_367UGW_progressDetail",
|
|
4975
|
-
"
|
|
4976
|
-
"
|
|
4977
|
-
"
|
|
4978
|
-
"
|
|
4979
|
-
"
|
|
4980
|
-
"
|
|
4981
|
-
"
|
|
4982
|
-
"
|
|
4983
|
-
"
|
|
4984
|
-
"pickerGroup": "_367UGW_pickerGroup",
|
|
4985
|
-
"spinnerLabel": "_367UGW_spinnerLabel",
|
|
4986
|
-
"consultDimension": "_367UGW_consultDimension",
|
|
4987
|
-
"reportBody": "_367UGW_reportBody",
|
|
4988
|
-
"drawerMask": "_367UGW_drawerMask",
|
|
4989
|
-
"emptyHeroSymbol": "_367UGW_emptyHeroSymbol",
|
|
4990
|
-
"sectionDivider": "_367UGW_sectionDivider",
|
|
4991
|
-
"pickerTreeRow": "_367UGW_pickerTreeRow",
|
|
4992
|
-
"kvRow": "_367UGW_kvRow",
|
|
4993
|
-
"diffScroll": "_367UGW_diffScroll",
|
|
4994
|
-
"diffTable": "_367UGW_diffTable",
|
|
4995
|
-
"card": "_367UGW_card",
|
|
4996
|
-
"tabRow": "_367UGW_tabRow",
|
|
4997
|
-
"quickActionSymbol": "_367UGW_quickActionSymbol",
|
|
4998
|
-
"empty": "_367UGW_empty",
|
|
4999
|
-
"snapshotRowHeader": "_367UGW_snapshotRowHeader",
|
|
5000
|
-
"restorePlanRowStatic": "_367UGW_restorePlanRowStatic",
|
|
5001
|
-
"exportGrid": "_367UGW_exportGrid",
|
|
5002
|
-
"modeHint": "_367UGW_modeHint",
|
|
5003
|
-
"hiddenFile": "_367UGW_hiddenFile",
|
|
5004
|
-
"factGrid": "_367UGW_factGrid",
|
|
5005
|
-
"syncChannelHead": "_367UGW_syncChannelHead",
|
|
5006
|
-
"shellMain": "_367UGW_shellMain",
|
|
5007
|
-
"quickActionTitle": "_367UGW_quickActionTitle",
|
|
5008
|
-
"compositionViewport": "_367UGW_compositionViewport",
|
|
5009
|
-
"pathMappingList": "_367UGW_pathMappingList",
|
|
5010
|
-
"activityTime": "_367UGW_activityTime",
|
|
5011
|
-
"restorePlanPath": "_367UGW_restorePlanPath",
|
|
5012
|
-
"cellMetaNote": "_367UGW_cellMetaNote",
|
|
5013
|
-
"progressMeta": "_367UGW_progressMeta",
|
|
5014
|
-
"pickerCount": "_367UGW_pickerCount",
|
|
5015
|
-
"tableFixed": "_367UGW_tableFixed",
|
|
5016
|
-
"groupHeader": "_367UGW_groupHeader",
|
|
5017
|
-
"infoGrid": "_367UGW_infoGrid",
|
|
5018
|
-
"conflictHead": "_367UGW_conflictHead",
|
|
5019
|
-
"reportFooter": "_367UGW_reportFooter",
|
|
5020
|
-
"restorePlanNote": "_367UGW_restorePlanNote",
|
|
5021
|
-
"categoryName": "_367UGW_categoryName",
|
|
5022
|
-
"pathValue": "_367UGW_pathValue",
|
|
5023
|
-
"pickerChevronSpacer": "_367UGW_pickerChevronSpacer",
|
|
5024
|
-
"statHealth": "_367UGW_statHealth",
|
|
5025
|
-
"confirmScroll": "_367UGW_confirmScroll",
|
|
5026
|
-
"mono": "_367UGW_mono",
|
|
5027
|
-
"headRow": "_367UGW_headRow",
|
|
5028
|
-
"pathIssueKind": "_367UGW_pathIssueKind",
|
|
5029
|
-
"pullScroll": "_367UGW_pullScroll",
|
|
4974
|
+
"historySections": "_367UGW_historySections",
|
|
4975
|
+
"kindTagWarn": "_367UGW_kindTagWarn",
|
|
4976
|
+
"cellActions": "_367UGW_cellActions",
|
|
4977
|
+
"quickActionHint": "_367UGW_quickActionHint",
|
|
4978
|
+
"historyScroll": "_367UGW_historyScroll",
|
|
4979
|
+
"conflictId": "_367UGW_conflictId",
|
|
4980
|
+
"statusSpacer": "_367UGW_statusSpacer",
|
|
4981
|
+
"secretsList": "_367UGW_secretsList",
|
|
4982
|
+
"pickerOverlay": "_367UGW_pickerOverlay",
|
|
5030
4983
|
"cliName": "_367UGW_cliName",
|
|
5031
|
-
"
|
|
5032
|
-
"
|
|
5033
|
-
"
|
|
4984
|
+
"sectionCount": "_367UGW_sectionCount",
|
|
4985
|
+
"checkboxRow": "_367UGW_checkboxRow",
|
|
4986
|
+
"historyRow": "_367UGW_historyRow",
|
|
4987
|
+
"modeTabs": "_367UGW_modeTabs",
|
|
4988
|
+
"ovActivityTime": "_367UGW_ovActivityTime",
|
|
4989
|
+
"cliCommand": "_367UGW_cliCommand",
|
|
4990
|
+
"historyTime": "_367UGW_historyTime",
|
|
4991
|
+
"marketFilterMeta": "_367UGW_marketFilterMeta",
|
|
4992
|
+
"toastText": "_367UGW_toastText",
|
|
4993
|
+
"diffPane": "_367UGW_diffPane",
|
|
4994
|
+
"ovActivityItem": "_367UGW_ovActivityItem",
|
|
4995
|
+
"cellMeta": "_367UGW_cellMeta",
|
|
4996
|
+
"pickerUnit": "_367UGW_pickerUnit",
|
|
4997
|
+
"conflictLineValue": "_367UGW_conflictLineValue",
|
|
4998
|
+
"pathMappingList": "_367UGW_pathMappingList",
|
|
4999
|
+
"diffNoColW5": "_367UGW_diffNoColW5",
|
|
5000
|
+
"statMeta": "_367UGW_statMeta",
|
|
5001
|
+
"dialogHeader": "_367UGW_dialogHeader",
|
|
5002
|
+
"toastIn": "_367UGW_toastIn",
|
|
5003
|
+
"dialogFooter": "_367UGW_dialogFooter",
|
|
5004
|
+
"actionRow": "_367UGW_actionRow",
|
|
5005
|
+
"pushRight": "_367UGW_pushRight",
|
|
5006
|
+
"activityResultOk": "_367UGW_activityResultOk",
|
|
5007
|
+
"logScroll": "_367UGW_logScroll",
|
|
5008
|
+
"marketReviewScroll": "_367UGW_marketReviewScroll",
|
|
5009
|
+
"todoText": "_367UGW_todoText",
|
|
5010
|
+
"conflictItem": "_367UGW_conflictItem",
|
|
5034
5011
|
"conflictLineLabel": "_367UGW_conflictLineLabel",
|
|
5035
5012
|
"activityCard": "_367UGW_activityCard",
|
|
5036
|
-
"
|
|
5037
|
-
"
|
|
5038
|
-
"
|
|
5013
|
+
"logPanel": "_367UGW_logPanel",
|
|
5014
|
+
"actionRowTop": "_367UGW_actionRowTop",
|
|
5015
|
+
"sectionSubtitle": "_367UGW_sectionSubtitle",
|
|
5016
|
+
"emptyHero": "_367UGW_emptyHero",
|
|
5017
|
+
"diffStatTotal": "_367UGW_diffStatTotal",
|
|
5018
|
+
"hiddenFile": "_367UGW_hiddenFile",
|
|
5019
|
+
"logLine": "_367UGW_logLine",
|
|
5020
|
+
"progressLabel": "_367UGW_progressLabel",
|
|
5021
|
+
"reportView": "_367UGW_reportView",
|
|
5022
|
+
"severityError": "_367UGW_severityError",
|
|
5023
|
+
"pathRow": "_367UGW_pathRow",
|
|
5024
|
+
"kindTagOk": "_367UGW_kindTagOk",
|
|
5025
|
+
"diffTable": "_367UGW_diffTable",
|
|
5026
|
+
"restorePlanPath": "_367UGW_restorePlanPath",
|
|
5027
|
+
"consultDimension": "_367UGW_consultDimension",
|
|
5028
|
+
"exportGroup": "_367UGW_exportGroup",
|
|
5029
|
+
"groupList": "_367UGW_groupList",
|
|
5030
|
+
"pathOld": "_367UGW_pathOld",
|
|
5031
|
+
"errorActionLabel": "_367UGW_errorActionLabel",
|
|
5032
|
+
"diffNoColW3": "_367UGW_diffNoColW3",
|
|
5033
|
+
"diffHunkRow": "_367UGW_diffHunkRow",
|
|
5034
|
+
"diffGroupToggle": "_367UGW_diffGroupToggle",
|
|
5035
|
+
"reportFooter": "_367UGW_reportFooter",
|
|
5036
|
+
"secretFields": "_367UGW_secretFields",
|
|
5039
5037
|
"backupFileNote": "_367UGW_backupFileNote",
|
|
5040
|
-
"
|
|
5041
|
-
"categoryDesc": "_367UGW_categoryDesc",
|
|
5042
|
-
"logEmpty": "_367UGW_logEmpty",
|
|
5043
|
-
"statusMeta": "_367UGW_statusMeta",
|
|
5044
|
-
"marketFilterGrid": "_367UGW_marketFilterGrid",
|
|
5045
|
-
"logScroll": "_367UGW_logScroll",
|
|
5046
|
-
"pickerToolbar": "_367UGW_pickerToolbar",
|
|
5047
|
-
"primaryButton": "_367UGW_primaryButton",
|
|
5048
|
-
"errorLine": "_367UGW_errorLine",
|
|
5049
|
-
"diffStatDel": "_367UGW_diffStatDel",
|
|
5038
|
+
"badgeWarn": "_367UGW_badgeWarn",
|
|
5050
5039
|
"dim": "_367UGW_dim",
|
|
5051
|
-
"
|
|
5052
|
-
"
|
|
5053
|
-
"backupFileName": "_367UGW_backupFileName",
|
|
5054
|
-
"warnList": "_367UGW_warnList",
|
|
5055
|
-
"restorePlanGroupHead": "_367UGW_restorePlanGroupHead",
|
|
5056
|
-
"diffCellAdd": "_367UGW_diffCellAdd",
|
|
5057
|
-
"historyTime": "_367UGW_historyTime",
|
|
5058
|
-
"detailLines": "_367UGW_detailLines",
|
|
5059
|
-
"listHeaderRow": "_367UGW_listHeaderRow",
|
|
5060
|
-
"statusPulse": "_367UGW_statusPulse",
|
|
5061
|
-
"aboutAuthor": "_367UGW_aboutAuthor",
|
|
5062
|
-
"noticeLine": "_367UGW_noticeLine",
|
|
5063
|
-
"reportScroll": "_367UGW_reportScroll",
|
|
5064
|
-
"sectionRow": "_367UGW_sectionRow",
|
|
5065
|
-
"copyBtn": "_367UGW_copyBtn",
|
|
5066
|
-
"profileRowTitle": "_367UGW_profileRowTitle",
|
|
5067
|
-
"profileRowMeta": "_367UGW_profileRowMeta",
|
|
5068
|
-
"sectionOptionRow": "_367UGW_sectionOptionRow",
|
|
5069
|
-
"activitySummary": "_367UGW_activitySummary",
|
|
5070
|
-
"errorBanner": "_367UGW_errorBanner",
|
|
5040
|
+
"cellTitle": "_367UGW_cellTitle",
|
|
5041
|
+
"progressBarDone": "_367UGW_progressBarDone",
|
|
5071
5042
|
"diffNo": "_367UGW_diffNo",
|
|
5072
|
-
"
|
|
5073
|
-
"
|
|
5074
|
-
"
|
|
5075
|
-
"
|
|
5076
|
-
"metricValue": "_367UGW_metricValue",
|
|
5077
|
-
"pickerUnit": "_367UGW_pickerUnit",
|
|
5078
|
-
"field": "_367UGW_field",
|
|
5079
|
-
"emptyHeroBody": "_367UGW_emptyHeroBody",
|
|
5080
|
-
"cellActions": "_367UGW_cellActions",
|
|
5081
|
-
"statHealthAction": "_367UGW_statHealthAction",
|
|
5082
|
-
"ovSide": "_367UGW_ovSide",
|
|
5043
|
+
"statusBar": "_367UGW_statusBar",
|
|
5044
|
+
"metricMeta": "_367UGW_metricMeta",
|
|
5045
|
+
"factCell": "_367UGW_factCell",
|
|
5046
|
+
"statRow": "_367UGW_statRow",
|
|
5083
5047
|
"reportText": "_367UGW_reportText",
|
|
5084
|
-
"
|
|
5085
|
-
"
|
|
5086
|
-
"
|
|
5087
|
-
"
|
|
5088
|
-
"
|
|
5089
|
-
"
|
|
5090
|
-
"
|
|
5091
|
-
"
|
|
5092
|
-
"
|
|
5093
|
-
"
|
|
5094
|
-
"
|
|
5095
|
-
"
|
|
5096
|
-
"
|
|
5097
|
-
"
|
|
5098
|
-
"
|
|
5099
|
-
"
|
|
5100
|
-
"
|
|
5101
|
-
"
|
|
5102
|
-
"
|
|
5103
|
-
"
|
|
5104
|
-
"infoValue": "_367UGW_infoValue",
|
|
5105
|
-
"authorRow": "_367UGW_authorRow",
|
|
5106
|
-
"marketFilterMeta": "_367UGW_marketFilterMeta",
|
|
5107
|
-
"reportList": "_367UGW_reportList",
|
|
5048
|
+
"ovMain": "_367UGW_ovMain",
|
|
5049
|
+
"marketFilterGrid": "_367UGW_marketFilterGrid",
|
|
5050
|
+
"quickActionTitle": "_367UGW_quickActionTitle",
|
|
5051
|
+
"warnList": "_367UGW_warnList",
|
|
5052
|
+
"diffScroll": "_367UGW_diffScroll",
|
|
5053
|
+
"exportGrid": "_367UGW_exportGrid",
|
|
5054
|
+
"errorBanner": "_367UGW_errorBanner",
|
|
5055
|
+
"confirmScroll": "_367UGW_confirmScroll",
|
|
5056
|
+
"fillCard": "_367UGW_fillCard",
|
|
5057
|
+
"shellNav": "_367UGW_shellNav",
|
|
5058
|
+
"tableWrap": "_367UGW_tableWrap",
|
|
5059
|
+
"pickerChevronSpacer": "_367UGW_pickerChevronSpacer",
|
|
5060
|
+
"pickerUnitNested": "_367UGW_pickerUnitNested",
|
|
5061
|
+
"pathValue": "_367UGW_pathValue",
|
|
5062
|
+
"navActions": "_367UGW_navActions",
|
|
5063
|
+
"errorItem": "_367UGW_errorItem",
|
|
5064
|
+
"profileRowMeta": "_367UGW_profileRowMeta",
|
|
5065
|
+
"detailLines": "_367UGW_detailLines",
|
|
5066
|
+
"dangerButton": "_367UGW_dangerButton",
|
|
5067
|
+
"choiceTitle": "_367UGW_choiceTitle",
|
|
5108
5068
|
"iconBtn": "_367UGW_iconBtn",
|
|
5109
|
-
"
|
|
5110
|
-
"
|
|
5069
|
+
"tableCompact": "_367UGW_tableCompact",
|
|
5070
|
+
"drawerMask": "_367UGW_drawerMask",
|
|
5071
|
+
"reasonLine": "_367UGW_reasonLine",
|
|
5072
|
+
"restorePlanList": "_367UGW_restorePlanList",
|
|
5073
|
+
"restorePlan": "_367UGW_restorePlan",
|
|
5074
|
+
"conflictDetail": "_367UGW_conflictDetail",
|
|
5075
|
+
"ovGrid": "_367UGW_ovGrid",
|
|
5076
|
+
"pullScroll": "_367UGW_pullScroll",
|
|
5077
|
+
"ovActivity": "_367UGW_ovActivity",
|
|
5078
|
+
"groupHintRow": "_367UGW_groupHintRow",
|
|
5079
|
+
"infoKey": "_367UGW_infoKey",
|
|
5080
|
+
"snapshotPickerHint": "_367UGW_snapshotPickerHint",
|
|
5081
|
+
"reportScroll": "_367UGW_reportScroll",
|
|
5082
|
+
"restorePlanRowStatic": "_367UGW_restorePlanRowStatic",
|
|
5083
|
+
"backupFileRow": "_367UGW_backupFileRow",
|
|
5084
|
+
"select": "_367UGW_select",
|
|
5085
|
+
"diffNoColW4": "_367UGW_diffNoColW4",
|
|
5086
|
+
"progressPercent": "_367UGW_progressPercent",
|
|
5087
|
+
"optionsCard": "_367UGW_optionsCard",
|
|
5111
5088
|
"stepperLabel": "_367UGW_stepperLabel",
|
|
5112
|
-
"
|
|
5089
|
+
"kvValue": "_367UGW_kvValue",
|
|
5090
|
+
"statValue": "_367UGW_statValue",
|
|
5091
|
+
"badge": "_367UGW_badge",
|
|
5092
|
+
"statValueSmall": "_367UGW_statValueSmall",
|
|
5093
|
+
"drawerHeader": "_367UGW_drawerHeader",
|
|
5094
|
+
"restorePlanStat": "_367UGW_restorePlanStat",
|
|
5095
|
+
"quickGrid": "_367UGW_quickGrid",
|
|
5096
|
+
"sectionTitle": "_367UGW_sectionTitle",
|
|
5097
|
+
"drawerPanel": "_367UGW_drawerPanel",
|
|
5098
|
+
"progressBar": "_367UGW_progressBar",
|
|
5099
|
+
"stepperConnector": "_367UGW_stepperConnector",
|
|
5100
|
+
"spinnerLabel": "_367UGW_spinnerLabel",
|
|
5101
|
+
"sectionOptionRow": "_367UGW_sectionOptionRow",
|
|
5102
|
+
"dataTable": "_367UGW_dataTable",
|
|
5103
|
+
"drawerTitle": "_367UGW_drawerTitle",
|
|
5104
|
+
"sectionRow": "_367UGW_sectionRow",
|
|
5105
|
+
"exportItems": "_367UGW_exportItems",
|
|
5106
|
+
"activityTitle": "_367UGW_activityTitle",
|
|
5107
|
+
"wizardStepperRow": "_367UGW_wizardStepperRow",
|
|
5108
|
+
"historyRowMain": "_367UGW_historyRowMain",
|
|
5113
5109
|
"statSegDim": "_367UGW_statSegDim",
|
|
5110
|
+
"statHealth": "_367UGW_statHealth",
|
|
5111
|
+
"empty": "_367UGW_empty",
|
|
5112
|
+
"kindTag": "_367UGW_kindTag",
|
|
5114
5113
|
"statStrip": "_367UGW_statStrip",
|
|
5115
|
-
"
|
|
5116
|
-
"
|
|
5117
|
-
"
|
|
5118
|
-
"
|
|
5114
|
+
"rowActions": "_367UGW_rowActions",
|
|
5115
|
+
"section": "_367UGW_section",
|
|
5116
|
+
"tabRow": "_367UGW_tabRow",
|
|
5117
|
+
"choiceCard": "_367UGW_choiceCard",
|
|
5118
|
+
"cellMain": "_367UGW_cellMain",
|
|
5119
|
+
"badgeInfo": "_367UGW_badgeInfo",
|
|
5120
|
+
"sectionTitleBlock": "_367UGW_sectionTitleBlock",
|
|
5119
5121
|
"inspectGroup": "_367UGW_inspectGroup",
|
|
5120
|
-
"
|
|
5121
|
-
"
|
|
5122
|
-
"
|
|
5123
|
-
"
|
|
5124
|
-
"
|
|
5125
|
-
"progressPercent": "_367UGW_progressPercent",
|
|
5126
|
-
"metricMeta": "_367UGW_metricMeta",
|
|
5127
|
-
"toastIn": "_367UGW_toastIn",
|
|
5122
|
+
"pickerList": "_367UGW_pickerList",
|
|
5123
|
+
"conflictOptions": "_367UGW_conflictOptions",
|
|
5124
|
+
"restorePlanNote": "_367UGW_restorePlanNote",
|
|
5125
|
+
"badgeOk": "_367UGW_badgeOk",
|
|
5126
|
+
"categoryDesc": "_367UGW_categoryDesc",
|
|
5128
5127
|
"drawerIn": "_367UGW_drawerIn",
|
|
5129
|
-
"
|
|
5130
|
-
"
|
|
5131
|
-
"
|
|
5132
|
-
"pickerSubgroupName": "_367UGW_pickerSubgroupName",
|
|
5128
|
+
"stepperDot": "_367UGW_stepperDot",
|
|
5129
|
+
"snapshotRowHeader": "_367UGW_snapshotRowHeader",
|
|
5130
|
+
"backupFileName": "_367UGW_backupFileName",
|
|
5133
5131
|
"diffNoColW6": "_367UGW_diffNoColW6",
|
|
5132
|
+
"emptyHeroTitle": "_367UGW_emptyHeroTitle",
|
|
5133
|
+
"badgeError": "_367UGW_badgeError",
|
|
5134
5134
|
"statLabel": "_367UGW_statLabel",
|
|
5135
|
-
"pushRight": "_367UGW_pushRight",
|
|
5136
5135
|
"activityFit": "_367UGW_activityFit",
|
|
5137
|
-
"
|
|
5138
|
-
"
|
|
5139
|
-
"
|
|
5140
|
-
"
|
|
5141
|
-
"
|
|
5142
|
-
"
|
|
5143
|
-
"kindTag": "_367UGW_kindTag",
|
|
5144
|
-
"cliCommand": "_367UGW_cliCommand",
|
|
5145
|
-
"statGrid": "_367UGW_statGrid",
|
|
5146
|
-
"groupItems": "_367UGW_groupItems",
|
|
5147
|
-
"progressBar": "_367UGW_progressBar",
|
|
5148
|
-
"dialogHeaderRow": "_367UGW_dialogHeaderRow",
|
|
5149
|
-
"conflictPrefix": "_367UGW_conflictPrefix",
|
|
5150
|
-
"badge": "_367UGW_badge",
|
|
5151
|
-
"progressIndeterminate": "_367UGW_progressIndeterminate",
|
|
5152
|
-
"checkboxRow": "_367UGW_checkboxRow",
|
|
5136
|
+
"sectionGrid": "_367UGW_sectionGrid",
|
|
5137
|
+
"pickerRow": "_367UGW_pickerRow",
|
|
5138
|
+
"logJumpButton": "_367UGW_logJumpButton",
|
|
5139
|
+
"profileRowMain": "_367UGW_profileRowMain",
|
|
5140
|
+
"exportItem": "_367UGW_exportItem",
|
|
5141
|
+
"pagePad": "_367UGW_pagePad",
|
|
5153
5142
|
"scheduleNote": "_367UGW_scheduleNote",
|
|
5154
|
-
"
|
|
5155
|
-
"
|
|
5156
|
-
"
|
|
5157
|
-
"
|
|
5158
|
-
"
|
|
5159
|
-
"
|
|
5160
|
-
"
|
|
5161
|
-
"
|
|
5162
|
-
"
|
|
5163
|
-
"
|
|
5143
|
+
"rollbackBox": "_367UGW_rollbackBox",
|
|
5144
|
+
"snapshotRowMain": "_367UGW_snapshotRowMain",
|
|
5145
|
+
"categoryItem": "_367UGW_categoryItem",
|
|
5146
|
+
"restorePlanRow": "_367UGW_restorePlanRow",
|
|
5147
|
+
"fillViewport": "_367UGW_fillViewport",
|
|
5148
|
+
"badgeRow": "_367UGW_badgeRow",
|
|
5149
|
+
"dialogContentCenter": "_367UGW_dialogContentCenter",
|
|
5150
|
+
"drawerBody": "_367UGW_drawerBody",
|
|
5151
|
+
"primaryButton": "_367UGW_primaryButton",
|
|
5152
|
+
"emptyHeroSymbol": "_367UGW_emptyHeroSymbol",
|
|
5153
|
+
"progressIndeterminate": "_367UGW_progressIndeterminate",
|
|
5154
|
+
"snapshotRow": "_367UGW_snapshotRow",
|
|
5155
|
+
"emptyHeroBody": "_367UGW_emptyHeroBody",
|
|
5156
|
+
"dialogHeaderRow": "_367UGW_dialogHeaderRow",
|
|
5157
|
+
"ovSide": "_367UGW_ovSide",
|
|
5158
|
+
"field": "_367UGW_field",
|
|
5159
|
+
"infoRow": "_367UGW_infoRow",
|
|
5160
|
+
"indet": "_367UGW_indet",
|
|
5161
|
+
"cellMetaNoteText": "_367UGW_cellMetaNoteText",
|
|
5162
|
+
"headRow": "_367UGW_headRow"
|
|
5164
5163
|
};
|
|
5165
5164
|
//#endregion
|
|
5166
5165
|
//#region src/client/common/ui.tsx
|
|
@@ -6306,7 +6305,7 @@ function OverviewPanel({ api, syncApi, historyApi, t, openActivity }) {
|
|
|
6306
6305
|
const { run } = await api.runBackupNow();
|
|
6307
6306
|
const outcome = backupRunOutcome(run);
|
|
6308
6307
|
if (outcome.kind === "ok") toast.ok(t("overview.quick.backupDone"));
|
|
6309
|
-
else if (outcome.kind === "skipped") toast.warn(t(BACKUP_SKIP_KEY[outcome.reason]
|
|
6308
|
+
else if (outcome.kind === "skipped") toast.warn(t(BACKUP_SKIP_KEY[outcome.reason]));
|
|
6310
6309
|
else toast.error(t("overview.quick.backupFailed", { message: redact(outcome.message ?? t("common.unknownError")) }));
|
|
6311
6310
|
if (aliveRef.current) load();
|
|
6312
6311
|
} catch (err) {
|
|
@@ -25956,7 +25955,7 @@ const zh$4 = {
|
|
|
25956
25955
|
"overview.quick.backupSkippedRunning": "已跳过:上一次备份仍在进行中",
|
|
25957
25956
|
"overview.quick.backupSkippedConflict": "已跳过:另一项任务正在执行(防重)",
|
|
25958
25957
|
"overview.quick.backupSkippedLocked": "已跳过:环境锁被占用(另一项任务进行中,或存在需回收的残留锁)",
|
|
25959
|
-
"overview.quick.backupSkippedOther": "
|
|
25958
|
+
"overview.quick.backupSkippedOther": "已跳过:备份服务当前无法执行(详情见宿主日志)",
|
|
25960
25959
|
"overview.quick.backupFailed": "备份失败:{message}",
|
|
25961
25960
|
"overview.quick.sync": "远程同步",
|
|
25962
25961
|
"overview.activity.title": "最近活动",
|
|
@@ -26539,7 +26538,7 @@ const en$4 = {
|
|
|
26539
26538
|
"overview.quick.backupSkippedRunning": "Skipped: a previous backup is still running",
|
|
26540
26539
|
"overview.quick.backupSkippedConflict": "Skipped: another task is running (duplicate guard)",
|
|
26541
26540
|
"overview.quick.backupSkippedLocked": "Skipped: the environment lock is held (another task is running, or a stale lock needs recovery)",
|
|
26542
|
-
"overview.quick.backupSkippedOther": "Skipped:
|
|
26541
|
+
"overview.quick.backupSkippedOther": "Skipped: the backup service cannot run right now (see host logs for details)",
|
|
26543
26542
|
"overview.quick.backupFailed": "Backup failed: {message}",
|
|
26544
26543
|
"overview.quick.sync": "Remote sync",
|
|
26545
26544
|
"overview.activity.title": "Recent activity",
|
package/lib/index.js
CHANGED
|
@@ -127,7 +127,7 @@ export const name = 'config-manager';
|
|
|
127
127
|
/** Services required before the engine can mount (present in every profile). */
|
|
128
128
|
export const inject = ['settings', 'credentials'];
|
|
129
129
|
/** Plugin version, kept in sync with package.json ("version"). */
|
|
130
|
-
const PLUGIN_VERSION = '0.1.
|
|
130
|
+
const PLUGIN_VERSION = '0.1.63';
|
|
131
131
|
/** Plugin own package name — excluded from its own exported plugins list. */
|
|
132
132
|
const PLUGIN_NAME = 'dsh-config-manager';
|
|
133
133
|
/**
|
|
@@ -94,7 +94,6 @@ export type BackupRunOutcome = {
|
|
|
94
94
|
} | {
|
|
95
95
|
kind: 'skipped';
|
|
96
96
|
reason: BackupSkipReason;
|
|
97
|
-
raw?: string;
|
|
98
97
|
} | {
|
|
99
98
|
kind: 'error';
|
|
100
99
|
message: string | null;
|
|
@@ -104,7 +103,10 @@ export type BackupRunOutcome = {
|
|
|
104
103
|
* (见 src/index.ts 的 backup-schedule/run 路由),所以**不能**用「有没有抛异常」判成败 ——
|
|
105
104
|
* 那会把「定时备份未启用 → 一个备份文件都没产出」读成「备份完成」。
|
|
106
105
|
*
|
|
107
|
-
* 本函数只做语义投影(零文案):success → ok;skipped → 结构化 reason
|
|
106
|
+
* 本函数只做语义投影(零文案):success → ok;skipped → 结构化 reason(**未知 token 归一为 other**,
|
|
107
|
+
* 绝不把机器 token 原样摆到用户面前——仓库既有纪律:用户可见文本里不留裸 token);
|
|
108
108
|
* 其余(含 failed 与未来新增 status)→ error,fail-safe 地绝不宣称成功。
|
|
109
|
+
* `failed` 但宿主没给出可用错误文本(undefined / 空串 / 全空白)→ message 为 null,由壳层回退通用文案
|
|
110
|
+
* (否则会渲染出「备份失败:」这种半截提示)。
|
|
109
111
|
*/
|
|
110
112
|
export declare function backupRunOutcome(run: BackupRunResult): BackupRunOutcome;
|
|
@@ -112,8 +112,11 @@ export function backupRunSummary(run) {
|
|
|
112
112
|
* (见 src/index.ts 的 backup-schedule/run 路由),所以**不能**用「有没有抛异常」判成败 ——
|
|
113
113
|
* 那会把「定时备份未启用 → 一个备份文件都没产出」读成「备份完成」。
|
|
114
114
|
*
|
|
115
|
-
* 本函数只做语义投影(零文案):success → ok;skipped → 结构化 reason
|
|
115
|
+
* 本函数只做语义投影(零文案):success → ok;skipped → 结构化 reason(**未知 token 归一为 other**,
|
|
116
|
+
* 绝不把机器 token 原样摆到用户面前——仓库既有纪律:用户可见文本里不留裸 token);
|
|
116
117
|
* 其余(含 failed 与未来新增 status)→ error,fail-safe 地绝不宣称成功。
|
|
118
|
+
* `failed` 但宿主没给出可用错误文本(undefined / 空串 / 全空白)→ message 为 null,由壳层回退通用文案
|
|
119
|
+
* (否则会渲染出「备份失败:」这种半截提示)。
|
|
117
120
|
*/
|
|
118
121
|
export function backupRunOutcome(run) {
|
|
119
122
|
switch (run.status) {
|
|
@@ -125,14 +128,14 @@ export function backupRunOutcome(run) {
|
|
|
125
128
|
case 'running': return { kind: 'skipped', reason: 'running' };
|
|
126
129
|
case 'conflict': return { kind: 'skipped', reason: 'conflict' };
|
|
127
130
|
case 'mutation-locked': return { kind: 'skipped', reason: 'locked' };
|
|
128
|
-
default:
|
|
129
|
-
return run.skipReason === undefined || run.skipReason === ''
|
|
130
|
-
? { kind: 'skipped', reason: 'other' }
|
|
131
|
-
: { kind: 'skipped', reason: 'other', raw: run.skipReason };
|
|
131
|
+
default: return { kind: 'skipped', reason: 'other' };
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
default:
|
|
135
|
-
return {
|
|
135
|
+
return {
|
|
136
|
+
kind: 'error',
|
|
137
|
+
message: run.error !== undefined && run.error.trim() !== '' ? run.error : null,
|
|
138
|
+
};
|
|
136
139
|
}
|
|
137
140
|
}
|
|
138
141
|
//# sourceMappingURL=backup-schedule.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-config-manager",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.63",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Backup, restore, export, import, migrate and sync your DeepSeek Harness (DSH) configuration: settings, plugins, MCP servers, skills, agent presets and workspaces. One-click migration to another machine. DSH 配置一键备份、恢复、导出、导入、迁移与同步插件。",
|
|
6
6
|
"keywords": [
|
package/src/client/locales.ts
CHANGED
|
@@ -70,7 +70,7 @@ export const zh = {
|
|
|
70
70
|
'overview.quick.backupSkippedRunning': '已跳过:上一次备份仍在进行中',
|
|
71
71
|
'overview.quick.backupSkippedConflict': '已跳过:另一项任务正在执行(防重)',
|
|
72
72
|
'overview.quick.backupSkippedLocked': '已跳过:环境锁被占用(另一项任务进行中,或存在需回收的残留锁)',
|
|
73
|
-
'overview.quick.backupSkippedOther': '
|
|
73
|
+
'overview.quick.backupSkippedOther': '已跳过:备份服务当前无法执行(详情见宿主日志)',
|
|
74
74
|
'overview.quick.backupFailed': '备份失败:{message}',
|
|
75
75
|
'overview.quick.sync': '远程同步',
|
|
76
76
|
'overview.activity.title': '最近活动',
|
|
@@ -676,7 +676,7 @@ export const en: Record<keyof typeof zh, string> = {
|
|
|
676
676
|
'overview.quick.backupSkippedRunning': 'Skipped: a previous backup is still running',
|
|
677
677
|
'overview.quick.backupSkippedConflict': 'Skipped: another task is running (duplicate guard)',
|
|
678
678
|
'overview.quick.backupSkippedLocked': 'Skipped: the environment lock is held (another task is running, or a stale lock needs recovery)',
|
|
679
|
-
'overview.quick.backupSkippedOther': 'Skipped:
|
|
679
|
+
'overview.quick.backupSkippedOther': 'Skipped: the backup service cannot run right now (see host logs for details)',
|
|
680
680
|
'overview.quick.backupFailed': 'Backup failed: {message}',
|
|
681
681
|
'overview.quick.sync': 'Remote sync',
|
|
682
682
|
'overview.activity.title': 'Recent activity',
|
|
@@ -235,7 +235,7 @@ export function OverviewPanel({ api, syncApi, historyApi, t, openActivity }: Ove
|
|
|
235
235
|
if (outcome.kind === 'ok') {
|
|
236
236
|
toast.ok(t('overview.quick.backupDone'))
|
|
237
237
|
} else if (outcome.kind === 'skipped') {
|
|
238
|
-
toast.warn(t(BACKUP_SKIP_KEY[outcome.reason]
|
|
238
|
+
toast.warn(t(BACKUP_SKIP_KEY[outcome.reason]))
|
|
239
239
|
} else {
|
|
240
240
|
toast.error(t('overview.quick.backupFailed', { message: redact(outcome.message ?? t('common.unknownError')) }))
|
|
241
241
|
}
|
package/src/index.ts
CHANGED
|
@@ -185,7 +185,7 @@ export const name = 'config-manager'
|
|
|
185
185
|
export const inject = ['settings', 'credentials']
|
|
186
186
|
|
|
187
187
|
/** Plugin version, kept in sync with package.json ("version"). */
|
|
188
|
-
const PLUGIN_VERSION = '0.1.
|
|
188
|
+
const PLUGIN_VERSION = '0.1.63'
|
|
189
189
|
|
|
190
190
|
/** Plugin own package name — excluded from its own exported plugins list. */
|
|
191
191
|
const PLUGIN_NAME = 'dsh-config-manager'
|
|
@@ -211,10 +211,11 @@ test('issue #43:已知 skipReason token 各自映射(running / conflict / lo
|
|
|
211
211
|
}
|
|
212
212
|
})
|
|
213
213
|
|
|
214
|
-
test('issue #43:未知 skipReason
|
|
214
|
+
test('issue #43:未知 skipReason 归一为 other(不把机器 token 摆给用户,也不当作成功)', () => {
|
|
215
|
+
// PR #44(外部贡献者)意见:未知原因应给本地化的通用说明,而不是原样回传裸 token
|
|
215
216
|
assert.deepEqual(
|
|
216
217
|
backupRunOutcome({ status: 'skipped', skipReason: 'weird-future-token', consecutiveFailures: 0 }),
|
|
217
|
-
{ kind: 'skipped', reason: 'other'
|
|
218
|
+
{ kind: 'skipped', reason: 'other' },
|
|
218
219
|
)
|
|
219
220
|
assert.deepEqual(
|
|
220
221
|
backupRunOutcome({ status: 'skipped', consecutiveFailures: 0 }),
|
|
@@ -231,6 +232,15 @@ test('issue #43:failed → error 通道(带宿主错误文本;缺失则 nu
|
|
|
231
232
|
backupRunOutcome({ status: 'failed', consecutiveFailures: 3 }),
|
|
232
233
|
{ kind: 'error', message: null },
|
|
233
234
|
)
|
|
235
|
+
// 空串 / 全空白同样回退(PR #44 意见:否则壳层会渲染出「备份失败:」这种半截提示)
|
|
236
|
+
assert.deepEqual(
|
|
237
|
+
backupRunOutcome({ status: 'failed', error: '', consecutiveFailures: 3 }),
|
|
238
|
+
{ kind: 'error', message: null },
|
|
239
|
+
)
|
|
240
|
+
assert.deepEqual(
|
|
241
|
+
backupRunOutcome({ status: 'failed', error: ' ', consecutiveFailures: 3 }),
|
|
242
|
+
{ kind: 'error', message: null },
|
|
243
|
+
)
|
|
234
244
|
})
|
|
235
245
|
|
|
236
246
|
test('issue #43:未知 status 落 error(fail-safe:绝不宣称成功)', () => {
|
|
@@ -173,7 +173,7 @@ export type BackupSkipReason = 'disabled' | 'running' | 'conflict' | 'locked' |
|
|
|
173
173
|
/** 立即备份结果 → 客户端提示通道(壳据 kind 选 toast,据 reason 选文案键)。 */
|
|
174
174
|
export type BackupRunOutcome =
|
|
175
175
|
| { kind: 'ok' }
|
|
176
|
-
| { kind: 'skipped'; reason: BackupSkipReason
|
|
176
|
+
| { kind: 'skipped'; reason: BackupSkipReason }
|
|
177
177
|
| { kind: 'error'; message: string | null }
|
|
178
178
|
|
|
179
179
|
/**
|
|
@@ -181,8 +181,11 @@ export type BackupRunOutcome =
|
|
|
181
181
|
* (见 src/index.ts 的 backup-schedule/run 路由),所以**不能**用「有没有抛异常」判成败 ——
|
|
182
182
|
* 那会把「定时备份未启用 → 一个备份文件都没产出」读成「备份完成」。
|
|
183
183
|
*
|
|
184
|
-
* 本函数只做语义投影(零文案):success → ok;skipped → 结构化 reason
|
|
184
|
+
* 本函数只做语义投影(零文案):success → ok;skipped → 结构化 reason(**未知 token 归一为 other**,
|
|
185
|
+
* 绝不把机器 token 原样摆到用户面前——仓库既有纪律:用户可见文本里不留裸 token);
|
|
185
186
|
* 其余(含 failed 与未来新增 status)→ error,fail-safe 地绝不宣称成功。
|
|
187
|
+
* `failed` 但宿主没给出可用错误文本(undefined / 空串 / 全空白)→ message 为 null,由壳层回退通用文案
|
|
188
|
+
* (否则会渲染出「备份失败:」这种半截提示)。
|
|
186
189
|
*/
|
|
187
190
|
export function backupRunOutcome(run: BackupRunResult): BackupRunOutcome {
|
|
188
191
|
switch (run.status) {
|
|
@@ -194,13 +197,13 @@ export function backupRunOutcome(run: BackupRunResult): BackupRunOutcome {
|
|
|
194
197
|
case 'running': return { kind: 'skipped', reason: 'running' }
|
|
195
198
|
case 'conflict': return { kind: 'skipped', reason: 'conflict' }
|
|
196
199
|
case 'mutation-locked': return { kind: 'skipped', reason: 'locked' }
|
|
197
|
-
default:
|
|
198
|
-
return run.skipReason === undefined || run.skipReason === ''
|
|
199
|
-
? { kind: 'skipped', reason: 'other' }
|
|
200
|
-
: { kind: 'skipped', reason: 'other', raw: run.skipReason }
|
|
200
|
+
default: return { kind: 'skipped', reason: 'other' }
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
default:
|
|
204
|
-
return {
|
|
204
|
+
return {
|
|
205
|
+
kind: 'error',
|
|
206
|
+
message: run.error !== undefined && run.error.trim() !== '' ? run.error : null,
|
|
207
|
+
}
|
|
205
208
|
}
|
|
206
209
|
}
|
|
@@ -333,6 +333,28 @@ async function readOwnershipByMgr(mgr: EnvironmentLockManager): Promise<LockOwne
|
|
|
333
333
|
catch { return null; }
|
|
334
334
|
}
|
|
335
335
|
|
|
336
|
+
/**
|
|
337
|
+
* 有界等待 heartbeat sidecar 的 seq 超过 `fromSeq`,返回最新记录(超时则返回当前值)。
|
|
338
|
+
*
|
|
339
|
+
* 为什么不能固定 sleep 猜定时器:`§11.1-c6` 原先「sleep 70ms ×3,再断言 seq 递增」,
|
|
340
|
+
* 而 heartbeat 定时器在 CI 负载下可能整段采样窗口都没触发 —— 实测失败 `heartbeat seq 应递增: 2,2,2`
|
|
341
|
+
* (同一 commit 重跑即过)。产品侧 seq 用 `++this.heartbeatSeq`,单进程内严格单调,
|
|
342
|
+
* 问题只在测试用墙钟猜「定时器何时跑」,故改为等待**观测到的**推进。
|
|
343
|
+
*/
|
|
344
|
+
async function waitHeartbeatSeqAbove(
|
|
345
|
+
hbPath: string,
|
|
346
|
+
fromSeq: number,
|
|
347
|
+
timeoutMs = 5000,
|
|
348
|
+
): Promise<{ seq: number; heartbeatAt: number }> {
|
|
349
|
+
const deadline = Date.now() + timeoutMs
|
|
350
|
+
let rec = JSON.parse(await readText(hbPath)) as { seq: number; heartbeatAt: number }
|
|
351
|
+
while (rec.seq <= fromSeq && Date.now() < deadline) {
|
|
352
|
+
await sleepReal(20)
|
|
353
|
+
rec = JSON.parse(await readText(hbPath)) as { seq: number; heartbeatAt: number }
|
|
354
|
+
}
|
|
355
|
+
return rec
|
|
356
|
+
}
|
|
357
|
+
|
|
336
358
|
test('§11.1-c6 heartbeat sidecar 更新不替换 environment.lock(inode/内容不变)', async (t) => {
|
|
337
359
|
const locksDir = tmp(t);
|
|
338
360
|
const ctl = makeIo();
|
|
@@ -352,10 +374,12 @@ test('§11.1-c6 heartbeat sidecar 更新不替换 environment.lock(inode/内
|
|
|
352
374
|
const beforeText = await readText(path.join(locksDir, OWNERSHIP_FILE));
|
|
353
375
|
// 等若干心跳周期(≥3 tick),期间只更新 sidecar
|
|
354
376
|
const hbPath = path.join(locksDir, heartbeatFile(id));
|
|
355
|
-
const seqProbe: number[] = [];
|
|
356
|
-
for (let
|
|
357
|
-
|
|
358
|
-
|
|
377
|
+
const seqProbe: number[] = [JSON.parse(await readText(hbPath)).seq as number];
|
|
378
|
+
for (let want = 1; want <= 3; want++) {
|
|
379
|
+
const prev = seqProbe[seqProbe.length - 1]!;
|
|
380
|
+
const next = await waitHeartbeatSeqAbove(hbPath, prev);
|
|
381
|
+
if (next.seq <= prev) break; // 有界等待超时:如实停止采样,由下面的断言报错(不假装更新过)
|
|
382
|
+
seqProbe.push(next.seq);
|
|
359
383
|
}
|
|
360
384
|
// ownership 内容绝对不变(无 rename/replace —— 若有 atomicWriteFile 替换 ownership 则内容会变/文件被换)
|
|
361
385
|
const afterText = await readText(path.join(locksDir, OWNERSHIP_FILE));
|
|
@@ -366,7 +390,14 @@ test('§11.1-c6 heartbeat sidecar 更新不替换 environment.lock(inode/内
|
|
|
366
390
|
const ino2 = (await fs.stat(path.join(locksDir, OWNERSHIP_FILE))).ino;
|
|
367
391
|
assert.equal(ino1, ino2, 'ownership inode 必须稳定');
|
|
368
392
|
}
|
|
393
|
+
assert.ok(
|
|
394
|
+
seqProbe.length >= 2,
|
|
395
|
+
`heartbeat sidecar 应在有界等待内至少推进一次(观测采样 ${seqProbe.length} 次: ${seqProbe.join(',')})`,
|
|
396
|
+
);
|
|
369
397
|
assert.ok(seqProbe[seqProbe.length - 1]! > seqProbe[0]!, `heartbeat seq 应递增: ${seqProbe.join(',')}`);
|
|
398
|
+
for (let i = 1; i < seqProbe.length; i++) {
|
|
399
|
+
assert.ok(seqProbe[i]! > seqProbe[i - 1]!, `heartbeat seq 必须严格单调: ${seqProbe.join(',')}`);
|
|
400
|
+
}
|
|
370
401
|
// heartbeat sidecar 内容绑定 ownerInstanceId
|
|
371
402
|
const hb = JSON.parse(await readText(hbPath)) as { ownerInstanceId: string };
|
|
372
403
|
assert.equal(hb.ownerInstanceId, id);
|
|
@@ -430,8 +461,8 @@ test('§11.1-c9 heartbeat 续期(注入时钟)+ 持续写 sidecar', async (t
|
|
|
430
461
|
assert.equal(first.heartbeatAt, clk.clock(), '首写 heartbeatAt 使用注入时钟');
|
|
431
462
|
// 推进时钟 + 等待若干 tick → heartbeatAt 跟随推进后的时钟(续期)
|
|
432
463
|
clk.advance(5000);
|
|
433
|
-
|
|
434
|
-
const last =
|
|
464
|
+
// 有界等待下一次**实际** heartbeat 写(同样不固定 sleep 猜定时器;§11.1-c6 的同类加固)
|
|
465
|
+
const last = await waitHeartbeatSeqAbove(hbPath, first.seq, 5000);
|
|
435
466
|
assert.ok(last.seq > first.seq, '续期后 seq 递增');
|
|
436
467
|
assert.ok(last.heartbeatAt >= clk.clock() - 60, '续期 heartbeatAt 反映推进后的时钟');
|
|
437
468
|
await mgr.release(res.token!);
|