@dsh-workbench/shared 1.1.14-beta.2 → 1.1.14

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.
Files changed (140) hide show
  1. package/README.md +1 -1
  2. package/dist/api/dsh.d.ts +12 -0
  3. package/dist/components/SelectFieldWheel.d.ts +9 -0
  4. package/dist/components/SelectFieldWheel.js +35 -0
  5. package/dist/contract/unit-declaration.js +15 -1
  6. package/dist/contract/unit.d.ts +3 -0
  7. package/dist/host/__scratch-guard.d.ts +1 -0
  8. package/dist/host/__scratch-guard.js +1 -0
  9. package/dist/host/adapter-set.js +0 -1
  10. package/dist/host/changelog.js +2 -1
  11. package/dist/host/channel-plugin.d.ts +15 -0
  12. package/dist/host/channel-plugin.js +42 -0
  13. package/dist/host/command-name.d.ts +1 -0
  14. package/dist/host/command-name.js +14 -0
  15. package/dist/host/config-sync.d.ts +1 -9
  16. package/dist/host/config-sync.js +3 -78
  17. package/dist/host/env-policy.d.ts +75 -0
  18. package/dist/host/env-policy.js +161 -0
  19. package/dist/host/extension.js +2 -1
  20. package/dist/host/flow/run.js +2 -1
  21. package/dist/host/fs-write.d.ts +62 -0
  22. package/dist/host/fs-write.js +112 -0
  23. package/dist/host/host-kit.d.ts +6 -2
  24. package/dist/host/host-kit.js +3 -1
  25. package/dist/host/http.js +11 -5
  26. package/dist/host/installed-sources.js +4 -5
  27. package/dist/host/long-task.js +3 -3
  28. package/dist/host/opencli-runner.d.ts +26 -0
  29. package/dist/host/opencli-runner.js +50 -0
  30. package/dist/host/package-content.d.ts +2 -2
  31. package/dist/host/package-content.js +20 -6
  32. package/dist/host/package-route.d.ts +3 -3
  33. package/dist/host/package-route.js +7 -6
  34. package/dist/host/panel-state.js +2 -1
  35. package/dist/host/patch-blocks.d.ts +13 -0
  36. package/dist/host/patch-blocks.js +52 -0
  37. package/dist/host/patch.d.ts +3 -8
  38. package/dist/host/patch.js +5 -76
  39. package/dist/host/plugin-source.d.ts +33 -0
  40. package/dist/host/plugin-source.js +91 -0
  41. package/dist/host/port-types.d.ts +9 -9
  42. package/dist/host/profile-registries.js +2 -3
  43. package/dist/host/registry-declaration.d.ts +2 -2
  44. package/dist/host/registry-declaration.js +14 -5
  45. package/dist/host/release-probe.d.ts +4 -4
  46. package/dist/host/release-probe.js +39 -14
  47. package/dist/host/runner.d.ts +26 -0
  48. package/dist/host/runner.js +50 -0
  49. package/dist/host/runtime-links.d.ts +7 -0
  50. package/dist/host/runtime-links.js +25 -0
  51. package/dist/host/seam/denial.d.ts +4 -0
  52. package/dist/host/seam/denial.js +24 -0
  53. package/dist/host/seam/env.d.ts +15 -0
  54. package/dist/host/seam/env.js +17 -0
  55. package/dist/host/seam/exec.d.ts +84 -0
  56. package/dist/host/seam/exec.js +1 -0
  57. package/dist/host/seam/host-env.d.ts +2 -0
  58. package/dist/host/seam/host-env.js +18 -0
  59. package/dist/host/seam/intent.d.ts +66 -0
  60. package/dist/host/seam/intent.js +24 -0
  61. package/dist/host/seam/policy.d.ts +10 -0
  62. package/dist/host/seam/policy.js +85 -0
  63. package/dist/host/seam/process.d.ts +2 -0
  64. package/dist/host/seam/process.js +80 -0
  65. package/dist/host/seam/run.d.ts +44 -0
  66. package/dist/host/seam/run.js +421 -0
  67. package/dist/host/seam/service.d.ts +4 -0
  68. package/dist/host/seam/service.js +4 -0
  69. package/dist/host/seam/unit-seam.d.ts +14 -0
  70. package/dist/host/seam/unit-seam.js +43 -0
  71. package/dist/host/shell.d.ts +12 -0
  72. package/dist/host/shell.js +3 -1
  73. package/dist/host/time.d.ts +10 -0
  74. package/dist/host/time.js +14 -0
  75. package/dist/host/value-handoff.js +3 -2
  76. package/dist/host/workspace-store.js +2 -8
  77. package/dist/host.d.ts +11 -0
  78. package/dist/host.js +11 -0
  79. package/dist/i18n/en.js +3 -3
  80. package/dist/i18n/index.d.ts +4 -4
  81. package/dist/i18n/zh.d.ts +3 -3
  82. package/dist/i18n/zh.js +3 -3
  83. package/dist/lib/version.d.ts +4 -0
  84. package/dist/lib/version.js +21 -0
  85. package/dist/testing/fake-adapter-set.js +0 -1
  86. package/dist/testing/git.d.ts +3 -0
  87. package/dist/testing/git.js +36 -0
  88. package/dist/testing/host-fakes.d.ts +30 -0
  89. package/dist/testing/host-fakes.js +104 -0
  90. package/package.json +5 -2
  91. package/src/api/dsh.ts +8 -1
  92. package/src/contract/unit-declaration.ts +20 -1
  93. package/src/contract/unit.ts +3 -0
  94. package/src/host/__tests__/env-policy.test.ts +114 -0
  95. package/src/host/__tests__/fs-write.test.ts +96 -0
  96. package/src/host/__tests__/preflight-route.test.ts +29 -0
  97. package/src/host/__tests__/seam.test.ts +296 -0
  98. package/src/host/__tests__/shell.test.ts +24 -0
  99. package/src/host/__tests__/time.test.ts +20 -0
  100. package/src/host/adapter-set.ts +0 -1
  101. package/src/host/changelog.ts +2 -1
  102. package/src/host/config-sync.ts +3 -90
  103. package/src/host/env-policy.ts +192 -0
  104. package/src/host/extension.ts +2 -1
  105. package/src/host/flow/run.ts +2 -1
  106. package/src/host/fs-write.ts +137 -0
  107. package/src/host/host-kit.ts +7 -2
  108. package/src/host/http.ts +11 -5
  109. package/src/host/installed-sources.ts +4 -5
  110. package/src/host/long-task.ts +3 -3
  111. package/src/host/package-content.ts +23 -13
  112. package/src/host/package-route.ts +10 -9
  113. package/src/host/panel-state.ts +2 -1
  114. package/src/host/patch-blocks.ts +67 -0
  115. package/src/host/patch.ts +5 -89
  116. package/src/host/port-types.ts +9 -9
  117. package/src/host/profile-registries.ts +2 -3
  118. package/src/host/registry-declaration.ts +17 -12
  119. package/src/host/release-probe.ts +47 -34
  120. package/src/host/seam/denial.ts +26 -0
  121. package/src/host/seam/env.ts +23 -0
  122. package/src/host/seam/exec.ts +94 -0
  123. package/src/host/seam/host-env.ts +20 -0
  124. package/src/host/seam/intent.ts +101 -0
  125. package/src/host/seam/policy.ts +89 -0
  126. package/src/host/seam/process.ts +90 -0
  127. package/src/host/seam/run.ts +484 -0
  128. package/src/host/seam/service.ts +8 -0
  129. package/src/host/seam/unit-seam.ts +62 -0
  130. package/src/host/shell.ts +17 -1
  131. package/src/host/time.ts +16 -0
  132. package/src/host/value-handoff.ts +3 -2
  133. package/src/host/workspace-store.ts +2 -8
  134. package/src/host.ts +11 -0
  135. package/src/i18n/en.ts +3 -3
  136. package/src/i18n/zh.ts +3 -3
  137. package/src/testing/fake-adapter-set.ts +0 -1
  138. package/src/testing/host-fakes.ts +126 -0
  139. package/dist/lib/unit-plugin.d.ts +0 -28
  140. package/dist/lib/unit-plugin.js +0 -23
