@dsh-workbench/shared 0.2.5 → 0.2.7

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.
@@ -3,6 +3,7 @@ import './Note.css';
3
3
  export interface NoteProps {
4
4
  readonly tone?: 'muted' | 'problem';
5
5
  readonly as?: 'p' | 'span';
6
+ readonly role?: 'alert' | 'status';
6
7
  readonly children?: ReactNode | undefined;
7
8
  }
8
- export declare function Note({ tone, as, children }: NoteProps): JSX.Element;
9
+ export declare function Note({ tone, as, role, children }: NoteProps): JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import { h } from '../lib/react.js';
2
2
  import './Note.css';
3
- export function Note({ tone = 'muted', as, children }) {
3
+ export function Note({ tone = 'muted', as, role, children }) {
4
4
  const className = tone === 'problem' ? 'wb-problem' : 'wb-note';
5
- return as === 'span' ? h("span", { className: className }, children) : h("p", { className: className }, children);
5
+ return as === 'span' ? (h("span", { className: className, role: role }, children)) : (h("p", { className: className, role: role }, children));
6
6
  }
@@ -1,26 +1,26 @@
1
1
 
2
- .wb-settings {
2
+ section.wb-settings {
3
3
  display: flex;
4
4
  flex-direction: column;
5
- gap: var(--wb-len-8);
6
- padding: var(--wb-len-10);
7
- border: 0.5px solid var(--dsw-alias-border-l2);
5
+ gap: var(--wb-len-12);
6
+ padding: 0;
7
+ border: 0;
8
8
  border-radius: var(--dsw-radius-md);
9
- background: var(--dsw-alias-bg-layer-1);
9
+ background: var(--dsw-alias-settings-card-fill);
10
10
  }
11
11
  .wb-settingsHead {
12
12
  display: flex;
13
13
  align-items: center;
14
14
  gap: var(--wb-len-8);
15
15
  }
16
- .wb-settingsTitle {
16
+ .wb-settings .wb-settingsTitle {
17
17
  flex: 1 1 auto;
18
18
  min-width: 0;
19
19
  overflow: hidden;
20
20
  text-overflow: ellipsis;
21
21
  white-space: nowrap;
22
- font-size: var(--dsw-font-xxs-12-font-size);
23
- line-height: var(--wb-line-18);
22
+ font-size: var(--dsw-font-base-16-font-size);
23
+ line-height: var(--wb-line-24);
24
24
  font-weight: 500;
25
25
  color: var(--dsw-alias-label-primary);
26
26
  }
package/dist/i18n/en.js CHANGED
@@ -13,6 +13,7 @@ export const en = {
13
13
  'project.search.placeholder': 'Search workspaces (folder / name / path)',
14
14
  'project.search.empty': 'No workspace matches “{query}”.',
15
15
  'project.group.workspaces': 'Workspaces',
16
+ 'project.group.defaultWorkspace': 'Default workspace',
16
17
  'project.group.workshop': 'Workshop',
17
18
  'project.rename.row': 'Rename “{name}”',
18
19
  'project.rename.current': 'Give this workspace a display name…',
@@ -105,6 +106,7 @@ export const en = {
105
106
  'panels.market.lead': 'Installed on this machine, shared by every project.',
106
107
  'panels.market.install': 'Install',
107
108
  'panels.market.update': 'Update',
109
+ 'panels.market.swapSlow': 'Not swapped yet — maybe a slow or failed download. Press Update again; if it stays like this, restart dsh.',
108
110
  'panels.market.uninstall': 'Uninstall',
109
111
  'panels.market.uninstallLabel': 'Uninstall {name}',
110
112
  'panels.market.installing': 'Installing…',
@@ -355,4 +357,37 @@ export const en = {
355
357
  'board.title': 'Workbench panel',
356
358
  'panel.conversation': 'Conversation',
357
359
  'panels.label': 'Global panels',
360
+ 'configSync.nav': 'Config sync',
361
+ 'configSync.lead': 'Bring over the rows another profile configures explicitly — pick any profile as the source.',
362
+ 'configSync.source': 'Source',
363
+ 'configSync.sourceBroken': 'its config is unreadable',
364
+ 'configSync.sourceRows': '{name}: {count} rows are new or different for the workbench',
365
+ 'configSync.sourceDead': 'unreadable',
366
+ 'configSync.refresh': 'Read again',
367
+ 'configSync.loading': 'Reading the source config…',
368
+ 'configSync.readHint': 'Pick another source, or read again.',
369
+ 'configSync.tag.new': 'New',
370
+ 'configSync.tag.differs': 'Differs',
371
+ 'configSync.conflictNote': 'Applying replaces this workbench copy with the source',
372
+ 'configSync.code.lang': 'yaml',
373
+ 'configSync.code.copy': 'Copy',
374
+ 'configSync.code.copied': 'Copied',
375
+ 'configSync.code.wrap': 'Wrap lines',
376
+ 'configSync.code.unwrap': 'No wrap',
377
+ 'configSync.code.collapse': 'Collapse',
378
+ 'configSync.code.collapseAria': 'Collapse this row',
379
+ 'configSync.code.expandAria': 'Expand the diff ({count} more lines)',
380
+ 'configSync.code.expand': 'Show {count} more lines',
381
+ 'configSync.missing': '{pkg} is not installed: the row will not take effect — run `dsh plugin --profile {profile} add {pkg}`, or install it from the module market',
382
+ 'configSync.apply': 'Sync {count} selected',
383
+ 'configSync.applyNone': 'Pick some rows first',
384
+ 'configSync.applying': 'Writing…',
385
+ 'configSync.applied': 'Written to the workbench config · applied',
386
+ 'configSync.appliedIds': 'Written this time: {ids}',
387
+ 'configSync.skippedIds': 'Left alone (already here): {ids}',
388
+ 'configSync.nothing': 'Nothing to sync',
389
+ 'configSync.unreadable': 'Cannot read {path}: {reason}',
390
+ 'configSync.noSource': 'This machine has no other profile to sync from',
391
+ 'configSync.emptyProviders': 'The workbench has no model provider yet — sync the llm- rows from some profile, or configure one under Models.',
392
+ 'configSync.failed': 'The sync did not go through; try again.',
358
393
  };
@@ -15,6 +15,7 @@ export declare const dictionaries: {
15
15
  readonly 'project.search.placeholder': "搜索工作区(目录名 / 中文名 / 路径)";
16
16
  readonly 'project.search.empty': "没有匹配「{query}」的工作区。";
17
17
  readonly 'project.group.workspaces': "工作区";
18
+ readonly 'project.group.defaultWorkspace': "默认工作区";
18
19
  readonly 'project.group.workshop': "工坊";
19
20
  readonly 'project.rename.row': "改「{name}」的中文名";
20
21
  readonly 'project.rename.current': "改当前工作区的中文名…";
@@ -107,6 +108,7 @@ export declare const dictionaries: {
107
108
  readonly 'panels.market.lead': "装在这台机器上,所有项目共用。";
108
109
  readonly 'panels.market.install': "安装";
109
110
  readonly 'panels.market.update': "更新";
111
+ readonly 'panels.market.swapSlow': "还没换上:可能网慢或没装上。再点一次「更新」;一直这样就把 dsh 重启一遍。";
110
112
  readonly 'panels.market.uninstall': "卸载";
111
113
  readonly 'panels.market.uninstallLabel': "卸载 {name}";
112
114
  readonly 'panels.market.installing': "正在安装…";
@@ -357,8 +359,41 @@ export declare const dictionaries: {
357
359
  readonly 'board.title': "工作台面板";
358
360
  readonly 'panel.conversation': "对话";
359
361
  readonly 'panels.label': "全局面板";
362
+ readonly 'configSync.nav': "配置同步";
363
+ readonly 'configSync.lead': "把另一个 profile 里显式配过的行搬过来 —— 来源随你选。";
364
+ readonly 'configSync.source': "来源";
365
+ readonly 'configSync.sourceBroken': "读不到它的配置";
366
+ readonly 'configSync.sourceRows': "{name} 这份里你有 {count} 行可搬";
367
+ readonly 'configSync.sourceDead': "读不到";
368
+ readonly 'configSync.refresh': "重新读一遍";
369
+ readonly 'configSync.loading': "正在读来源的配置…";
370
+ readonly 'configSync.readHint': "换个来源,或再读一遍。";
371
+ readonly 'configSync.tag.new': "新增";
372
+ readonly 'configSync.tag.differs': "差异";
373
+ readonly 'configSync.conflictNote': "应用后工作台这份会被来源覆盖";
374
+ readonly 'configSync.code.lang': "yaml";
375
+ readonly 'configSync.code.copy': "复制";
376
+ readonly 'configSync.code.copied': "已复制";
377
+ readonly 'configSync.code.wrap': "自动换行";
378
+ readonly 'configSync.code.unwrap': "不换行";
379
+ readonly 'configSync.code.collapse': "收起";
380
+ readonly 'configSync.code.collapseAria': "收起这一行的配置";
381
+ readonly 'configSync.code.expandAria': "展开差异(还有 {count} 行)";
382
+ readonly 'configSync.code.expand': "展开剩余 {count} 行";
383
+ readonly 'configSync.missing': "{pkg} 还没装:这一行搬过来也不会生效 —— 先 `dsh plugin --profile {profile} add {pkg}`,或在模块市场里装";
384
+ readonly 'configSync.apply': "同步选中的 {count} 行";
385
+ readonly 'configSync.applyNone': "先勾几行";
386
+ readonly 'configSync.applying': "正在写入…";
387
+ readonly 'configSync.applied': "已写入工作台配置 · 已生效";
388
+ readonly 'configSync.appliedIds': "这次写进去:{ids}";
389
+ readonly 'configSync.skippedIds': "这几行工作台自己已有,没动:{ids}";
390
+ readonly 'configSync.nothing': "没有需要同步的内容";
391
+ readonly 'configSync.unreadable': "读不到 {path}:{reason}";
392
+ readonly 'configSync.noSource': "这台机器上只有工作台这一个 profile,没有可同步的来源";
393
+ readonly 'configSync.emptyProviders': "工作台还没有任何模型供应商 —— 去「配置同步」从某个 profile 把 llm- 那几行搬过来,或自己去「模型」里配。";
394
+ readonly 'configSync.failed': "同步没成功,再试一次。";
360
395
  };
361
- 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.fix.update" | "blocker.market.open" | "env.unit.failed" | "env.unit.failedHint" | "env.unit.missingPlugin" | "env.unit.hint" | "env.unit.missingCommands" | "env.unit.missingCommandsHint" | "env.unit.unchecked" | "env.unit.uncheckedHint" | "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.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.waitingApproval" | "status.planReview" | "status.waitingAnswer" | "status.compact.approval" | "status.compact.planReview" | "status.compact.answer" | "status.completed" | "status.subagentsRunning.one" | "status.subagentsRunning.other" | "hover.copied" | "time.short.minutes" | "time.short.hours" | "time.short.days" | "time.short.months" | "time.short.years" | "panels.title" | "panels.groupBoardless" | "panels.groupPlugins" | "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.dep.failed" | "panels.dep.missingPlugin" | "panels.dep.missingCommands" | "panels.dep.unchecked" | "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.missing" | "panels.market.unchecked" | "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.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.failed" | "panels.market.needEnv" | "panels.market.needCommands" | "panels.market.localMark" | "panels.market.localHint" | "panels.market.noSource" | "panels.market.badSource" | "panels.market.empty" | "panels.market.sectionPlugins" | "panels.market.moduleOutdated" | "panels.market.moduleRefused" | "panels.market.moduleRefusedDetail" | "panels.market.moduleRestartHint" | "panels.market.workbenchName" | "panels.market.workbenchLocal" | "panels.market.pluginKeptInUse" | "panels.market.pluginKeptUnsure" | "panels.market.pluginKeptHeld" | "panels.market.pluginKeptUnnamed" | "panels.market.pluginBroken" | "panels.market.restartNeeded" | "panels.market.foot" | "panels.market.recheck" | "panels.market.checkUpdates" | "panels.market.checkedAt" | "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.failureTimeout" | "panels.market.add.failurePnpmMissing" | "panels.market.add.failureInstalled" | "panels.market.add.failureGeneric" | "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.add.approveBuilds" | "panels.market.add.approveHint" | "panels.market.add.doneApplied" | "panels.market.add.doneRestart" | "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.running" | "blocker.fix.failed" | "blocker.retry.running" | "panels.reading" | "panels.cardBroken" | "panels.cardRetry" | "panels.empty" | "panels.emptyHint" | "env.title" | "env.checking" | "env.installing" | "env.failed" | "env.elapsed" | "env.stepFailed.install" | "env.stepFailed.path" | "env.stepFailed.shell" | "env.bridge.ok" | "env.bridge.short" | "env.bridge.why" | "env.bridge.daemon" | "env.bridge.extension" | "env.bridge.extensionLink" | "env.bridge.profile" | "env.bridge.stale" | "env.bridge.unknown" | "env.fix.title" | "env.fix.why" | "env.fix.whyPath" | "env.fix.whyShell" | "env.fix.step" | "env.fix.stepPath" | "env.fix.stepShell" | "env.fix.permission" | "env.fix.network" | "env.fix.details" | "env.retry" | "env.copyCommand" | "env.copied" | "env.step.opencli" | "env.step.codingPlugin" | "env.step.bridge" | "env.step.warm" | "env.warm.done" | "env.warm.short" | "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" | "coding.notARepo.title" | "error.unknown" | "board.title" | "panel.conversation" | "panels.label", string>;
396
+ 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.fix.update" | "blocker.market.open" | "env.unit.failed" | "env.unit.failedHint" | "env.unit.missingPlugin" | "env.unit.hint" | "env.unit.missingCommands" | "env.unit.missingCommandsHint" | "env.unit.unchecked" | "env.unit.uncheckedHint" | "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.waitingApproval" | "status.planReview" | "status.waitingAnswer" | "status.compact.approval" | "status.compact.planReview" | "status.compact.answer" | "status.completed" | "status.subagentsRunning.one" | "status.subagentsRunning.other" | "hover.copied" | "time.short.minutes" | "time.short.hours" | "time.short.days" | "time.short.months" | "time.short.years" | "panels.title" | "panels.groupBoardless" | "panels.groupPlugins" | "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.dep.failed" | "panels.dep.missingPlugin" | "panels.dep.missingCommands" | "panels.dep.unchecked" | "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.missing" | "panels.market.unchecked" | "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.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.failed" | "panels.market.needEnv" | "panels.market.needCommands" | "panels.market.localMark" | "panels.market.localHint" | "panels.market.noSource" | "panels.market.badSource" | "panels.market.empty" | "panels.market.sectionPlugins" | "panels.market.moduleOutdated" | "panels.market.moduleRefused" | "panels.market.moduleRefusedDetail" | "panels.market.moduleRestartHint" | "panels.market.workbenchName" | "panels.market.workbenchLocal" | "panels.market.pluginKeptInUse" | "panels.market.pluginKeptUnsure" | "panels.market.pluginKeptHeld" | "panels.market.pluginKeptUnnamed" | "panels.market.pluginBroken" | "panels.market.restartNeeded" | "panels.market.foot" | "panels.market.recheck" | "panels.market.checkUpdates" | "panels.market.checkedAt" | "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.failureTimeout" | "panels.market.add.failurePnpmMissing" | "panels.market.add.failureInstalled" | "panels.market.add.failureGeneric" | "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.add.approveBuilds" | "panels.market.add.approveHint" | "panels.market.add.doneApplied" | "panels.market.add.doneRestart" | "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.running" | "blocker.fix.failed" | "blocker.retry.running" | "panels.reading" | "panels.cardBroken" | "panels.cardRetry" | "panels.empty" | "panels.emptyHint" | "env.title" | "env.checking" | "env.installing" | "env.failed" | "env.elapsed" | "env.stepFailed.install" | "env.stepFailed.path" | "env.stepFailed.shell" | "env.bridge.ok" | "env.bridge.short" | "env.bridge.why" | "env.bridge.daemon" | "env.bridge.extension" | "env.bridge.extensionLink" | "env.bridge.profile" | "env.bridge.stale" | "env.bridge.unknown" | "env.fix.title" | "env.fix.why" | "env.fix.whyPath" | "env.fix.whyShell" | "env.fix.step" | "env.fix.stepPath" | "env.fix.stepShell" | "env.fix.permission" | "env.fix.network" | "env.fix.details" | "env.retry" | "env.copyCommand" | "env.copied" | "env.step.opencli" | "env.step.codingPlugin" | "env.step.bridge" | "env.step.warm" | "env.warm.done" | "env.warm.short" | "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" | "coding.notARepo.title" | "error.unknown" | "board.title" | "panel.conversation" | "panels.label" | "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.appliedIds" | "configSync.skippedIds" | "configSync.nothing" | "configSync.unreadable" | "configSync.noSource" | "configSync.emptyProviders" | "configSync.failed", string>;
362
397
  };
363
398
  export type { WorkbenchMessages };
364
399
  export interface Dictionaries {
package/dist/i18n/zh.d.ts CHANGED
@@ -13,6 +13,7 @@ export declare const zh: {
13
13
  readonly 'project.search.placeholder': "搜索工作区(目录名 / 中文名 / 路径)";
14
14
  readonly 'project.search.empty': "没有匹配「{query}」的工作区。";
15
15
  readonly 'project.group.workspaces': "工作区";
16
+ readonly 'project.group.defaultWorkspace': "默认工作区";
16
17
  readonly 'project.group.workshop': "工坊";
17
18
  readonly 'project.rename.row': "改「{name}」的中文名";
18
19
  readonly 'project.rename.current': "改当前工作区的中文名…";
@@ -105,6 +106,7 @@ export declare const zh: {
105
106
  readonly 'panels.market.lead': "装在这台机器上,所有项目共用。";
106
107
  readonly 'panels.market.install': "安装";
107
108
  readonly 'panels.market.update': "更新";
109
+ readonly 'panels.market.swapSlow': "还没换上:可能网慢或没装上。再点一次「更新」;一直这样就把 dsh 重启一遍。";
108
110
  readonly 'panels.market.uninstall': "卸载";
109
111
  readonly 'panels.market.uninstallLabel': "卸载 {name}";
110
112
  readonly 'panels.market.installing': "正在安装…";
@@ -355,5 +357,38 @@ export declare const zh: {
355
357
  readonly 'board.title': "工作台面板";
356
358
  readonly 'panel.conversation': "对话";
357
359
  readonly 'panels.label': "全局面板";
360
+ readonly 'configSync.nav': "配置同步";
361
+ readonly 'configSync.lead': "把另一个 profile 里显式配过的行搬过来 —— 来源随你选。";
362
+ readonly 'configSync.source': "来源";
363
+ readonly 'configSync.sourceBroken': "读不到它的配置";
364
+ readonly 'configSync.sourceRows': "{name} 这份里你有 {count} 行可搬";
365
+ readonly 'configSync.sourceDead': "读不到";
366
+ readonly 'configSync.refresh': "重新读一遍";
367
+ readonly 'configSync.loading': "正在读来源的配置…";
368
+ readonly 'configSync.readHint': "换个来源,或再读一遍。";
369
+ readonly 'configSync.tag.new': "新增";
370
+ readonly 'configSync.tag.differs': "差异";
371
+ readonly 'configSync.conflictNote': "应用后工作台这份会被来源覆盖";
372
+ readonly 'configSync.code.lang': "yaml";
373
+ readonly 'configSync.code.copy': "复制";
374
+ readonly 'configSync.code.copied': "已复制";
375
+ readonly 'configSync.code.wrap': "自动换行";
376
+ readonly 'configSync.code.unwrap': "不换行";
377
+ readonly 'configSync.code.collapse': "收起";
378
+ readonly 'configSync.code.collapseAria': "收起这一行的配置";
379
+ readonly 'configSync.code.expandAria': "展开差异(还有 {count} 行)";
380
+ readonly 'configSync.code.expand': "展开剩余 {count} 行";
381
+ readonly 'configSync.missing': "{pkg} 还没装:这一行搬过来也不会生效 —— 先 `dsh plugin --profile {profile} add {pkg}`,或在模块市场里装";
382
+ readonly 'configSync.apply': "同步选中的 {count} 行";
383
+ readonly 'configSync.applyNone': "先勾几行";
384
+ readonly 'configSync.applying': "正在写入…";
385
+ readonly 'configSync.applied': "已写入工作台配置 · 已生效";
386
+ readonly 'configSync.appliedIds': "这次写进去:{ids}";
387
+ readonly 'configSync.skippedIds': "这几行工作台自己已有,没动:{ids}";
388
+ readonly 'configSync.nothing': "没有需要同步的内容";
389
+ readonly 'configSync.unreadable': "读不到 {path}:{reason}";
390
+ readonly 'configSync.noSource': "这台机器上只有工作台这一个 profile,没有可同步的来源";
391
+ readonly 'configSync.emptyProviders': "工作台还没有任何模型供应商 —— 去「配置同步」从某个 profile 把 llm- 那几行搬过来,或自己去「模型」里配。";
392
+ readonly 'configSync.failed': "同步没成功,再试一次。";
358
393
  };
359
394
  export type WorkbenchMessages = typeof zh;
package/dist/i18n/zh.js CHANGED
@@ -13,6 +13,7 @@ export const zh = {
13
13
  'project.search.placeholder': '搜索工作区(目录名 / 中文名 / 路径)',
14
14
  'project.search.empty': '没有匹配「{query}」的工作区。',
15
15
  'project.group.workspaces': '工作区',
16
+ 'project.group.defaultWorkspace': '默认工作区',
16
17
  'project.group.workshop': '工坊',
17
18
  'project.rename.row': '改「{name}」的中文名',
18
19
  'project.rename.current': '改当前工作区的中文名…',
@@ -105,6 +106,7 @@ export const zh = {
105
106
  'panels.market.lead': '装在这台机器上,所有项目共用。',
106
107
  'panels.market.install': '安装',
107
108
  'panels.market.update': '更新',
109
+ 'panels.market.swapSlow': '还没换上:可能网慢或没装上。再点一次「更新」;一直这样就把 dsh 重启一遍。',
108
110
  'panels.market.uninstall': '卸载',
109
111
  'panels.market.uninstallLabel': '卸载 {name}',
110
112
  'panels.market.installing': '正在安装…',
@@ -355,4 +357,37 @@ export const zh = {
355
357
  'board.title': '工作台面板',
356
358
  'panel.conversation': '对话',
357
359
  'panels.label': '全局面板',
360
+ 'configSync.nav': '配置同步',
361
+ 'configSync.lead': '把另一个 profile 里显式配过的行搬过来 —— 来源随你选。',
362
+ 'configSync.source': '来源',
363
+ 'configSync.sourceBroken': '读不到它的配置',
364
+ 'configSync.sourceRows': '{name} 这份里你有 {count} 行可搬',
365
+ 'configSync.sourceDead': '读不到',
366
+ 'configSync.refresh': '重新读一遍',
367
+ 'configSync.loading': '正在读来源的配置…',
368
+ 'configSync.readHint': '换个来源,或再读一遍。',
369
+ 'configSync.tag.new': '新增',
370
+ 'configSync.tag.differs': '差异',
371
+ 'configSync.conflictNote': '应用后工作台这份会被来源覆盖',
372
+ 'configSync.code.lang': 'yaml',
373
+ 'configSync.code.copy': '复制',
374
+ 'configSync.code.copied': '已复制',
375
+ 'configSync.code.wrap': '自动换行',
376
+ 'configSync.code.unwrap': '不换行',
377
+ 'configSync.code.collapse': '收起',
378
+ 'configSync.code.collapseAria': '收起这一行的配置',
379
+ 'configSync.code.expandAria': '展开差异(还有 {count} 行)',
380
+ 'configSync.code.expand': '展开剩余 {count} 行',
381
+ 'configSync.missing': '{pkg} 还没装:这一行搬过来也不会生效 —— 先 `dsh plugin --profile {profile} add {pkg}`,或在模块市场里装',
382
+ 'configSync.apply': '同步选中的 {count} 行',
383
+ 'configSync.applyNone': '先勾几行',
384
+ 'configSync.applying': '正在写入…',
385
+ 'configSync.applied': '已写入工作台配置 · 已生效',
386
+ 'configSync.appliedIds': '这次写进去:{ids}',
387
+ 'configSync.skippedIds': '这几行工作台自己已有,没动:{ids}',
388
+ 'configSync.nothing': '没有需要同步的内容',
389
+ 'configSync.unreadable': '读不到 {path}:{reason}',
390
+ 'configSync.noSource': '这台机器上只有工作台这一个 profile,没有可同步的来源',
391
+ 'configSync.emptyProviders': '工作台还没有任何模型供应商 —— 去「配置同步」从某个 profile 把 llm- 那几行搬过来,或自己去「模型」里配。',
392
+ 'configSync.failed': '同步没成功,再试一次。',
358
393
  };
@@ -0,0 +1 @@
1
+ export declare function useLintProbe(): number;
@@ -0,0 +1,6 @@
1
+ import { useRef } from './react';
2
+ export function useLintProbe() {
3
+ const probeRef = useRef(0);
4
+ probeRef.current = 1;
5
+ return probeRef.current;
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-workbench/shared",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "工作台与模块共享的纯代码与契约类型:类型、纯逻辑、哑组件、平台解析。宿主侧的东西从 /host 进(不影响浏览器产物)。",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -5,10 +5,19 @@ import './Note.css';
5
5
  export interface NoteProps {
6
6
  readonly tone?: 'muted' | 'problem';
7
7
  readonly as?: 'p' | 'span';
8
+ readonly role?: 'alert' | 'status';
8
9
  readonly children?: ReactNode | undefined;
9
10
  }
10
11
 
11
- export function Note({ tone = 'muted', as, children }: NoteProps) {
12
+ export function Note({ tone = 'muted', as, role, children }: NoteProps) {
12
13
  const className = tone === 'problem' ? 'wb-problem' : 'wb-note';
13
- return as === 'span' ? <span className={className}>{children}</span> : <p className={className}>{children}</p>;
14
+ return as === 'span' ? (
15
+ <span className={className} role={role}>
16
+ {children}
17
+ </span>
18
+ ) : (
19
+ <p className={className} role={role}>
20
+ {children}
21
+ </p>
22
+ );
14
23
  }
@@ -1,26 +1,26 @@
1
1
 
2
- .wb-settings {
2
+ section.wb-settings {
3
3
  display: flex;
4
4
  flex-direction: column;
5
- gap: var(--wb-len-8);
6
- padding: var(--wb-len-10);
7
- border: 0.5px solid var(--dsw-alias-border-l2);
5
+ gap: var(--wb-len-12);
6
+ padding: 0;
7
+ border: 0;
8
8
  border-radius: var(--dsw-radius-md);
9
- background: var(--dsw-alias-bg-layer-1);
9
+ background: var(--dsw-alias-settings-card-fill);
10
10
  }
11
11
  .wb-settingsHead {
12
12
  display: flex;
13
13
  align-items: center;
14
14
  gap: var(--wb-len-8);
15
15
  }
16
- .wb-settingsTitle {
16
+ .wb-settings .wb-settingsTitle {
17
17
  flex: 1 1 auto;
18
18
  min-width: 0;
19
19
  overflow: hidden;
20
20
  text-overflow: ellipsis;
21
21
  white-space: nowrap;
22
- font-size: var(--dsw-font-xxs-12-font-size);
23
- line-height: var(--wb-line-18);
22
+ font-size: var(--dsw-font-base-16-font-size);
23
+ line-height: var(--wb-line-24);
24
24
  font-weight: 500;
25
25
  color: var(--dsw-alias-label-primary);
26
26
  }
package/src/i18n/en.ts CHANGED
@@ -16,6 +16,7 @@ export const en: Record<keyof WorkbenchMessages, string> = {
16
16
  'project.search.placeholder': 'Search workspaces (folder / name / path)',
17
17
  'project.search.empty': 'No workspace matches “{query}”.',
18
18
  'project.group.workspaces': 'Workspaces',
19
+ 'project.group.defaultWorkspace': 'Default workspace',
19
20
  'project.group.workshop': 'Workshop',
20
21
  'project.rename.row': 'Rename “{name}”',
21
22
  'project.rename.current': 'Give this workspace a display name…',
@@ -110,6 +111,7 @@ export const en: Record<keyof WorkbenchMessages, string> = {
110
111
  'panels.market.lead': 'Installed on this machine, shared by every project.',
111
112
  'panels.market.install': 'Install',
112
113
  'panels.market.update': 'Update',
114
+ 'panels.market.swapSlow': 'Not swapped yet — maybe a slow or failed download. Press Update again; if it stays like this, restart dsh.',
113
115
  'panels.market.uninstall': 'Uninstall',
114
116
  'panels.market.uninstallLabel': 'Uninstall {name}',
115
117
  'panels.market.installing': 'Installing…',
@@ -367,4 +369,38 @@ export const en: Record<keyof WorkbenchMessages, string> = {
367
369
 
368
370
  'panel.conversation': 'Conversation',
369
371
  'panels.label': 'Global panels',
372
+
373
+ 'configSync.nav': 'Config sync',
374
+ 'configSync.lead': 'Bring over the rows another profile configures explicitly — pick any profile as the source.',
375
+ 'configSync.source': 'Source',
376
+ 'configSync.sourceBroken': 'its config is unreadable',
377
+ 'configSync.sourceRows': '{name}: {count} rows are new or different for the workbench',
378
+ 'configSync.sourceDead': 'unreadable',
379
+ 'configSync.refresh': 'Read again',
380
+ 'configSync.loading': 'Reading the source config…',
381
+ 'configSync.readHint': 'Pick another source, or read again.',
382
+ 'configSync.tag.new': 'New',
383
+ 'configSync.tag.differs': 'Differs',
384
+ 'configSync.conflictNote': 'Applying replaces this workbench copy with the source',
385
+ 'configSync.code.lang': 'yaml',
386
+ 'configSync.code.copy': 'Copy',
387
+ 'configSync.code.copied': 'Copied',
388
+ 'configSync.code.wrap': 'Wrap lines',
389
+ 'configSync.code.unwrap': 'No wrap',
390
+ 'configSync.code.collapse': 'Collapse',
391
+ 'configSync.code.collapseAria': 'Collapse this row',
392
+ 'configSync.code.expandAria': 'Expand the diff ({count} more lines)',
393
+ 'configSync.code.expand': 'Show {count} more lines',
394
+ 'configSync.missing': '{pkg} is not installed: the row will not take effect — run `dsh plugin --profile {profile} add {pkg}`, or install it from the module market',
395
+ 'configSync.apply': 'Sync {count} selected',
396
+ 'configSync.applyNone': 'Pick some rows first',
397
+ 'configSync.applying': 'Writing…',
398
+ 'configSync.applied': 'Written to the workbench config · applied',
399
+ 'configSync.appliedIds': 'Written this time: {ids}',
400
+ 'configSync.skippedIds': 'Left alone (already here): {ids}',
401
+ 'configSync.nothing': 'Nothing to sync',
402
+ 'configSync.unreadable': 'Cannot read {path}: {reason}',
403
+ 'configSync.noSource': 'This machine has no other profile to sync from',
404
+ 'configSync.emptyProviders': 'The workbench has no model provider yet — sync the llm- rows from some profile, or configure one under Models.',
405
+ 'configSync.failed': 'The sync did not go through; try again.',
370
406
  };
package/src/i18n/zh.ts CHANGED
@@ -14,6 +14,7 @@ export const zh = {
14
14
  'project.search.placeholder': '搜索工作区(目录名 / 中文名 / 路径)',
15
15
  'project.search.empty': '没有匹配「{query}」的工作区。',
16
16
  'project.group.workspaces': '工作区',
17
+ 'project.group.defaultWorkspace': '默认工作区',
17
18
  'project.group.workshop': '工坊',
18
19
  'project.rename.row': '改「{name}」的中文名',
19
20
  'project.rename.current': '改当前工作区的中文名…',
@@ -108,6 +109,7 @@ export const zh = {
108
109
  'panels.market.lead': '装在这台机器上,所有项目共用。',
109
110
  'panels.market.install': '安装',
110
111
  'panels.market.update': '更新',
112
+ 'panels.market.swapSlow': '还没换上:可能网慢或没装上。再点一次「更新」;一直这样就把 dsh 重启一遍。',
111
113
  'panels.market.uninstall': '卸载',
112
114
  'panels.market.uninstallLabel': '卸载 {name}',
113
115
  'panels.market.installing': '正在安装…',
@@ -363,6 +365,40 @@ export const zh = {
363
365
 
364
366
  'panel.conversation': '对话',
365
367
  'panels.label': '全局面板',
368
+
369
+ 'configSync.nav': '配置同步',
370
+ 'configSync.lead': '把另一个 profile 里显式配过的行搬过来 —— 来源随你选。',
371
+ 'configSync.source': '来源',
372
+ 'configSync.sourceBroken': '读不到它的配置',
373
+ 'configSync.sourceRows': '{name} 这份里你有 {count} 行可搬',
374
+ 'configSync.sourceDead': '读不到',
375
+ 'configSync.refresh': '重新读一遍',
376
+ 'configSync.loading': '正在读来源的配置…',
377
+ 'configSync.readHint': '换个来源,或再读一遍。',
378
+ 'configSync.tag.new': '新增',
379
+ 'configSync.tag.differs': '差异',
380
+ 'configSync.conflictNote': '应用后工作台这份会被来源覆盖',
381
+ 'configSync.code.lang': 'yaml',
382
+ 'configSync.code.copy': '复制',
383
+ 'configSync.code.copied': '已复制',
384
+ 'configSync.code.wrap': '自动换行',
385
+ 'configSync.code.unwrap': '不换行',
386
+ 'configSync.code.collapse': '收起',
387
+ 'configSync.code.collapseAria': '收起这一行的配置',
388
+ 'configSync.code.expandAria': '展开差异(还有 {count} 行)',
389
+ 'configSync.code.expand': '展开剩余 {count} 行',
390
+ 'configSync.missing': '{pkg} 还没装:这一行搬过来也不会生效 —— 先 `dsh plugin --profile {profile} add {pkg}`,或在模块市场里装',
391
+ 'configSync.apply': '同步选中的 {count} 行',
392
+ 'configSync.applyNone': '先勾几行',
393
+ 'configSync.applying': '正在写入…',
394
+ 'configSync.applied': '已写入工作台配置 · 已生效',
395
+ 'configSync.appliedIds': '这次写进去:{ids}',
396
+ 'configSync.skippedIds': '这几行工作台自己已有,没动:{ids}',
397
+ 'configSync.nothing': '没有需要同步的内容',
398
+ 'configSync.unreadable': '读不到 {path}:{reason}',
399
+ 'configSync.noSource': '这台机器上只有工作台这一个 profile,没有可同步的来源',
400
+ 'configSync.emptyProviders': '工作台还没有任何模型供应商 —— 去「配置同步」从某个 profile 把 llm- 那几行搬过来,或自己去「模型」里配。',
401
+ 'configSync.failed': '同步没成功,再试一次。',
366
402
  } as const;
367
403
 
368
404
  export type WorkbenchMessages = typeof zh;