package/dist/i18n/en.js CHANGED
@@ -583,9 +583,8 @@ export const en = {
583
583
  'env.title': 'Preparing the workbench',
584
584
  'env.checking': 'Getting the runtime ready…',
585
585
  'env.installing': 'Installing background tools — the first run takes a moment…',
586
- 'env.installingToolchain': 'Installing the workbench’s own npm / pnpm — the first run downloads them, so it can take a while.',
586
+ 'env.installingToolchain': 'Installing the workbench’s own pnpm — the first run downloads it, so it can take a while.',
587
587
  'env.failed': 'One step away',
588
- 'env.elapsed': 'Waiting {seconds}s',
589
588
  'env.stepFailed.install': 'install failed',
590
589
  'env.stepFailed.path': 'installed but not found',
591
590
  'env.stepFailed.shell': 'cannot reach the command line',
@@ -604,14 +603,15 @@ export const en = {
604
603
  'env.fix.whyShell': 'The workbench cannot reach the command line on this machine, so it cannot fetch data \u2014 you cannot install this from here; someone needs to fix the background environment.',
605
604
  'env.fix.whyHost': 'The workbench runs a few checks on the command line and collects what they return; this time the command went out and nothing came back. The tools themselves are most likely fine \u2014 reinstalling Node / npm / pnpm will not help.',
606
605
  'env.fix.step': 'Run this in a terminal, then hit Retry:',
606
+ 'env.fix.stepRetry': 'Hit Retry to try again; if it still fails you can enter the workbench anyway and restart it once the install succeeds.',
607
607
  'env.fix.stepPath': 'Open a new terminal window (or make sure npm\u2019s global bin directory is on PATH), then hit Retry.',
608
608
  'env.fix.stepShell': 'Restart the workbench (or dsh); if it keeps happening, the workbench still cannot reach the command line.',
609
609
  'env.fix.stepHost': 'Quit the workbench completely (including the tray icon), clear the dsh-* leftovers in the system temp folder, then open it again. If it keeps happening, update dsh.',
610
610
  'env.fix.permission': 'Permission denied: rerun with sudo, or point npm\u2019s global directory at your home.',
611
611
  'env.fix.network': 'Network unreachable: check your network or proxy, then retry.',
612
612
  'env.fix.details': 'Details (for troubleshooting)',
613
- 'env.log': 'Detailed output',
614
613
  'env.retry': 'Retry',
614
+ 'env.failed.continue': 'Enter workbench anyway',
615
615
  'env.wake': 'Open browser',
616
616
  'env.wake.opening': 'Opening the browser…',
617
617
  'env.wake.browserOpen': 'The browser is already running but the extension is not connected — check that it is enabled.',
@@ -593,9 +593,8 @@ export declare const dictionaries: {
593
593
  readonly 'env.title': "准备工作台";
594
594
  readonly 'env.checking': "正在准备运行环境…";
595
595
  readonly 'env.installing': "正在安装后台工具,第一次会慢一点…";
596
- readonly 'env.installingToolchain': "正在装工作台自己那份 npm / pnpm —— 第一次要下载,慢一点正常。";
596
+ readonly 'env.installingToolchain': "正在装工作台自己那份 pnpm —— 第一次要下载,慢一点正常。";
597
597
  readonly 'env.failed': "还差一步就能用了";
598
- readonly 'env.elapsed': "已等待 {seconds} 秒";
599
598
  readonly 'env.stepFailed.install': "装不上";
600
599
  readonly 'env.stepFailed.path': "装了但还找不到";
601
600
  readonly 'env.stepFailed.shell': "连不上命令行";
@@ -614,14 +613,15 @@ export declare const dictionaries: {
614
613
  readonly 'env.fix.whyShell': "工作台拿不到这台机器的命令行,所以取不了数据 —— 这一步你装不了,需要有人处理后台环境。";
615
614
  readonly 'env.fix.whyHost': "工作台要靠命令行跑几条检查,再把结果收回来;这次命令发出去了,结果一直没回来。工具本身多半是好的 —— 重装 Node / npm / pnpm 不会有帮助。";
616
615
  readonly 'env.fix.step': "在终端里运行下面这条命令,装好之后点「重试」:";
616
+ readonly 'env.fix.stepRetry': "点「重试」再装一次;还装不上也可以先进入工作台 —— 装好之后重启工作台就会用上。";
617
617
  readonly 'env.fix.stepPath': "新开一个终端窗口(或确认 npm 的全局 bin 目录在 PATH 里),然后点「重试」。";
618
618
  readonly 'env.fix.stepShell': "重启一次工作台(或 dsh);如果反复出现,说明工作台还是拿不到命令行。";
619
619
  readonly 'env.fix.stepHost': "完全退出工作台(托盘图标也要退),清掉系统临时目录里 dsh- 开头的残留,再重新打开;反复出现就升级 dsh。";
620
620
  readonly 'env.fix.permission': "权限不够:在命令前加 sudo 重跑,或先把 npm 的全局目录配到你的用户目录。";
621
621
  readonly 'env.fix.network': "网络不通:检查网络或代理设置后重试。";
622
622
  readonly 'env.fix.details': "详细输出(排障用)";
623
- readonly 'env.log': "详细输出";
624
623
  readonly 'env.retry': "重试";
624
+ readonly 'env.failed.continue': "先进入工作台";
625
625
  readonly 'env.wake': "打开浏览器";
626
626
  readonly 'env.wake.opening': "正在打开浏览器…";
627
627
  readonly 'env.wake.browserOpen': "浏览器已经开着,但扩展没连上 —— 检查扩展是否启用。";
@@ -827,7 +827,7 @@ export declare const dictionaries: {
827
827
  readonly 'configSync.emptyProviders': "工作台还没有任何模型供应商 —— 去「配置同步」从某个 profile 把模型供应商那几行同步过来,或自己去「模型」里配。";
828
828
  readonly 'configSync.failed': "同步没成功,再试一次。";
829
829
  };
830
- en: Record<"time.now" | "time.ago" | "time.minutes" | "time.hours" | "time.days" | "blocker.retry" | "blocker.copy" | "blocker.unknown.title" | "blocker.login.go" | "blocker.login.titleGeneric" | "blocker.login.title" | "blocker.login.manual" | "blocker.login.hint" | "blocker.forbidden.open" | "blocker.forbidden.titleGeneric" | "blocker.forbidden.title" | "blocker.forbidden.hint" | "blocker.timeout.hint" | "blocker.exec.hint" | "blocker.fix.install" | "blocker.market.open" | "env.unit.failed" | "env.unit.failedHint" | "env.unit.unsupported" | "env.unit.unsupportedHint" | "env.unit.degraded" | "env.unit.degradedHint" | "env.unit.unchecked" | "env.unit.uncheckedHint" | "profileCreate.nav" | "profileCreate.lead" | "profileCreate.name" | "profileCreate.nameHint" | "profileCreate.source" | "profileCreate.current" | "profileCreate.copy" | "profileCreate.settings" | "profileCreate.create" | "profileCreate.creating" | "profileCreate.created" | "profileCreate.command" | "profileCreate.readFailed" | "profileCreate.retry" | "profileCreate.reading" | "profileCreate.noProfiles" | "profileCreate.failed" | "configSync.nav" | "configSync.lead" | "configSync.source" | "configSync.sourceBroken" | "configSync.sourceRows" | "configSync.sourceDead" | "configSync.refresh" | "configSync.loading" | "configSync.readHint" | "configSync.tag.new" | "configSync.tag.differs" | "configSync.conflictNote" | "configSync.code.lang" | "configSync.code.copy" | "configSync.code.copied" | "configSync.code.wrap" | "configSync.code.unwrap" | "configSync.code.collapse" | "configSync.code.collapseAria" | "configSync.code.expandAria" | "configSync.code.expand" | "configSync.missing" | "configSync.apply" | "configSync.applyNone" | "configSync.applying" | "configSync.applied" | "configSync.appliedUnverified" | "configSync.appliedIds" | "configSync.skippedIds" | "configSync.nothing" | "configSync.unreadable" | "configSync.noSource" | "configSync.emptyProviders" | "configSync.failed" | "env.need.bin.missing" | "env.need.bin.hint" | "env.need.extension.missing" | "env.need.extension.outdated" | "env.need.extension.hint" | "env.need.lib.missing" | "env.need.lib.outdated" | "env.need.lib.unsatisfied" | "env.need.lib.hint" | "env.need.env.missing" | "env.need.env.hint" | "brand.name" | "toggle.open" | "toggle.collapse" | "project.label" | "workspace.section" | "project.none" | "project.empty" | "project.add" | "project.add.busy" | "project.add.failed" | "project.search.label" | "project.search.placeholder" | "project.search.empty" | "project.group.workspaces" | "project.group.defaultWorkspace" | "project.group.workshop" | "project.rename.row" | "project.rename.current" | "project.rename.title" | "project.rename.description" | "project.rename.field" | "project.rename.placeholder" | "project.rename.hint" | "project.rename.save" | "project.rename.saving" | "project.rename.cancel" | "project.rename.failed" | "session.new" | "session.new.label" | "session.empty" | "session.noProject" | "session.list.label" | "session.copy" | "session.pinned" | "session.actions" | "status.idle" | "status.running" | "status.longTask" | "status.waitingApproval" | "status.planReview" | "status.waitingAnswer" | "status.compact.approval" | "status.compact.planReview" | "status.compact.answer" | "status.completed" | "status.subagentsRunning.one" | "status.subagentsRunning.other" | "project.attention.warning.one" | "project.attention.warning.other" | "project.attention.running.one" | "project.attention.running.other" | "project.attention.longTask.one" | "project.attention.longTask.other" | "project.attention.done.one" | "project.attention.done.other" | "project.attention.state.warning" | "project.attention.state.running" | "project.attention.state.done" | "hover.copied" | "time.short.minutes" | "time.short.hours" | "time.short.days" | "time.short.months" | "time.short.years" | "panels.title" | "panels.groupBoardless" | "panels.groupPlugins" | "runtime.plugin" | "runtime.pluginOf" | "runtime.pluginThing" | "runtime.pluginArea" | "panels.market.defaultHint" | "panels.market.defaultLabel" | "panels.market.defaultLocked" | "panels.followAll" | "panels.followAllConfirmTitle" | "panels.followAllConfirmDetail" | "panels.followAllConfirmAck" | "panels.followAllConfirmYes" | "panels.followAllConfirmNo" | "panels.enabled" | "panels.disabled" | "panels.choose" | "panels.buildModule" | "panels.failed" | "panels.dragHint" | "panels.unknownStep" | "panels.labelWithHint" | "panels.hintJoin" | "panels.dep.failed" | "panels.dep.unchecked" | "panels.dep.missing" | "panels.dep.outdated" | "panels.dep.degraded" | "panels.dep.unsupported" | "panels.tab.modules" | "panels.tab.market" | "panels.browseMarket" | "panels.noneInstalled" | "panels.noneInstalledHint" | "panels.market.installed" | "panels.market.notActive" | "panels.market.notUsable" | "panels.market.broken" | "panels.market.hasNew" | "panels.market.hasProblem" | "panels.market.missing" | "panels.market.unchecked" | "panels.market.uncheckedHint" | "panels.market.checking" | "panels.market.sectionInstalled" | "panels.market.sectionPending" | "panels.market.sectionShared" | "panels.market.sharedUsedBy" | "panels.market.listSeparator" | "panels.market.sharedMissing" | "panels.market.sharedOutdated" | "panels.market.sharedUnsatisfied" | "panels.market.sharedOk" | "panels.market.versionArrow" | "panels.market.lead" | "panels.market.install" | "panels.market.update" | "panels.market.swapSlow" | "panels.market.removeSlow" | "panels.market.updateNoChange" | "panels.market.updateUnknownVersion" | "panels.market.updateGone" | "panels.market.updateRestored" | "panels.market.updateBehind" | "panels.market.updateStuck.title" | "panels.market.updateStuck.factNoChange" | "panels.market.updateStuck.copiedHint" | "panels.market.selfUpdateFailed" | "panels.market.selfUpdateUnknown" | "panels.market.selfUpdateRolledBack" | "panels.market.uninstall" | "panels.market.uninstallLabel" | "panels.market.installing" | "panels.market.updating" | "panels.market.uninstalling" | "panels.market.confirmUninstallTitle" | "panels.market.confirmUninstallDetail" | "panels.market.confirmUninstallAck" | "panels.market.confirmYes" | "panels.market.confirmNo" | "panels.market.noMarketSource" | "panels.market.failed" | "panels.market.failure.permission" | "panels.market.failure.diskFull" | "panels.market.failure.sandbox" | "panels.market.failure.unknown" | "panels.market.failure.factOwner" | "panels.market.failure.factMode" | "panels.market.failure.factSpace" | "panels.market.failure.factStuck" | "panels.market.failure.nowhere" | "panels.market.failure.copyFix" | "panels.market.failure.copied" | "panels.market.failure.copiedHint" | "panels.market.failure.askAgent" | "panels.market.failure.askAgentText" | "panels.market.failure.askAgentHint" | "panels.market.failure.recheck" | "panels.market.failure.showOutput" | "panels.market.failure.hideOutput" | "panels.market.failure.term.commandLine" | "panels.market.failure.term.signal" | "panels.market.failure.term.exitCode" | "panels.market.failure.term.noExitCode" | "panels.market.failure.term.running" | "panels.market.failure.term.failed" | "panels.market.failure.term.done" | "panels.market.failure.term.copy" | "panels.market.failure.term.copied" | "panels.market.failure.term.noOutput" | "panels.market.failure.term.collapse" | "panels.market.failure.term.expandAria" | "panels.market.failure.term.expand" | "panels.market.needEnv" | "panels.market.needCommands" | "panels.market.needBinary" | "panels.market.needLib" | "panels.market.localMark" | "panels.market.noSource" | "panels.market.badSource" | "panels.market.empty" | "panels.market.sectionPlugins" | "panels.market.openDetail" | "panels.market.detailBack" | "panels.market.detailSourceTitle" | "panels.market.detailSource" | "panels.market.detailRegistry" | "panels.market.detailSpec" | "panels.market.detailUnit" | "panels.market.detailVersion" | "panels.market.detailLatest" | "panels.market.detailPluginName" | "panels.market.detailInstalledAt" | "panels.market.detailMarket" | "panels.market.detailRepository" | "panels.market.detailCommit" | "panels.market.detailDirectory" | "panels.market.detailUpdateSource" | "panels.market.detailUpdateVersion" | "panels.market.detailLocalDirectory" | "panels.market.detailUnknown" | "panels.market.moduleOutdated" | "panels.market.updateNeedsWorkbench" | "panels.market.updateIncompatible" | "panels.market.moduleRefused" | "panels.market.moduleRestartHint" | "panels.market.pendingRestart" | "panels.market.pendingFollowUp" | "panels.market.migrationHint" | "panels.market.migrateAction" | "panels.market.migrating" | "panels.market.migrateConfirmTitle" | "panels.market.migrateConfirmDetail" | "panels.market.migrateConfirmAck" | "panels.market.migrateConfirmYes" | "panels.market.migrateDone" | "panels.market.dismissFollowUp" | "panels.market.dismissing" | "panels.market.dismissFollowUpTitle" | "panels.market.dismissFollowUpDetail" | "panels.market.dismissFollowUpAck" | "panels.market.dismissFollowUpYes" | "panels.market.dismissed" | "panels.market.workbenchName" | "panels.market.pluginBroken" | "panels.market.restartNeeded" | "panels.market.foot" | "panels.market.checkUpdates" | "panels.market.checkAll" | "panels.market.checkingNow" | "panels.market.checkFailed" | "panels.market.checkedAt" | "panels.market.latestPartial" | "panels.market.latestNoRegistry" | "panels.market.latestProbeFailed" | "panels.market.justNow" | "panels.market.minutesAgo" | "panels.market.hoursAgo" | "panels.market.add.description" | "panels.market.add.specPlaceholder" | "panels.market.add.guideToggle" | "panels.market.add.guideHide" | "panels.market.add.guideIdTitle" | "panels.market.add.guideIdExample" | "panels.market.add.guideIdHint" | "panels.market.add.guideGitTitle" | "panels.market.add.guideGitExample" | "panels.market.add.guideGitHint" | "panels.market.add.guidePathTitle" | "panels.market.add.guidePathExample" | "panels.market.add.guidePathHint" | "panels.market.add.guideExampleLabel" | "panels.market.add.guideFill" | "panels.market.add.guideSafety" | "panels.market.add.registryLegend" | "panels.market.add.registryOfficial" | "panels.market.add.registryMirror" | "panels.market.add.registryWithHost" | "panels.market.add.registryToggle" | "panels.market.add.installVersion" | "panels.market.add.registryDefault" | "panels.market.add.registryCustom" | "panels.market.add.registryCustomPlaceholder" | "panels.market.add.registryCustomHint" | "panels.market.add.registryCustomInvalid" | "panels.market.add.run" | "panels.market.add.edit" | "panels.market.add.changeRegistry" | "panels.market.add.installingTitle" | "panels.market.add.installedTitle" | "panels.market.add.failedTitle" | "panels.market.add.cancelledTitle" | "panels.market.add.failureNetworkHost" | "panels.market.add.problemInvalid" | "panels.market.add.problemInstalled" | "panels.market.add.problemNotFound" | "panels.market.add.problemNotPackage" | "panels.market.add.problemNotBundle" | "panels.market.add.problemNotWorkbenchModule" | "panels.market.add.problemNotModuleOrPlugin" | "panels.market.add.failureNotModuleOrPlugin" | "panels.market.add.installedPlugin" | "panels.market.add.pluginPreview" | "panels.market.add.pluginAlias" | "panels.market.add.problemNetwork" | "panels.market.add.problemUnknown" | "panels.market.add.failureNetwork" | "panels.market.add.failureNotFound" | "panels.market.add.failureNoMatchingVersion" | "panels.market.add.failureDiskFull" | "panels.market.add.failurePermission" | "panels.market.add.failureBuildBlocked" | "panels.market.add.failureIntegrity" | "panels.market.add.failureStopProfile" | "panels.market.add.failureCancelled" | "panels.market.add.failureTimeout" | "panels.market.add.failurePnpmMissing" | "panels.market.add.failureInstalled" | "panels.market.add.failureGeneric" | "panels.market.add.failureCredentials" | "panels.market.add.approveTitle" | "panels.market.add.approveCaution" | "panels.market.add.approveRun" | "panels.market.add.restart" | "panels.market.add.tookEffect" | "panels.market.add.details" | "panels.market.add.open" | "panels.market.add.title" | "panels.market.add.intro" | "panels.market.add.specLabel" | "panels.market.add.specHint" | "panels.market.add.exampleTitle" | "panels.market.add.exampleFill" | "panels.market.add.registryLabel" | "panels.market.add.registryProfile" | "panels.market.add.registryPnpm" | "panels.market.add.check" | "panels.market.add.checking" | "panels.market.add.classifying" | "panels.market.add.change" | "panels.market.add.previewTitle" | "panels.market.add.fieldName" | "panels.market.add.fieldVersion" | "panels.market.add.fieldDescription" | "panels.market.add.fieldSource" | "panels.market.add.install" | "panels.market.add.installing" | "panels.market.add.cancel" | "panels.market.add.close" | "panels.market.add.retry" | "panels.market.add.changeSource" | "panels.market.tabInstalled" | "panels.market.tabs" | "panels.tab.discover" | "panels.discover.loading" | "panels.discover.slowHint" | "panels.discover.lead" | "panels.discover.addSource" | "panels.discover.addingSource" | "panels.discover.addFirstSource" | "panels.discover.removeSource" | "panels.discover.removeTitle" | "panels.discover.removeBody" | "panels.discover.sourceActions" | "panels.discover.sourceStateWritable" | "panels.discover.sourceStateReadOnly" | "panels.discover.sourceEnable" | "panels.discover.sourceDisable" | "panels.discover.sourceWorking" | "panels.discover.sourceEnabled" | "panels.discover.sourceReadOnly" | "panels.discover.refresh" | "panels.discover.search" | "panels.discover.clearSearch" | "panels.discover.all" | "panels.discover.sourceLabel" | "panels.discover.sourceKind" | "panels.discover.sourceKindHttp" | "panels.discover.sourceKindGit" | "panels.discover.sourceUrl" | "panels.discover.sourcePlaceholder" | "panels.discover.sourceRef" | "panels.discover.sourcePath" | "panels.discover.sourceLocal" | "panels.discover.sourceLocalHint" | "panels.discover.save" | "panels.discover.cancel" | "panels.discover.retry" | "panels.discover.noSource" | "panels.discover.noSourceHint" | "panels.discover.sourcesFailed" | "panels.discover.unreadable" | "panels.discover.sandbox" | "panels.discover.sourceAuth" | "panels.discover.invalid" | "panels.discover.emptyRepo" | "panels.discover.missingIndex" | "panels.discover.initTitle" | "panels.discover.initCta" | "panels.discover.initWhat" | "panels.discover.initBranch" | "panels.discover.initBranchHint" | "panels.discover.initBranchBad" | "panels.discover.initOk" | "panels.discover.initBusy" | "panels.discover.initDone" | "panels.discover.stale" | "panels.discover.empty" | "panels.discover.noMatch" | "panels.discover.notInstalled" | "panels.discover.installed" | "panels.discover.installedVersion" | "panels.discover.update" | "panels.discover.badShell" | "panels.discover.badShellDetail" | "panels.discover.unverified" | "panels.discover.installing" | "panels.discover.installingNamed" | "panels.discover.cancelInstall" | "panels.discover.cancelling" | "panels.discover.installCancelled" | "panels.discover.installedDone" | "panels.discover.failed" | "panels.discover.transportTitle" | "panels.discover.transportSsh" | "panels.discover.transportHttps" | "panels.discover.transportOk" | "panels.discover.transportAuth" | "panels.discover.transportUnreachable" | "panels.discover.transportUnknown" | "panels.discover.transportChecking" | "panels.discover.transportTest" | "panels.discover.transportPlaceholder" | "panels.discover.transportNeedsAuth" | "panels.discover.transportChange" | "panels.discover.transportChangeHide" | "panels.discover.transportNone" | "panels.discover.expand" | "panels.discover.collapse" | "panels.discover.versionCount" | "panels.discover.sourceNpm" | "panels.discover.sourceNpmDefault" | "panels.discover.sourceGit" | "panels.discover.installVersion" | "panels.discover.confirmTitle" | "panels.discover.confirmDetail" | "panels.discover.confirmAck" | "panels.discover.confirmOk" | "panels.discover.confirmCancel" | "panels.discover.marketMenu" | "panels.discover.manageSources" | "panels.discover.sourcesTitle" | "panels.discover.sourcesIntro" | "panels.discover.sourcesLabel" | "panels.discover.sourceTrust" | "panels.discover.sourceDuplicate" | "panels.discover.sourceBadUrl" | "panels.discover.close" | "panels.discover.labelsMenu" | "panels.discover.labelsCount" | "panels.discover.tagsAll" | "panels.discover.sort" | "panels.discover.sortWith" | "panels.discover.sortRelevance" | "panels.discover.sortDefault" | "panels.discover.sortPublished" | "panels.discover.categoriesLabel" | "panels.discover.showMore" | "panels.discover.entryMeta" | "panels.discover.entryMetaAuthor" | "panels.discover.openEntry" | "panels.discover.cardInstall" | "panels.discover.cardInstalled" | "panels.discover.cardUpdate" | "panels.discover.cardBlocked" | "panels.discover.installTitle" | "panels.discover.installVersionTitle" | "panels.discover.openInstalled" | "panels.discover.noCompatibleVersion" | "panels.discover.detailBack" | "panels.discover.publishedAt" | "panels.discover.detailMarket" | "panels.discover.detailIncompatible" | "panels.discover.detailUnknown" | "panels.discover.detailSource" | "panels.discover.authorUnknown" | "panels.discover.tabOverview" | "panels.discover.tabReadme" | "panels.discover.tabChangelog" | "panels.discover.docReadme" | "panels.discover.docChangelog" | "panels.discover.docLoading" | "panels.discover.docMissing" | "panels.discover.docUnavailable" | "panels.discover.docUnknownReason" | "panels.discover.detailTabs" | "panels.discover.factPackage" | "panels.discover.factRegistry" | "panels.discover.factRepository" | "panels.discover.factCommit" | "panels.discover.factDirectory" | "panels.discover.factPublished" | "panels.discover.factAuthor" | "panels.discover.factHomepage" | "panels.discover.factCategory" | "panels.discover.factLabels" | "panels.discover.factMarket" | "panels.discover.detailVersions" | "panels.discover.versionsLabel" | "panels.discover.tagRecommended" | "panels.discover.tagPrerelease" | "panels.discover.tagInstalled" | "panels.discover.tagIncompatible" | "panels.discover.tagUnknown" | "panels.discover.selected" | "panels.discover.done" | "panels.discover.installTrust" | "panels.discover.progress" | "panels.market.add.approveBuilds" | "panels.market.add.approveHint" | "panels.market.add.doneApplied" | "panels.market.add.doneRestart" | "panels.market.add.restartWhy" | "panels.market.add.restartWhy.no-hmr" | "panels.market.add.restartWhy.package-moved" | "panels.market.add.restartWhy.host-module" | "panels.market.add.restartWhy.unmanaged-plugin" | "panels.market.add.restartWhy.module-comparison" | "panels.market.add.cancelled" | "panels.market.add.failed" | "panels.market.add.removed" | "panels.market.add.supplyPending" | "panels.market.add.supplyFailed" | "panels.market.add.notModule" | "panels.market.add.removedRestart" | "panels.market.add.remove" | "panels.market.add.problem.invalidSpec" | "panels.market.add.problem.alreadyInstalled" | "panels.market.add.problem.notFound" | "panels.market.add.problem.notAPackage" | "panels.market.add.problem.notABundle" | "panels.market.add.problem.network" | "panels.market.add.problem.unknown" | "panels.market.add.reason.invalidSpec" | "panels.market.add.reason.incompatible" | "panels.market.add.reason.notBundle" | "panels.market.add.reason.notRemovable" | "panels.market.add.reason.bundleInUse" | "panels.market.add.reason.stopProfile" | "panels.market.add.reason.staleApproval" | "panels.market.add.reason.operationError" | "panels.market.add.reason.buildBlocked" | "panels.market.add.reason.pnpmMissing" | "panels.market.add.reason.noMatchingVersion" | "panels.market.add.reason.diskFull" | "panels.market.add.reason.permission" | "panels.market.add.reason.integrity" | "panels.market.add.reason.timeout" | "panels.market.add.reason.network" | "panels.market.add.reason.notFound" | "panels.market.add.reason.unknown" | "blocker.fix.update" | "blocker.fix.running" | "blocker.fix.failed" | "blocker.retry.running" | "panels.reading" | "panels.cardBroken" | "panels.cardRetry" | "panels.empty" | "panels.emptyHint" | "env.title" | "env.checking" | "env.installing" | "env.installingToolchain" | "env.failed" | "env.elapsed" | "env.stepFailed.install" | "env.stepFailed.path" | "env.stepFailed.shell" | "env.stepFailed.host" | "env.toolchain.ok" | "env.toolchain.warn" | "env.runtime.ok" | "env.bridge.ok" | "env.bridge.short" | "env.bridge.why" | "env.bridge.hold" | "env.bridge.unknown" | "env.fix.title" | "env.fix.why" | "env.fix.whyPath" | "env.fix.whyShell" | "env.fix.whyHost" | "env.fix.step" | "env.fix.stepPath" | "env.fix.stepShell" | "env.fix.stepHost" | "env.fix.permission" | "env.fix.network" | "env.fix.details" | "env.log" | "env.retry" | "env.wake" | "env.wake.opening" | "env.wake.browserOpen" | "env.wake.noBrowser" | "env.wake.failed" | "env.bridge.continue" | "env.diy.ok" | "env.diy.short" | "env.diy.hold" | "env.diy.why" | "env.diy.rows" | "env.diy.noRow" | "env.diy.step" | "env.diy.continue" | "env.copyCommand" | "env.copied" | "env.step.toolchain" | "env.step.adapter" | "env.step.runtime" | "env.step.bridge" | "env.step.diy" | "env.step.warm" | "env.warm.done" | "env.warm.short" | "adapterSet.not-configured" | "adapterSet.no-profile" | "adapterSet.malformed" | "adapterSet.not-resolvable" | "adapterSet.import-failed" | "adapterSet.bad-export" | "adapterSet.factory-failed" | "adapterSet.incompatible-version" | "adapterSet.missing-member" | "env.unit.hint" | "rightbar.label" | "rightbar.expand" | "rightbar.collapse" | "rightbar.column.label" | "rightbar.column.workbench" | "rightbar.column.dsh" | "rightbar.refresh" | "rightbar.refreshing" | "rightbar.updatedAt" | "rightbar.noProject" | "rightbar.openPlatform" | "error.unknown" | "board.title" | "panel.conversation" | "panels.label" | "adapterSet.title" | "adapterSet.lead" | "adapterSet.active" | "adapterSet.defaults" | "adapterSet.failed" | "adapterSet.healthUnreadable" | "workbenchSettings.nav" | "workbenchSettings.lead" | "sidebarEdition.nav" | "sidebarEdition.lead" | "sidebarEdition.official" | "sidebarEdition.officialHint" | "sidebarEdition.custom" | "sidebarEdition.customHint" | "sidebarEdition.saving" | "sidebarEdition.reloadRequired" | "sidebarEdition.reload" | "sidebarEdition.failed" | "debug.workspace" | "debug.status" | "debug.status.trouble" | "debug.stalled" | "debug.act.pause" | "debug.act.resume" | "debug.act.stop" | "debug.act.stop.ask" | "debug.card.here.title" | "debug.card.here.note" | "debug.card.away.note" | "debug.card.paused.note" | "debug.card.hidden.note" | "record.waiting" | "record.waiting.note" | "record.recording" | "record.recording.note" | "record.recording.shots" | "record.finished" | "record.finished.note" | "record.act.cancel" | "record.act.halt" | "approval.record.site" | "approval.record.what" | "approval.record.lands" | "approval.record.noUrl" | "approval.record.oneAction" | "approval.record.noSwitch" | "approval.longTask.what" | "approval.longTask.signal" | "approval.plugin.name" | "approval.plugin.command" | "approval.plugin.note" | "approval.publish.module" | "approval.publish.target" | "approval.publish.version" | "approval.publish.author" | "approval.publish.authorMissing" | "approval.publish.labels" | "approval.publish.labelsMissing" | "approval.publish.owner" | "approval.publish.ownerUnowned" | "approval.publish.ownerTaken" | "approval.publish.unit" | "approval.publish.unitTaken" | "approval.publish.path" | "approval.publish.pathTaken" | "approval.publish.registry" | "approval.publish.repo" | "approval.publish.branch" | "approval.publish.defaultBranch" | "approval.publish.artifacts" | "approval.publish.index" | "approval.publish.commits" | "approval.publish.twoCommits" | "approval.publish.reading" | "approval.publish.changelog" | "approval.publish.changelogPending" | "approval.publish.changelogMissing" | "approval.publish.targetAuto" | "approval.publish.targetTeam" | "approval.publish.targetPublic" | "approval.publish.targetTarball" | "approval.publish.targetGit" | "approval.publish.targetMarket" | "approval.publish.targetLocal" | "approval.market.source" | "approval.market.url" | "approval.market.action" | "approval.market.policy" | "approval.market.enable" | "approval.market.disable" | "approval.market.writable" | "approval.market.readOnly" | "approval.market.reading" | "markdown.copy" | "markdown.copied" | "markdown.footnotes", string>;
830
+ en: Record<"time.now" | "time.ago" | "time.minutes" | "time.hours" | "time.days" | "blocker.retry" | "blocker.copy" | "blocker.unknown.title" | "blocker.login.go" | "blocker.login.titleGeneric" | "blocker.login.title" | "blocker.login.manual" | "blocker.login.hint" | "blocker.forbidden.open" | "blocker.forbidden.titleGeneric" | "blocker.forbidden.title" | "blocker.forbidden.hint" | "blocker.timeout.hint" | "blocker.exec.hint" | "blocker.fix.install" | "blocker.market.open" | "env.unit.failed" | "env.unit.failedHint" | "env.unit.unsupported" | "env.unit.unsupportedHint" | "env.unit.degraded" | "env.unit.degradedHint" | "env.unit.unchecked" | "env.unit.uncheckedHint" | "profileCreate.nav" | "profileCreate.lead" | "profileCreate.name" | "profileCreate.nameHint" | "profileCreate.source" | "profileCreate.current" | "profileCreate.copy" | "profileCreate.settings" | "profileCreate.create" | "profileCreate.creating" | "profileCreate.created" | "profileCreate.command" | "profileCreate.readFailed" | "profileCreate.retry" | "profileCreate.reading" | "profileCreate.noProfiles" | "profileCreate.failed" | "configSync.nav" | "configSync.lead" | "configSync.source" | "configSync.sourceBroken" | "configSync.sourceRows" | "configSync.sourceDead" | "configSync.refresh" | "configSync.loading" | "configSync.readHint" | "configSync.tag.new" | "configSync.tag.differs" | "configSync.conflictNote" | "configSync.code.lang" | "configSync.code.copy" | "configSync.code.copied" | "configSync.code.wrap" | "configSync.code.unwrap" | "configSync.code.collapse" | "configSync.code.collapseAria" | "configSync.code.expandAria" | "configSync.code.expand" | "configSync.missing" | "configSync.apply" | "configSync.applyNone" | "configSync.applying" | "configSync.applied" | "configSync.appliedUnverified" | "configSync.appliedIds" | "configSync.skippedIds" | "configSync.nothing" | "configSync.unreadable" | "configSync.noSource" | "configSync.emptyProviders" | "configSync.failed" | "env.need.bin.missing" | "env.need.bin.hint" | "env.need.extension.missing" | "env.need.extension.outdated" | "env.need.extension.hint" | "env.need.lib.missing" | "env.need.lib.outdated" | "env.need.lib.unsatisfied" | "env.need.lib.hint" | "env.need.env.missing" | "env.need.env.hint" | "brand.name" | "toggle.open" | "toggle.collapse" | "project.label" | "workspace.section" | "project.none" | "project.empty" | "project.add" | "project.add.busy" | "project.add.failed" | "project.search.label" | "project.search.placeholder" | "project.search.empty" | "project.group.workspaces" | "project.group.defaultWorkspace" | "project.group.workshop" | "project.rename.row" | "project.rename.current" | "project.rename.title" | "project.rename.description" | "project.rename.field" | "project.rename.placeholder" | "project.rename.hint" | "project.rename.save" | "project.rename.saving" | "project.rename.cancel" | "project.rename.failed" | "session.new" | "session.new.label" | "session.empty" | "session.noProject" | "session.list.label" | "session.copy" | "session.pinned" | "session.actions" | "status.idle" | "status.running" | "status.longTask" | "status.waitingApproval" | "status.planReview" | "status.waitingAnswer" | "status.compact.approval" | "status.compact.planReview" | "status.compact.answer" | "status.completed" | "status.subagentsRunning.one" | "status.subagentsRunning.other" | "project.attention.warning.one" | "project.attention.warning.other" | "project.attention.running.one" | "project.attention.running.other" | "project.attention.longTask.one" | "project.attention.longTask.other" | "project.attention.done.one" | "project.attention.done.other" | "project.attention.state.warning" | "project.attention.state.running" | "project.attention.state.done" | "hover.copied" | "time.short.minutes" | "time.short.hours" | "time.short.days" | "time.short.months" | "time.short.years" | "panels.title" | "panels.groupBoardless" | "panels.groupPlugins" | "runtime.plugin" | "runtime.pluginOf" | "runtime.pluginThing" | "runtime.pluginArea" | "panels.market.defaultHint" | "panels.market.defaultLabel" | "panels.market.defaultLocked" | "panels.followAll" | "panels.followAllConfirmTitle" | "panels.followAllConfirmDetail" | "panels.followAllConfirmAck" | "panels.followAllConfirmYes" | "panels.followAllConfirmNo" | "panels.enabled" | "panels.disabled" | "panels.choose" | "panels.buildModule" | "panels.failed" | "panels.dragHint" | "panels.unknownStep" | "panels.labelWithHint" | "panels.hintJoin" | "panels.dep.failed" | "panels.dep.unchecked" | "panels.dep.missing" | "panels.dep.outdated" | "panels.dep.degraded" | "panels.dep.unsupported" | "panels.tab.modules" | "panels.tab.market" | "panels.browseMarket" | "panels.noneInstalled" | "panels.noneInstalledHint" | "panels.market.installed" | "panels.market.notActive" | "panels.market.notUsable" | "panels.market.broken" | "panels.market.hasNew" | "panels.market.hasProblem" | "panels.market.missing" | "panels.market.unchecked" | "panels.market.uncheckedHint" | "panels.market.checking" | "panels.market.sectionInstalled" | "panels.market.sectionPending" | "panels.market.sectionShared" | "panels.market.sharedUsedBy" | "panels.market.listSeparator" | "panels.market.sharedMissing" | "panels.market.sharedOutdated" | "panels.market.sharedUnsatisfied" | "panels.market.sharedOk" | "panels.market.versionArrow" | "panels.market.lead" | "panels.market.install" | "panels.market.update" | "panels.market.swapSlow" | "panels.market.removeSlow" | "panels.market.updateNoChange" | "panels.market.updateUnknownVersion" | "panels.market.updateGone" | "panels.market.updateRestored" | "panels.market.updateBehind" | "panels.market.updateStuck.title" | "panels.market.updateStuck.factNoChange" | "panels.market.updateStuck.copiedHint" | "panels.market.selfUpdateFailed" | "panels.market.selfUpdateUnknown" | "panels.market.selfUpdateRolledBack" | "panels.market.uninstall" | "panels.market.uninstallLabel" | "panels.market.installing" | "panels.market.updating" | "panels.market.uninstalling" | "panels.market.confirmUninstallTitle" | "panels.market.confirmUninstallDetail" | "panels.market.confirmUninstallAck" | "panels.market.confirmYes" | "panels.market.confirmNo" | "panels.market.noMarketSource" | "panels.market.failed" | "panels.market.failure.permission" | "panels.market.failure.diskFull" | "panels.market.failure.sandbox" | "panels.market.failure.unknown" | "panels.market.failure.factOwner" | "panels.market.failure.factMode" | "panels.market.failure.factSpace" | "panels.market.failure.factStuck" | "panels.market.failure.nowhere" | "panels.market.failure.copyFix" | "panels.market.failure.copied" | "panels.market.failure.copiedHint" | "panels.market.failure.askAgent" | "panels.market.failure.askAgentText" | "panels.market.failure.askAgentHint" | "panels.market.failure.recheck" | "panels.market.failure.showOutput" | "panels.market.failure.hideOutput" | "panels.market.failure.term.commandLine" | "panels.market.failure.term.signal" | "panels.market.failure.term.exitCode" | "panels.market.failure.term.noExitCode" | "panels.market.failure.term.running" | "panels.market.failure.term.failed" | "panels.market.failure.term.done" | "panels.market.failure.term.copy" | "panels.market.failure.term.copied" | "panels.market.failure.term.noOutput" | "panels.market.failure.term.collapse" | "panels.market.failure.term.expandAria" | "panels.market.failure.term.expand" | "panels.market.needEnv" | "panels.market.needCommands" | "panels.market.needBinary" | "panels.market.needLib" | "panels.market.localMark" | "panels.market.noSource" | "panels.market.badSource" | "panels.market.empty" | "panels.market.sectionPlugins" | "panels.market.openDetail" | "panels.market.detailBack" | "panels.market.detailSourceTitle" | "panels.market.detailSource" | "panels.market.detailRegistry" | "panels.market.detailSpec" | "panels.market.detailUnit" | "panels.market.detailVersion" | "panels.market.detailLatest" | "panels.market.detailPluginName" | "panels.market.detailInstalledAt" | "panels.market.detailMarket" | "panels.market.detailRepository" | "panels.market.detailCommit" | "panels.market.detailDirectory" | "panels.market.detailUpdateSource" | "panels.market.detailUpdateVersion" | "panels.market.detailLocalDirectory" | "panels.market.detailUnknown" | "panels.market.moduleOutdated" | "panels.market.updateNeedsWorkbench" | "panels.market.updateIncompatible" | "panels.market.moduleRefused" | "panels.market.moduleRestartHint" | "panels.market.pendingRestart" | "panels.market.pendingFollowUp" | "panels.market.migrationHint" | "panels.market.migrateAction" | "panels.market.migrating" | "panels.market.migrateConfirmTitle" | "panels.market.migrateConfirmDetail" | "panels.market.migrateConfirmAck" | "panels.market.migrateConfirmYes" | "panels.market.migrateDone" | "panels.market.dismissFollowUp" | "panels.market.dismissing" | "panels.market.dismissFollowUpTitle" | "panels.market.dismissFollowUpDetail" | "panels.market.dismissFollowUpAck" | "panels.market.dismissFollowUpYes" | "panels.market.dismissed" | "panels.market.workbenchName" | "panels.market.pluginBroken" | "panels.market.restartNeeded" | "panels.market.foot" | "panels.market.checkUpdates" | "panels.market.checkAll" | "panels.market.checkingNow" | "panels.market.checkFailed" | "panels.market.checkedAt" | "panels.market.latestPartial" | "panels.market.latestNoRegistry" | "panels.market.latestProbeFailed" | "panels.market.justNow" | "panels.market.minutesAgo" | "panels.market.hoursAgo" | "panels.market.add.description" | "panels.market.add.specPlaceholder" | "panels.market.add.guideToggle" | "panels.market.add.guideHide" | "panels.market.add.guideIdTitle" | "panels.market.add.guideIdExample" | "panels.market.add.guideIdHint" | "panels.market.add.guideGitTitle" | "panels.market.add.guideGitExample" | "panels.market.add.guideGitHint" | "panels.market.add.guidePathTitle" | "panels.market.add.guidePathExample" | "panels.market.add.guidePathHint" | "panels.market.add.guideExampleLabel" | "panels.market.add.guideFill" | "panels.market.add.guideSafety" | "panels.market.add.registryLegend" | "panels.market.add.registryOfficial" | "panels.market.add.registryMirror" | "panels.market.add.registryWithHost" | "panels.market.add.registryToggle" | "panels.market.add.installVersion" | "panels.market.add.registryDefault" | "panels.market.add.registryCustom" | "panels.market.add.registryCustomPlaceholder" | "panels.market.add.registryCustomHint" | "panels.market.add.registryCustomInvalid" | "panels.market.add.run" | "panels.market.add.edit" | "panels.market.add.changeRegistry" | "panels.market.add.installingTitle" | "panels.market.add.installedTitle" | "panels.market.add.failedTitle" | "panels.market.add.cancelledTitle" | "panels.market.add.failureNetworkHost" | "panels.market.add.problemInvalid" | "panels.market.add.problemInstalled" | "panels.market.add.problemNotFound" | "panels.market.add.problemNotPackage" | "panels.market.add.problemNotBundle" | "panels.market.add.problemNotWorkbenchModule" | "panels.market.add.problemNotModuleOrPlugin" | "panels.market.add.failureNotModuleOrPlugin" | "panels.market.add.installedPlugin" | "panels.market.add.pluginPreview" | "panels.market.add.pluginAlias" | "panels.market.add.problemNetwork" | "panels.market.add.problemUnknown" | "panels.market.add.failureNetwork" | "panels.market.add.failureNotFound" | "panels.market.add.failureNoMatchingVersion" | "panels.market.add.failureDiskFull" | "panels.market.add.failurePermission" | "panels.market.add.failureBuildBlocked" | "panels.market.add.failureIntegrity" | "panels.market.add.failureStopProfile" | "panels.market.add.failureCancelled" | "panels.market.add.failureTimeout" | "panels.market.add.failurePnpmMissing" | "panels.market.add.failureInstalled" | "panels.market.add.failureGeneric" | "panels.market.add.failureCredentials" | "panels.market.add.approveTitle" | "panels.market.add.approveCaution" | "panels.market.add.approveRun" | "panels.market.add.restart" | "panels.market.add.tookEffect" | "panels.market.add.details" | "panels.market.add.open" | "panels.market.add.title" | "panels.market.add.intro" | "panels.market.add.specLabel" | "panels.market.add.specHint" | "panels.market.add.exampleTitle" | "panels.market.add.exampleFill" | "panels.market.add.registryLabel" | "panels.market.add.registryProfile" | "panels.market.add.registryPnpm" | "panels.market.add.check" | "panels.market.add.checking" | "panels.market.add.classifying" | "panels.market.add.change" | "panels.market.add.previewTitle" | "panels.market.add.fieldName" | "panels.market.add.fieldVersion" | "panels.market.add.fieldDescription" | "panels.market.add.fieldSource" | "panels.market.add.install" | "panels.market.add.installing" | "panels.market.add.cancel" | "panels.market.add.close" | "panels.market.add.retry" | "panels.market.add.changeSource" | "panels.market.tabInstalled" | "panels.market.tabs" | "panels.tab.discover" | "panels.discover.loading" | "panels.discover.slowHint" | "panels.discover.lead" | "panels.discover.addSource" | "panels.discover.addingSource" | "panels.discover.addFirstSource" | "panels.discover.removeSource" | "panels.discover.removeTitle" | "panels.discover.removeBody" | "panels.discover.sourceActions" | "panels.discover.sourceStateWritable" | "panels.discover.sourceStateReadOnly" | "panels.discover.sourceEnable" | "panels.discover.sourceDisable" | "panels.discover.sourceWorking" | "panels.discover.sourceEnabled" | "panels.discover.sourceReadOnly" | "panels.discover.refresh" | "panels.discover.search" | "panels.discover.clearSearch" | "panels.discover.all" | "panels.discover.sourceLabel" | "panels.discover.sourceKind" | "panels.discover.sourceKindHttp" | "panels.discover.sourceKindGit" | "panels.discover.sourceUrl" | "panels.discover.sourcePlaceholder" | "panels.discover.sourceRef" | "panels.discover.sourcePath" | "panels.discover.sourceLocal" | "panels.discover.sourceLocalHint" | "panels.discover.save" | "panels.discover.cancel" | "panels.discover.retry" | "panels.discover.noSource" | "panels.discover.noSourceHint" | "panels.discover.sourcesFailed" | "panels.discover.unreadable" | "panels.discover.sandbox" | "panels.discover.sourceAuth" | "panels.discover.invalid" | "panels.discover.emptyRepo" | "panels.discover.missingIndex" | "panels.discover.initTitle" | "panels.discover.initCta" | "panels.discover.initWhat" | "panels.discover.initBranch" | "panels.discover.initBranchHint" | "panels.discover.initBranchBad" | "panels.discover.initOk" | "panels.discover.initBusy" | "panels.discover.initDone" | "panels.discover.stale" | "panels.discover.empty" | "panels.discover.noMatch" | "panels.discover.notInstalled" | "panels.discover.installed" | "panels.discover.installedVersion" | "panels.discover.update" | "panels.discover.badShell" | "panels.discover.badShellDetail" | "panels.discover.unverified" | "panels.discover.installing" | "panels.discover.installingNamed" | "panels.discover.cancelInstall" | "panels.discover.cancelling" | "panels.discover.installCancelled" | "panels.discover.installedDone" | "panels.discover.failed" | "panels.discover.transportTitle" | "panels.discover.transportSsh" | "panels.discover.transportHttps" | "panels.discover.transportOk" | "panels.discover.transportAuth" | "panels.discover.transportUnreachable" | "panels.discover.transportUnknown" | "panels.discover.transportChecking" | "panels.discover.transportTest" | "panels.discover.transportPlaceholder" | "panels.discover.transportNeedsAuth" | "panels.discover.transportChange" | "panels.discover.transportChangeHide" | "panels.discover.transportNone" | "panels.discover.expand" | "panels.discover.collapse" | "panels.discover.versionCount" | "panels.discover.sourceNpm" | "panels.discover.sourceNpmDefault" | "panels.discover.sourceGit" | "panels.discover.installVersion" | "panels.discover.confirmTitle" | "panels.discover.confirmDetail" | "panels.discover.confirmAck" | "panels.discover.confirmOk" | "panels.discover.confirmCancel" | "panels.discover.marketMenu" | "panels.discover.manageSources" | "panels.discover.sourcesTitle" | "panels.discover.sourcesIntro" | "panels.discover.sourcesLabel" | "panels.discover.sourceTrust" | "panels.discover.sourceDuplicate" | "panels.discover.sourceBadUrl" | "panels.discover.close" | "panels.discover.labelsMenu" | "panels.discover.labelsCount" | "panels.discover.tagsAll" | "panels.discover.sort" | "panels.discover.sortWith" | "panels.discover.sortRelevance" | "panels.discover.sortDefault" | "panels.discover.sortPublished" | "panels.discover.categoriesLabel" | "panels.discover.showMore" | "panels.discover.entryMeta" | "panels.discover.entryMetaAuthor" | "panels.discover.openEntry" | "panels.discover.cardInstall" | "panels.discover.cardInstalled" | "panels.discover.cardUpdate" | "panels.discover.cardBlocked" | "panels.discover.installTitle" | "panels.discover.installVersionTitle" | "panels.discover.openInstalled" | "panels.discover.noCompatibleVersion" | "panels.discover.detailBack" | "panels.discover.publishedAt" | "panels.discover.detailMarket" | "panels.discover.detailIncompatible" | "panels.discover.detailUnknown" | "panels.discover.detailSource" | "panels.discover.authorUnknown" | "panels.discover.tabOverview" | "panels.discover.tabReadme" | "panels.discover.tabChangelog" | "panels.discover.docReadme" | "panels.discover.docChangelog" | "panels.discover.docLoading" | "panels.discover.docMissing" | "panels.discover.docUnavailable" | "panels.discover.docUnknownReason" | "panels.discover.detailTabs" | "panels.discover.factPackage" | "panels.discover.factRegistry" | "panels.discover.factRepository" | "panels.discover.factCommit" | "panels.discover.factDirectory" | "panels.discover.factPublished" | "panels.discover.factAuthor" | "panels.discover.factHomepage" | "panels.discover.factCategory" | "panels.discover.factLabels" | "panels.discover.factMarket" | "panels.discover.detailVersions" | "panels.discover.versionsLabel" | "panels.discover.tagRecommended" | "panels.discover.tagPrerelease" | "panels.discover.tagInstalled" | "panels.discover.tagIncompatible" | "panels.discover.tagUnknown" | "panels.discover.selected" | "panels.discover.done" | "panels.discover.installTrust" | "panels.discover.progress" | "panels.market.add.approveBuilds" | "panels.market.add.approveHint" | "panels.market.add.doneApplied" | "panels.market.add.doneRestart" | "panels.market.add.restartWhy" | "panels.market.add.restartWhy.no-hmr" | "panels.market.add.restartWhy.package-moved" | "panels.market.add.restartWhy.host-module" | "panels.market.add.restartWhy.unmanaged-plugin" | "panels.market.add.restartWhy.module-comparison" | "panels.market.add.cancelled" | "panels.market.add.failed" | "panels.market.add.removed" | "panels.market.add.supplyPending" | "panels.market.add.supplyFailed" | "panels.market.add.notModule" | "panels.market.add.removedRestart" | "panels.market.add.remove" | "panels.market.add.problem.invalidSpec" | "panels.market.add.problem.alreadyInstalled" | "panels.market.add.problem.notFound" | "panels.market.add.problem.notAPackage" | "panels.market.add.problem.notABundle" | "panels.market.add.problem.network" | "panels.market.add.problem.unknown" | "panels.market.add.reason.invalidSpec" | "panels.market.add.reason.incompatible" | "panels.market.add.reason.notBundle" | "panels.market.add.reason.notRemovable" | "panels.market.add.reason.bundleInUse" | "panels.market.add.reason.stopProfile" | "panels.market.add.reason.staleApproval" | "panels.market.add.reason.operationError" | "panels.market.add.reason.buildBlocked" | "panels.market.add.reason.pnpmMissing" | "panels.market.add.reason.noMatchingVersion" | "panels.market.add.reason.diskFull" | "panels.market.add.reason.permission" | "panels.market.add.reason.integrity" | "panels.market.add.reason.timeout" | "panels.market.add.reason.network" | "panels.market.add.reason.notFound" | "panels.market.add.reason.unknown" | "blocker.fix.update" | "blocker.fix.running" | "blocker.fix.failed" | "blocker.retry.running" | "panels.reading" | "panels.cardBroken" | "panels.cardRetry" | "panels.empty" | "panels.emptyHint" | "env.title" | "env.checking" | "env.installing" | "env.installingToolchain" | "env.failed" | "env.stepFailed.install" | "env.stepFailed.path" | "env.stepFailed.shell" | "env.stepFailed.host" | "env.toolchain.ok" | "env.toolchain.warn" | "env.runtime.ok" | "env.bridge.ok" | "env.bridge.short" | "env.bridge.why" | "env.bridge.hold" | "env.bridge.unknown" | "env.fix.title" | "env.fix.why" | "env.fix.whyPath" | "env.fix.whyShell" | "env.fix.whyHost" | "env.fix.step" | "env.fix.stepRetry" | "env.fix.stepPath" | "env.fix.stepShell" | "env.fix.stepHost" | "env.fix.permission" | "env.fix.network" | "env.fix.details" | "env.retry" | "env.failed.continue" | "env.wake" | "env.wake.opening" | "env.wake.browserOpen" | "env.wake.noBrowser" | "env.wake.failed" | "env.bridge.continue" | "env.diy.ok" | "env.diy.short" | "env.diy.hold" | "env.diy.why" | "env.diy.rows" | "env.diy.noRow" | "env.diy.step" | "env.diy.continue" | "env.copyCommand" | "env.copied" | "env.step.toolchain" | "env.step.adapter" | "env.step.runtime" | "env.step.bridge" | "env.step.diy" | "env.step.warm" | "env.warm.done" | "env.warm.short" | "adapterSet.not-configured" | "adapterSet.no-profile" | "adapterSet.malformed" | "adapterSet.not-resolvable" | "adapterSet.import-failed" | "adapterSet.bad-export" | "adapterSet.factory-failed" | "adapterSet.incompatible-version" | "adapterSet.missing-member" | "env.unit.hint" | "rightbar.label" | "rightbar.expand" | "rightbar.collapse" | "rightbar.column.label" | "rightbar.column.workbench" | "rightbar.column.dsh" | "rightbar.refresh" | "rightbar.refreshing" | "rightbar.updatedAt" | "rightbar.noProject" | "rightbar.openPlatform" | "error.unknown" | "board.title" | "panel.conversation" | "panels.label" | "adapterSet.title" | "adapterSet.lead" | "adapterSet.active" | "adapterSet.defaults" | "adapterSet.failed" | "adapterSet.healthUnreadable" | "workbenchSettings.nav" | "workbenchSettings.lead" | "sidebarEdition.nav" | "sidebarEdition.lead" | "sidebarEdition.official" | "sidebarEdition.officialHint" | "sidebarEdition.custom" | "sidebarEdition.customHint" | "sidebarEdition.saving" | "sidebarEdition.reloadRequired" | "sidebarEdition.reload" | "sidebarEdition.failed" | "debug.workspace" | "debug.status" | "debug.status.trouble" | "debug.stalled" | "debug.act.pause" | "debug.act.resume" | "debug.act.stop" | "debug.act.stop.ask" | "debug.card.here.title" | "debug.card.here.note" | "debug.card.away.note" | "debug.card.paused.note" | "debug.card.hidden.note" | "record.waiting" | "record.waiting.note" | "record.recording" | "record.recording.note" | "record.recording.shots" | "record.finished" | "record.finished.note" | "record.act.cancel" | "record.act.halt" | "approval.record.site" | "approval.record.what" | "approval.record.lands" | "approval.record.noUrl" | "approval.record.oneAction" | "approval.record.noSwitch" | "approval.longTask.what" | "approval.longTask.signal" | "approval.plugin.name" | "approval.plugin.command" | "approval.plugin.note" | "approval.publish.module" | "approval.publish.target" | "approval.publish.version" | "approval.publish.author" | "approval.publish.authorMissing" | "approval.publish.labels" | "approval.publish.labelsMissing" | "approval.publish.owner" | "approval.publish.ownerUnowned" | "approval.publish.ownerTaken" | "approval.publish.unit" | "approval.publish.unitTaken" | "approval.publish.path" | "approval.publish.pathTaken" | "approval.publish.registry" | "approval.publish.repo" | "approval.publish.branch" | "approval.publish.defaultBranch" | "approval.publish.artifacts" | "approval.publish.index" | "approval.publish.commits" | "approval.publish.twoCommits" | "approval.publish.reading" | "approval.publish.changelog" | "approval.publish.changelogPending" | "approval.publish.changelogMissing" | "approval.publish.targetAuto" | "approval.publish.targetTeam" | "approval.publish.targetPublic" | "approval.publish.targetTarball" | "approval.publish.targetGit" | "approval.publish.targetMarket" | "approval.publish.targetLocal" | "approval.market.source" | "approval.market.url" | "approval.market.action" | "approval.market.policy" | "approval.market.enable" | "approval.market.disable" | "approval.market.writable" | "approval.market.readOnly" | "approval.market.reading" | "markdown.copy" | "markdown.copied" | "markdown.footnotes", string>;
831
831
  };
832
832
  /** 中文词表的键类型(从 `zh.ts` 转出):`en` 与模块词表都得覆盖同一批键。 */
833
833
  export type { WorkbenchMessages };
package/dist/i18n/zh.d.ts CHANGED
@@ -591,9 +591,8 @@ export declare const zh: {
591
591
  readonly 'env.title': "准备工作台";
592
592
  readonly 'env.checking': "正在准备运行环境…";
593
593
  readonly 'env.installing': "正在安装后台工具,第一次会慢一点…";
594
- readonly 'env.installingToolchain': "正在装工作台自己那份 npm / pnpm —— 第一次要下载,慢一点正常。";
594
+ readonly 'env.installingToolchain': "正在装工作台自己那份 pnpm —— 第一次要下载,慢一点正常。";
595
595
  readonly 'env.failed': "还差一步就能用了";
596
- readonly 'env.elapsed': "已等待 {seconds} 秒";
597
596
  readonly 'env.stepFailed.install': "装不上";
598
597
  readonly 'env.stepFailed.path': "装了但还找不到";
599
598
  readonly 'env.stepFailed.shell': "连不上命令行";
@@ -612,14 +611,15 @@ export declare const zh: {
612
611
  readonly 'env.fix.whyShell': "工作台拿不到这台机器的命令行,所以取不了数据 —— 这一步你装不了,需要有人处理后台环境。";
613
612
  readonly 'env.fix.whyHost': "工作台要靠命令行跑几条检查,再把结果收回来;这次命令发出去了,结果一直没回来。工具本身多半是好的 —— 重装 Node / npm / pnpm 不会有帮助。";
614
613
  readonly 'env.fix.step': "在终端里运行下面这条命令,装好之后点「重试」:";
614
+ readonly 'env.fix.stepRetry': "点「重试」再装一次;还装不上也可以先进入工作台 —— 装好之后重启工作台就会用上。";
615
615
  readonly 'env.fix.stepPath': "新开一个终端窗口(或确认 npm 的全局 bin 目录在 PATH 里),然后点「重试」。";
616
616
  readonly 'env.fix.stepShell': "重启一次工作台(或 dsh);如果反复出现,说明工作台还是拿不到命令行。";
617
617
  readonly 'env.fix.stepHost': "完全退出工作台(托盘图标也要退),清掉系统临时目录里 dsh- 开头的残留,再重新打开;反复出现就升级 dsh。";
618
618
  readonly 'env.fix.permission': "权限不够:在命令前加 sudo 重跑,或先把 npm 的全局目录配到你的用户目录。";
619
619
  readonly 'env.fix.network': "网络不通:检查网络或代理设置后重试。";
620
620
  readonly 'env.fix.details': "详细输出(排障用)";
621
- readonly 'env.log': "详细输出";
622
621
  readonly 'env.retry': "重试";
622
+ readonly 'env.failed.continue': "先进入工作台";
623
623
  readonly 'env.wake': "打开浏览器";
624
624
  readonly 'env.wake.opening': "正在打开浏览器…";
625
625
  readonly 'env.wake.browserOpen': "浏览器已经开着,但扩展没连上 —— 检查扩展是否启用。";
package/dist/i18n/zh.js CHANGED
@@ -583,9 +583,8 @@ export const zh = {
583
583
  'env.title': '准备工作台',
584
584
  'env.checking': '正在准备运行环境…',
585
585
  'env.installing': '正在安装后台工具,第一次会慢一点…',
586
- 'env.installingToolchain': '正在装工作台自己那份 npm / pnpm —— 第一次要下载,慢一点正常。',
586
+ 'env.installingToolchain': '正在装工作台自己那份 pnpm —— 第一次要下载,慢一点正常。',
587
587
  'env.failed': '还差一步就能用了',
588
- 'env.elapsed': '已等待 {seconds} 秒',
589
588
  'env.stepFailed.install': '装不上',
590
589
  'env.stepFailed.path': '装了但还找不到',
591
590
  'env.stepFailed.shell': '连不上命令行',
@@ -604,14 +603,15 @@ export const zh = {
604
603
  'env.fix.whyShell': '工作台拿不到这台机器的命令行,所以取不了数据 —— 这一步你装不了,需要有人处理后台环境。',
605
604
  'env.fix.whyHost': '工作台要靠命令行跑几条检查,再把结果收回来;这次命令发出去了,结果一直没回来。工具本身多半是好的 —— 重装 Node / npm / pnpm 不会有帮助。',
606
605
  'env.fix.step': '在终端里运行下面这条命令,装好之后点「重试」:',
606
+ 'env.fix.stepRetry': '点「重试」再装一次;还装不上也可以先进入工作台 —— 装好之后重启工作台就会用上。',
607
607
  'env.fix.stepPath': '新开一个终端窗口(或确认 npm 的全局 bin 目录在 PATH 里),然后点「重试」。',
608
608
  'env.fix.stepShell': '重启一次工作台(或 dsh);如果反复出现,说明工作台还是拿不到命令行。',
609
609
  'env.fix.stepHost': '完全退出工作台(托盘图标也要退),清掉系统临时目录里 dsh- 开头的残留,再重新打开;反复出现就升级 dsh。',
610
610
  'env.fix.permission': '权限不够:在命令前加 sudo 重跑,或先把 npm 的全局目录配到你的用户目录。',
611
611
  'env.fix.network': '网络不通:检查网络或代理设置后重试。',
612
612
  'env.fix.details': '详细输出(排障用)',
613
- 'env.log': '详细输出',
614
613
  'env.retry': '重试',
614
+ 'env.failed.continue': '先进入工作台',
615
615
  'env.wake': '打开浏览器',
616
616
  'env.wake.opening': '正在打开浏览器…',
617
617
  'env.wake.browserOpen': '浏览器已经开着,但扩展没连上 —— 检查扩展是否启用。',
@@ -0,0 +1,4 @@
1
+ export declare function isValidVersion(value: string): boolean;
2
+ export declare function isPrereleaseVersion(value: string): boolean;
3
+ export declare function compareVersions(left: string, right: string): number | undefined;
4
+ export declare function isNewerVersion(latest: string, installed: string): boolean;
@@ -0,0 +1,21 @@
1
+ import semver from 'semver';
2
+ export function isValidVersion(value) {
3
+ return semver.valid(value.trim()) !== null;
4
+ }
5
+ export function isPrereleaseVersion(value) {
6
+ const parsed = semver.valid(value.trim());
7
+ return parsed !== null && semver.prerelease(parsed) !== null;
8
+ }
9
+ export function compareVersions(left, right) {
10
+ const a = semver.valid(left.trim());
11
+ const b = semver.valid(right.trim());
12
+ if (a === null || b === null)
13
+ return undefined;
14
+ return semver.compare(a, b);
15
+ }
16
+ export function isNewerVersion(latest, installed) {
17
+ if (latest === installed)
18
+ return false;
19
+ const compared = compareVersions(latest, installed);
20
+ return compared === undefined ? true : compared > 0;
21
+ }
@@ -95,7 +95,6 @@ const runtimePreset = (capabilities) => ({
95
95
  runners: () => ({}),
96
96
  health: () => ({}),
97
97
  seed: () => undefined,
98
- warnUnwritableRoot: () => undefined,
99
98
  });
100
99
  const plugins = {
101
100
  declarationLookup: () => () => undefined,
@@ -0,0 +1,3 @@
1
+ import type { DshShell } from '../api/dsh.js';
2
+ import type { GitReader } from '../contract/git.js';
3
+ export declare function createFakeGit(shell: DshShell): GitReader;
@@ -0,0 +1,36 @@
1
+ import { quoteShellArg, tailLines } from '../host/shell-text.js';
2
+ import { runShell } from '../host/shell.js';
3
+ export function createFakeGit(shell) {
4
+ return {
5
+ async origin(path) {
6
+ const key = path.trim();
7
+ if (!key)
8
+ return { kind: 'unknown', reason: 'no-path' };
9
+ const result = await runShell(shell, `git -C ${quoteShellArg(key)} remote get-url origin`);
10
+ if (result.exitCode !== 0)
11
+ return { kind: 'no-origin', detail: tailLines(result.stderr, 3) };
12
+ return { kind: 'ok', remote: result.stdout.trim() };
13
+ },
14
+ async branch(path) {
15
+ const key = path.trim();
16
+ if (!key)
17
+ return { kind: 'unknown', reason: 'no-path' };
18
+ const result = await runShell(shell, `git -C ${quoteShellArg(key)} rev-parse --abbrev-ref HEAD`);
19
+ const name = result.stdout.trim();
20
+ if (result.exitCode !== 0)
21
+ return { kind: 'no-branch', detail: tailLines(result.stderr, 3) };
22
+ if (name === '' || name === 'HEAD')
23
+ return { kind: 'no-branch', detail: name };
24
+ return { kind: 'ok', branch: name };
25
+ },
26
+ async head(path) {
27
+ const key = path.trim();
28
+ if (!key)
29
+ return { kind: 'unknown', reason: 'no-path' };
30
+ const result = await runShell(shell, `git -C ${quoteShellArg(key)} rev-parse HEAD`);
31
+ if (result.exitCode !== 0)
32
+ return { kind: 'no-head', detail: tailLines(result.stderr, 3) };
33
+ return { kind: 'ok', commit: result.stdout.trim() };
34
+ },
35
+ };
36
+ }
@@ -1,4 +1,5 @@
1
1
  import type { DshShell } from '../api/dsh.js';
2
+ import type { ProcessChild, ProcessHost, ProcessSpawnOptions } from '../host/seam/exec.js';
2
3
  export interface ShellCall {
3
4
  command: string;
4
5
  workdir?: string;
@@ -6,6 +7,7 @@ export interface ShellCall {
6
7
  onExpiry?: string;
7
8
  stdoutMaxBytes?: number;
8
9
  env?: Readonly<Record<string, string>>;
10
+ sandboxPolicy?: unknown;
9
11
  }
10
12
  export interface ShellReply {
11
13
  stdout?: string;
@@ -15,6 +17,12 @@ export interface ShellReply {
15
17
  aborted?: boolean;
16
18
  truncated?: boolean;
17
19
  failWith?: Error;
20
+ sandbox?: {
21
+ mode?: string;
22
+ denied?: boolean;
23
+ enforcement?: string;
24
+ runnerFailed?: boolean;
25
+ } | undefined;
18
26
  }
19
27
  export declare function createFakeShell(replies?: ShellReply[] | ((call: ShellCall, index: number) => ShellReply)): {
20
28
  shell: DshShell;
@@ -29,3 +37,25 @@ export declare function createFakeLogger(): {
29
37
  };
30
38
  warnings: string[];
31
39
  };
40
+ export interface FakeProcessReply {
41
+ readonly stdout?: string;
42
+ readonly stderr?: string;
43
+ readonly exitCode?: number | null;
44
+ readonly signal?: string | null;
45
+ readonly error?: Error;
46
+ readonly hang?: boolean;
47
+ }
48
+ export interface FakeProcessChild extends ProcessChild {
49
+ readonly writes: readonly string[];
50
+ readonly killed: readonly string[];
51
+ readonly unrefed: boolean;
52
+ finish(code?: number | null, signal?: string | null): void;
53
+ emitStdout(chunk: string): void;
54
+ emitStderr(chunk: string): void;
55
+ fail(error: Error): void;
56
+ }
57
+ export declare function createFakeProcesses(replies?: FakeProcessReply[] | ((call: ProcessSpawnOptions, index: number) => FakeProcessReply)): {
58
+ host: ProcessHost;
59
+ calls: ProcessSpawnOptions[];
60
+ children: FakeProcessChild[];
61
+ };
@@ -27,6 +27,7 @@ export function createFakeShell(replies = []) {
27
27
  aborted: reply.aborted ?? false,
28
28
  stdout: { text: reply.stdout ?? '', truncated: reply.truncated === true },
29
29
  stderr: { text: reply.stderr ?? '', truncated: false },
30
+ ...(reply.sandbox === undefined ? {} : { sandbox: reply.sandbox }),
30
31
  };
31
32
  },
32
33
  };
@@ -51,3 +52,106 @@ export function createFakeLogger() {
51
52
  warnings,
52
53
  };
53
54
  }
55
+ export function createFakeProcesses(replies = []) {
56
+ const calls = [];
57
+ const children = [];
58
+ const host = {
59
+ spawn(options) {
60
+ const index = calls.length;
61
+ calls.push(options);
62
+ const reply = typeof replies === 'function' ? replies(options, index) : (replies[index] ?? {});
63
+ const outListeners = [];
64
+ const errListeners = [];
65
+ const exitListeners = [];
66
+ const errorListeners = [];
67
+ const writes = [];
68
+ const killed = [];
69
+ let unrefed = false;
70
+ let finished = false;
71
+ const emitStdout = (chunk) => {
72
+ for (const listener of outListeners)
73
+ listener(chunk);
74
+ };
75
+ const emitStderr = (chunk) => {
76
+ for (const listener of errListeners)
77
+ listener(chunk);
78
+ };
79
+ const finish = (code = 0, signal = null) => {
80
+ if (finished)
81
+ return;
82
+ finished = true;
83
+ for (const listener of exitListeners)
84
+ listener({ code, signal });
85
+ };
86
+ const child = {
87
+ pid: 4242 + index,
88
+ stdin: { write: (chunk) => writes.push(chunk) },
89
+ stdout: streamOf(outListeners),
90
+ stderr: streamOf(errListeners),
91
+ writes,
92
+ killed,
93
+ get unrefed() {
94
+ return unrefed;
95
+ },
96
+ finish,
97
+ emitStdout,
98
+ emitStderr,
99
+ fail(error) {
100
+ for (const listener of errorListeners)
101
+ listener(error);
102
+ },
103
+ onExit(listener) {
104
+ exitListeners.push(listener);
105
+ return () => {
106
+ const at = exitListeners.indexOf(listener);
107
+ if (at >= 0)
108
+ exitListeners.splice(at, 1);
109
+ };
110
+ },
111
+ onError(listener) {
112
+ errorListeners.push(listener);
113
+ return () => {
114
+ const at = errorListeners.indexOf(listener);
115
+ if (at >= 0)
116
+ errorListeners.splice(at, 1);
117
+ };
118
+ },
119
+ unref() {
120
+ unrefed = true;
121
+ },
122
+ kill(signal) {
123
+ killed.push(signal ?? 'SIGTERM');
124
+ queueMicrotask(() => finish(null, signal ?? 'SIGTERM'));
125
+ },
126
+ };
127
+ children.push(child);
128
+ if (reply.hang !== true) {
129
+ queueMicrotask(() => {
130
+ if (reply.error !== undefined) {
131
+ child.fail(reply.error);
132
+ return;
133
+ }
134
+ if (reply.stdout !== undefined)
135
+ emitStdout(reply.stdout);
136
+ if (reply.stderr !== undefined)
137
+ emitStderr(reply.stderr);
138
+ finish(reply.exitCode ?? 0, reply.signal ?? null);
139
+ });
140
+ }
141
+ return child;
142
+ },
143
+ };
144
+ return { host, calls, children };
145
+ }
146
+ function streamOf(listeners) {
147
+ return {
148
+ onData(listener) {
149
+ listeners.push(listener);
150
+ return () => {
151
+ const at = listeners.indexOf(listener);
152
+ if (at >= 0)
153
+ listeners.splice(at, 1);
154
+ };
155
+ },
156
+ };
157
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-workbench/shared",
3
- "version": "1.1.14-beta.2",
3
+ "version": "1.1.14",
4
4
  "description": "工作台与模块共享的纯代码与契约类型:类型、纯逻辑、哑组件、平台解析。宿主侧的东西从 /host 进(不影响浏览器产物)。",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -38,6 +38,7 @@
38
38
  "@types/node": "^24.19.0",
39
39
  "@types/react": "^19.0.0",
40
40
  "@types/semver": "^7.8.0",
41
+ "@types/write-file-atomic": "^4.0.3",
41
42
  "@vitest/coverage-v8": "^5.0.2",
42
43
  "react": "^18.0.0",
43
44
  "typescript": "5.9",
@@ -45,7 +46,9 @@
45
46
  },
46
47
  "dependencies": {
47
48
  "dayjs": "^1.11.23",
48
- "semver": "^7.8.5"
49
+ "execa": "^10.2.0",
50
+ "semver": "^7.8.5",
51
+ "write-file-atomic": "^8.0.0"
49
52
  },
50
53
  "repository": {
51
54
  "type": "git",
package/src/api/dsh.ts CHANGED
@@ -144,6 +144,7 @@ export interface DshShellExecution {
144
144
  aborted: boolean;
145
145
  stdout: { text: string; truncated: boolean };
146
146
  stderr: { text: string; truncated: boolean };
147
+ sandbox?: { mode?: string; denied?: boolean; enforcement?: string; runnerFailed?: boolean } | undefined;
147
148
  }>;
148
149
  }
149
150
 
@@ -160,6 +161,10 @@ export interface DshShell {
160
161
  stdoutMaxBytes?: number;
161
162
  signal?: AbortSignal;
162
163
  env?: Readonly<Record<string, string>>;
164
+ sandboxPolicy?: {
165
+ mode: 'read-only' | 'workspace-write' | 'danger-full-access';
166
+ workspaceRoot: string;
167
+ };
163
168
  }): unknown;
164
169
  execute(spec: unknown): Promise<DshShellExecution>;
165
170
  }
@@ -244,7 +249,9 @@ export interface DshApprovalService {
244
249
  * 方法可选:服务缺席或老版本没有它时,调用方必须当成「不知道」而不是「完全放行」。
245
250
  */
246
251
  export interface DshSandboxPolicy {
247
- resolve?(request?: { readonly session?: unknown }): { readonly mode?: string } | undefined;
252
+ resolve?(request?: { readonly session?: unknown; readonly mode?: string }):
253
+ | { readonly mode?: string; readonly workspaceRoot?: string }
254
+ | undefined;
248
255
  }
249
256
 
250
257
  /**
@@ -71,7 +71,9 @@ const TITLE_KEYS = ['zh', 'en'];
71
71
  const TOOL_KEYS = ['name', 'writes', 'key'];
72
72
 
73
73
  const TOOL_KEY_SHAPE = /^[a-z][a-zA-Z0-9]*$/;
74
- const HOST_KEYS = ['inject', 'optional'];
74
+ const HOST_KEYS = ['inject', 'optional', 'writes'];
75
+
76
+ const UNIT_WRITE_SCOPES: readonly string[] = ['unit', 'workspace'];
75
77
 
76
78
  function text(value: unknown): string {
77
79
  return typeof value === 'string' ? value.trim() : '';
@@ -263,6 +265,22 @@ export function declarationProblemsOf(subject: string, raw: unknown): readonly s
263
265
  if (host.optional !== undefined) {
264
266
  problems.push(...stringArrayProblems(`${subject}: dsh.workbench.host.optional`, host.optional));
265
267
  }
268
+ if (host.writes !== undefined) {
269
+ const shape = stringArrayProblems(`${subject}: dsh.workbench.host.writes`, host.writes);
270
+ problems.push(...shape);
271
+ if (shape.length === 0) {
272
+ const outsideScopes = (host.writes as readonly string[]).filter(
273
+ (scope) => !UNIT_WRITE_SCOPES.includes(scope),
274
+ );
275
+ if (outsideScopes.length > 0) {
276
+ problems.push(
277
+ `${subject}: dsh.workbench.host.writes 里有不认的写入域 ${listOf(outsideScopes)} —— ` +
278
+ `只认 "unit"(模块自己的数据目录)与 "workspace"(当前会话工作区)两档;` +
279
+ `模块拿不到产品域与任意路径,别写别的名字(缺省 [] = 不给执行缝门面)`,
280
+ );
281
+ }
282
+ }
283
+ }
266
284
  }
267
285
  }
268
286
 
@@ -308,6 +326,7 @@ export function readDeclaration(subject: string, raw: unknown): DeclarationRead
308
326
  host: {
309
327
  inject: [...(declaration.host.inject ?? [])],
310
328
  ...(declaration.host.optional === undefined ? {} : { optional: [...declaration.host.optional] }),
329
+ writes: [...(declaration.host.writes ?? [])],
311
330
  },
312
331
  ...(declaration.needs === undefined ? {} : { needs: declaration.needs }),
313
332
  },
@@ -45,10 +45,13 @@ export interface UnitTool {
45
45
 
46
46
  /**
47
47
  * 模块要外壳的哪些服务:inject 缺一个就挂不上,optional 缺了照挂。
48
+ * writes 声明模块要哪几档执行缝写入域:unit 是模块自己的数据目录,workspace 是当前会话工作区;
49
+ * 缺省 [] = 不给执行缝门面(deps.seam 是 undefined)。
48
50
  */
49
51
  export interface UnitHostNeeds {
50
52
  readonly inject: readonly string[];
51
53
  readonly optional?: readonly string[];
54
+ readonly writes?: readonly ('unit' | 'workspace')[];
52
55
  }
53
56
 
54
57
  /**