@dsh-workbench/shared 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/i18n/en.js CHANGED
@@ -29,20 +29,32 @@ export const en = {
29
29
  'session.new.label': 'Start a session in the current project',
30
30
  'session.empty': 'No sessions in this project yet.',
31
31
  'session.noProject': 'Add a project first.',
32
+ 'session.list.label': 'Sessions',
33
+ 'session.copy': 'Copy',
32
34
  'session.pinned': 'Pinned',
33
35
  'session.actions': 'Actions for {name}',
34
36
  'status.idle': 'Idle',
35
37
  'status.running': 'Running',
36
38
  'status.waitingApproval': 'Waiting for approval',
37
- 'status.planReview': 'Waiting for plan review',
39
+ 'status.planReview': 'Plan awaiting review',
38
40
  'status.waitingAnswer': 'Waiting for your answer',
41
+ 'status.compact.approval': 'Approval',
42
+ 'status.compact.planReview': 'Plan review',
43
+ 'status.compact.answer': 'Answer',
39
44
  'status.completed': 'Completed',
40
45
  'status.subagentsRunning.one': '{n} subagent running',
41
46
  'status.subagentsRunning.other': '{n} subagents running',
47
+ 'hover.copied': 'Copied',
42
48
  'time.now': 'just now',
43
49
  'time.minutes': '{n} min ago',
44
50
  'time.hours': '{n} h ago',
45
51
  'time.days': '{n} d ago',
52
+ 'time.ago': '{t} ago',
53
+ 'time.short.minutes': '{n}min',
54
+ 'time.short.hours': '{n}h',
55
+ 'time.short.days': '{n}d',
56
+ 'time.short.months': '{n}mo',
57
+ 'time.short.years': '{n}y',
46
58
  'panels.title': 'Panel modules',
47
59
  'panels.groupBoardless': 'No-board modules',
48
60
  'panels.groupPlugins': 'opencli plugins',
@@ -31,20 +31,32 @@ export declare const dictionaries: {
31
31
  readonly 'session.new.label': "在当前项目新建会话";
32
32
  readonly 'session.empty': "这个项目还没有会话。";
33
33
  readonly 'session.noProject': "先添加一个项目。";
34
+ readonly 'session.list.label': "会话";
35
+ readonly 'session.copy': "复制";
34
36
  readonly 'session.pinned': "已置顶";
35
37
  readonly 'session.actions': "{name} 的操作";
36
38
  readonly 'status.idle': "空闲";
37
- readonly 'status.running': "运行中";
38
- readonly 'status.waitingApproval': "等待授权";
39
- readonly 'status.planReview': "等待计划确认";
39
+ readonly 'status.running': "进行中";
40
+ readonly 'status.waitingApproval': "等待审批";
41
+ readonly 'status.planReview': "计划待审";
40
42
  readonly 'status.waitingAnswer': "等待回答";
43
+ readonly 'status.compact.approval': "待审批";
44
+ readonly 'status.compact.planReview': "计划待审";
45
+ readonly 'status.compact.answer': "待回答";
41
46
  readonly 'status.completed': "已完成";
42
47
  readonly 'status.subagentsRunning.one': "{n} 个子代理运行中";
43
48
  readonly 'status.subagentsRunning.other': "{n} 个子代理运行中";
49
+ readonly 'hover.copied': "已复制";
44
50
  readonly 'time.now': "刚刚";
45
51
  readonly 'time.minutes': "{n} 分钟前";
46
52
  readonly 'time.hours': "{n} 小时前";
47
53
  readonly 'time.days': "{n} 天前";
54
+ readonly 'time.ago': "{t}前";
55
+ readonly 'time.short.minutes': "{n}分钟";
56
+ readonly 'time.short.hours': "{n}小时";
57
+ readonly 'time.short.days': "{n}天";
58
+ readonly 'time.short.months': "{n}个月";
59
+ readonly 'time.short.years': "{n}年";
48
60
  readonly 'panels.title': "面板模块";
49
61
  readonly 'panels.groupBoardless': "无看板模块";
50
62
  readonly 'panels.groupPlugins': "opencli 插件";
@@ -346,7 +358,7 @@ export declare const dictionaries: {
346
358
  readonly 'panel.conversation': "对话";
347
359
  readonly 'panels.label': "全局面板";
348
360
  };
349
- en: Record<"time.now" | "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.pinned" | "session.actions" | "status.idle" | "status.running" | "status.waitingApproval" | "status.planReview" | "status.waitingAnswer" | "status.completed" | "status.subagentsRunning.one" | "status.subagentsRunning.other" | "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>;
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>;
350
362
  };
351
363
  export type { WorkbenchMessages };
352
364
  export interface Dictionaries {
package/dist/i18n/zh.d.ts CHANGED
@@ -29,20 +29,32 @@ export declare const zh: {
29
29
  readonly 'session.new.label': "在当前项目新建会话";
30
30
  readonly 'session.empty': "这个项目还没有会话。";
31
31
  readonly 'session.noProject': "先添加一个项目。";
32
+ readonly 'session.list.label': "会话";
33
+ readonly 'session.copy': "复制";
32
34
  readonly 'session.pinned': "已置顶";
33
35
  readonly 'session.actions': "{name} 的操作";
34
36
  readonly 'status.idle': "空闲";
35
- readonly 'status.running': "运行中";
36
- readonly 'status.waitingApproval': "等待授权";
37
- readonly 'status.planReview': "等待计划确认";
37
+ readonly 'status.running': "进行中";
38
+ readonly 'status.waitingApproval': "等待审批";
39
+ readonly 'status.planReview': "计划待审";
38
40
  readonly 'status.waitingAnswer': "等待回答";
41
+ readonly 'status.compact.approval': "待审批";
42
+ readonly 'status.compact.planReview': "计划待审";
43
+ readonly 'status.compact.answer': "待回答";
39
44
  readonly 'status.completed': "已完成";
40
45
  readonly 'status.subagentsRunning.one': "{n} 个子代理运行中";
41
46
  readonly 'status.subagentsRunning.other': "{n} 个子代理运行中";
47
+ readonly 'hover.copied': "已复制";
42
48
  readonly 'time.now': "刚刚";
43
49
  readonly 'time.minutes': "{n} 分钟前";
44
50
  readonly 'time.hours': "{n} 小时前";
45
51
  readonly 'time.days': "{n} 天前";
52
+ readonly 'time.ago': "{t}前";
53
+ readonly 'time.short.minutes': "{n}分钟";
54
+ readonly 'time.short.hours': "{n}小时";
55
+ readonly 'time.short.days': "{n}天";
56
+ readonly 'time.short.months': "{n}个月";
57
+ readonly 'time.short.years': "{n}年";
46
58
  readonly 'panels.title': "面板模块";
47
59
  readonly 'panels.groupBoardless': "无看板模块";
48
60
  readonly 'panels.groupPlugins': "opencli 插件";
package/dist/i18n/zh.js CHANGED
@@ -29,20 +29,32 @@ export const zh = {
29
29
  'session.new.label': '在当前项目新建会话',
30
30
  'session.empty': '这个项目还没有会话。',
31
31
  'session.noProject': '先添加一个项目。',
32
+ 'session.list.label': '会话',
33
+ 'session.copy': '复制',
32
34
  'session.pinned': '已置顶',
33
35
  'session.actions': '{name} 的操作',
34
36
  'status.idle': '空闲',
35
- 'status.running': '运行中',
36
- 'status.waitingApproval': '等待授权',
37
- 'status.planReview': '等待计划确认',
37
+ 'status.running': '进行中',
38
+ 'status.waitingApproval': '等待审批',
39
+ 'status.planReview': '计划待审',
38
40
  'status.waitingAnswer': '等待回答',
41
+ 'status.compact.approval': '待审批',
42
+ 'status.compact.planReview': '计划待审',
43
+ 'status.compact.answer': '待回答',
39
44
  'status.completed': '已完成',
40
45
  'status.subagentsRunning.one': '{n} 个子代理运行中',
41
46
  'status.subagentsRunning.other': '{n} 个子代理运行中',
47
+ 'hover.copied': '已复制',
42
48
  'time.now': '刚刚',
43
49
  'time.minutes': '{n} 分钟前',
44
50
  'time.hours': '{n} 小时前',
45
51
  'time.days': '{n} 天前',
52
+ 'time.ago': '{t}前',
53
+ 'time.short.minutes': '{n}分钟',
54
+ 'time.short.hours': '{n}小时',
55
+ 'time.short.days': '{n}天',
56
+ 'time.short.months': '{n}个月',
57
+ 'time.short.years': '{n}年',
46
58
  'panels.title': '面板模块',
47
59
  'panels.groupBoardless': '无看板模块',
48
60
  'panels.groupPlugins': 'opencli 插件',
package/dist/lib/ui.d.ts CHANGED
@@ -1,5 +1,13 @@
1
1
  export declare function cx(...parts: Array<string | false | null | undefined>): string;
2
2
  export type TimeTranslate = (key: string, params?: Record<string, unknown>) => string;
3
+ export type RelativeTimeUnit = 'now' | 'minutes' | 'hours' | 'days' | 'months' | 'years';
4
+ export interface RelativeTimeBucket {
5
+ readonly unit: RelativeTimeUnit;
6
+ readonly n: number;
7
+ }
8
+ export declare function relativeTimeBucket(epochMs: number, now?: number): RelativeTimeBucket | null;
9
+ export declare function relativeTimeCompact(epochMs: number, t: TimeTranslate, now?: number): string;
10
+ export declare function relativeTimeAgo(epochMs: number, t: TimeTranslate, now?: number): string;
3
11
  export declare function relativeTime(epochMs: number, t: TimeTranslate): string;
4
12
  export declare function shortenPath(path: unknown): string;
5
13
  export declare function parseLocalTimestamp(text: string | null | undefined): number;
package/dist/lib/ui.js CHANGED
@@ -2,6 +2,40 @@ export function cx(...parts) {
2
2
  return parts.filter(Boolean).join(' ');
3
3
  }
4
4
  const MINUTE = 60 * 1000;
5
+ const HOUR = 60 * MINUTE;
6
+ const DAY = 24 * HOUR;
7
+ const MONTH = 30 * DAY;
8
+ const YEAR = 365 * DAY;
9
+ export function relativeTimeBucket(epochMs, now = Date.now()) {
10
+ if (!Number.isFinite(epochMs) || !Number.isFinite(now))
11
+ return null;
12
+ const diff = Math.max(0, now - epochMs);
13
+ if (diff < MINUTE)
14
+ return { unit: 'now', n: 0 };
15
+ if (diff < HOUR)
16
+ return { unit: 'minutes', n: Math.floor(diff / MINUTE) };
17
+ if (diff < DAY)
18
+ return { unit: 'hours', n: Math.floor(diff / HOUR) };
19
+ if (diff < MONTH)
20
+ return { unit: 'days', n: Math.floor(diff / DAY) };
21
+ if (diff < YEAR)
22
+ return { unit: 'months', n: Math.floor(diff / MONTH) };
23
+ return { unit: 'years', n: Math.floor(diff / YEAR) };
24
+ }
25
+ function bucketLabel(bucket, t) {
26
+ return bucket.unit === 'now' ? t('time.now') : t(`time.short.${bucket.unit}`, { n: bucket.n });
27
+ }
28
+ export function relativeTimeCompact(epochMs, t, now) {
29
+ const bucket = relativeTimeBucket(epochMs, now);
30
+ return bucket === null ? '' : bucketLabel(bucket, t);
31
+ }
32
+ export function relativeTimeAgo(epochMs, t, now) {
33
+ const bucket = relativeTimeBucket(epochMs, now);
34
+ if (bucket === null)
35
+ return '';
36
+ const label = bucketLabel(bucket, t);
37
+ return bucket.unit === 'now' ? label : t('time.ago', { t: label });
38
+ }
5
39
  export function relativeTime(epochMs, t) {
6
40
  if (!Number.isFinite(epochMs))
7
41
  return '';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-workbench/shared",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "工作台与模块共享的纯代码与契约类型:类型、纯逻辑、哑组件、平台解析。宿主侧的东西从 /host 进(不影响浏览器产物)。",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/i18n/en.ts CHANGED
@@ -32,21 +32,33 @@ export const en: Record<keyof WorkbenchMessages, string> = {
32
32
  'session.new.label': 'Start a session in the current project',
33
33
  'session.empty': 'No sessions in this project yet.',
34
34
  'session.noProject': 'Add a project first.',
35
+ 'session.list.label': 'Sessions',
36
+ 'session.copy': 'Copy',
35
37
  'session.pinned': 'Pinned',
36
38
  'session.actions': 'Actions for {name}',
37
39
  'status.idle': 'Idle',
38
40
  'status.running': 'Running',
39
41
  'status.waitingApproval': 'Waiting for approval',
40
- 'status.planReview': 'Waiting for plan review',
42
+ 'status.planReview': 'Plan awaiting review',
41
43
  'status.waitingAnswer': 'Waiting for your answer',
44
+ 'status.compact.approval': 'Approval',
45
+ 'status.compact.planReview': 'Plan review',
46
+ 'status.compact.answer': 'Answer',
42
47
  'status.completed': 'Completed',
43
48
  'status.subagentsRunning.one': '{n} subagent running',
44
49
  'status.subagentsRunning.other': '{n} subagents running',
45
50
 
51
+ 'hover.copied': 'Copied',
46
52
  'time.now': 'just now',
47
53
  'time.minutes': '{n} min ago',
48
54
  'time.hours': '{n} h ago',
49
55
  'time.days': '{n} d ago',
56
+ 'time.ago': '{t} ago',
57
+ 'time.short.minutes': '{n}min',
58
+ 'time.short.hours': '{n}h',
59
+ 'time.short.days': '{n}d',
60
+ 'time.short.months': '{n}mo',
61
+ 'time.short.years': '{n}y',
50
62
 
51
63
  'panels.title': 'Panel modules',
52
64
  'panels.groupBoardless': 'No-board modules',
package/src/i18n/zh.ts CHANGED
@@ -30,21 +30,33 @@ export const zh = {
30
30
  'session.new.label': '在当前项目新建会话',
31
31
  'session.empty': '这个项目还没有会话。',
32
32
  'session.noProject': '先添加一个项目。',
33
+ 'session.list.label': '会话',
34
+ 'session.copy': '复制',
33
35
  'session.pinned': '已置顶',
34
36
  'session.actions': '{name} 的操作',
35
37
  'status.idle': '空闲',
36
- 'status.running': '运行中',
37
- 'status.waitingApproval': '等待授权',
38
- 'status.planReview': '等待计划确认',
38
+ 'status.running': '进行中',
39
+ 'status.waitingApproval': '等待审批',
40
+ 'status.planReview': '计划待审',
39
41
  'status.waitingAnswer': '等待回答',
42
+ 'status.compact.approval': '待审批',
43
+ 'status.compact.planReview': '计划待审',
44
+ 'status.compact.answer': '待回答',
40
45
  'status.completed': '已完成',
41
46
  'status.subagentsRunning.one': '{n} 个子代理运行中',
42
47
  'status.subagentsRunning.other': '{n} 个子代理运行中',
43
48
 
49
+ 'hover.copied': '已复制',
44
50
  'time.now': '刚刚',
45
51
  'time.minutes': '{n} 分钟前',
46
52
  'time.hours': '{n} 小时前',
47
53
  'time.days': '{n} 天前',
54
+ 'time.ago': '{t}前',
55
+ 'time.short.minutes': '{n}分钟',
56
+ 'time.short.hours': '{n}小时',
57
+ 'time.short.days': '{n}天',
58
+ 'time.short.months': '{n}个月',
59
+ 'time.short.years': '{n}年',
48
60
 
49
61
  'panels.title': '面板模块',
50
62
  'panels.groupBoardless': '无看板模块',
@@ -3,12 +3,17 @@ import {
3
3
  cx,
4
4
  parseLocalTimestamp,
5
5
  relativeTime,
6
+ relativeTimeAgo,
7
+ relativeTimeBucket,
8
+ relativeTimeCompact,
6
9
  shortenPath,
7
10
  type TimeTranslate,
8
11
  } from './ui.js';
9
12
 
10
- const t: TimeTranslate = (key, params) =>
11
- params === undefined ? key : `${key}:${String(params.n ?? '')}`;
13
+ const t: TimeTranslate = (key, params) => {
14
+ if (params === undefined) return key;
15
+ return `${key}:${String(params.n ?? params.t ?? '')}`;
16
+ };
12
17
 
13
18
  const NOW = Date.parse('2026-09-27T12:00:00.000Z');
14
19
 
@@ -59,6 +64,48 @@ describe('relativeTime', () => {
59
64
  });
60
65
  });
61
66
 
67
+ describe('relativeTimeBucket / relativeTimeCompact / relativeTimeAgo(会话行那一列)', () => {
68
+ const at = (ago: number): number => NOW - ago;
69
+ const MIN = 60_000;
70
+ const HOUR = 3_600_000;
71
+ const DAY = 86_400_000;
72
+
73
+ it('★ 档位与 dsh 的 relative-time 逐条一致:now / minutes / hours / days / months / years', () => {
74
+ expect(relativeTimeBucket(at(30_000), NOW)).toEqual({ unit: 'now', n: 0 });
75
+ expect(relativeTimeBucket(at(3 * MIN), NOW)).toEqual({ unit: 'minutes', n: 3 });
76
+ expect(relativeTimeBucket(at(5 * HOUR), NOW)).toEqual({ unit: 'hours', n: 5 });
77
+ expect(relativeTimeBucket(at(3 * DAY), NOW)).toEqual({ unit: 'days', n: 3 });
78
+ expect(relativeTimeBucket(at(40 * DAY), NOW)).toEqual({ unit: 'months', n: 1 });
79
+ expect(relativeTimeBucket(at(400 * DAY), NOW)).toEqual({ unit: 'years', n: 1 });
80
+ });
81
+
82
+ it('★ 边界在 30 天与 365 天那一侧(dsh 的分档,不是我们的 7 天)', () => {
83
+ expect(relativeTimeBucket(at(29 * DAY), NOW)?.unit).toBe('days');
84
+ expect(relativeTimeBucket(at(30 * DAY), NOW)?.unit).toBe('months');
85
+ expect(relativeTimeBucket(at(364 * DAY), NOW)?.unit).toBe('months');
86
+ expect(relativeTimeBucket(at(365 * DAY), NOW)?.unit).toBe('years');
87
+ });
88
+
89
+ it('未来时间钳到 now(不当成负档)', () => {
90
+ expect(relativeTimeBucket(NOW + MIN, NOW)).toEqual({ unit: 'now', n: 0 });
91
+ });
92
+
93
+ it('非法时间戳:桶给 null、两句都给空串', () => {
94
+ expect(relativeTimeBucket(Number.NaN, NOW)).toBeNull();
95
+ expect(relativeTimeBucket(NOW, Number.NaN)).toBeNull();
96
+ expect(relativeTimeCompact(Number.NaN, t, NOW)).toBe('');
97
+ expect(relativeTimeAgo(Number.NaN, t, NOW)).toBe('');
98
+ });
99
+
100
+ it('★ 行里是紧凑写法,悬停卡才补「前」;now 那一档两处都不加', () => {
101
+ expect(relativeTimeCompact(at(3 * MIN), t, NOW)).toBe('time.short.minutes:3');
102
+ expect(relativeTimeCompact(at(40 * DAY), t, NOW)).toBe('time.short.months:1');
103
+ expect(relativeTimeAgo(at(3 * MIN), t, NOW)).toBe('time.ago:time.short.minutes:3');
104
+ expect(relativeTimeCompact(at(30_000), t, NOW)).toBe('time.now');
105
+ expect(relativeTimeAgo(at(30_000), t, NOW)).toBe('time.now');
106
+ });
107
+ });
108
+
62
109
  describe('shortenPath', () => {
63
110
  it('把用户主目录缩成 ~', () => {
64
111
  expect(shortenPath('/Users/you/dev/app')).toBe('~/dev/app');
package/src/lib/ui.ts CHANGED
@@ -3,9 +3,47 @@ export function cx(...parts: Array<string | false | null | undefined>): string {
3
3
  }
4
4
 
5
5
  const MINUTE = 60 * 1000;
6
+ const HOUR = 60 * MINUTE;
7
+ const DAY = 24 * HOUR;
8
+ const MONTH = 30 * DAY;
9
+ const YEAR = 365 * DAY;
6
10
 
7
11
  export type TimeTranslate = (key: string, params?: Record<string, unknown>) => string;
8
12
 
13
+ export type RelativeTimeUnit = 'now' | 'minutes' | 'hours' | 'days' | 'months' | 'years';
14
+
15
+ export interface RelativeTimeBucket {
16
+ readonly unit: RelativeTimeUnit;
17
+ readonly n: number;
18
+ }
19
+
20
+ export function relativeTimeBucket(epochMs: number, now: number = Date.now()): RelativeTimeBucket | null {
21
+ if (!Number.isFinite(epochMs) || !Number.isFinite(now)) return null;
22
+ const diff = Math.max(0, now - epochMs);
23
+ if (diff < MINUTE) return { unit: 'now', n: 0 };
24
+ if (diff < HOUR) return { unit: 'minutes', n: Math.floor(diff / MINUTE) };
25
+ if (diff < DAY) return { unit: 'hours', n: Math.floor(diff / HOUR) };
26
+ if (diff < MONTH) return { unit: 'days', n: Math.floor(diff / DAY) };
27
+ if (diff < YEAR) return { unit: 'months', n: Math.floor(diff / MONTH) };
28
+ return { unit: 'years', n: Math.floor(diff / YEAR) };
29
+ }
30
+
31
+ function bucketLabel(bucket: RelativeTimeBucket, t: TimeTranslate): string {
32
+ return bucket.unit === 'now' ? t('time.now') : t(`time.short.${bucket.unit}`, { n: bucket.n });
33
+ }
34
+
35
+ export function relativeTimeCompact(epochMs: number, t: TimeTranslate, now?: number): string {
36
+ const bucket = relativeTimeBucket(epochMs, now);
37
+ return bucket === null ? '' : bucketLabel(bucket, t);
38
+ }
39
+
40
+ export function relativeTimeAgo(epochMs: number, t: TimeTranslate, now?: number): string {
41
+ const bucket = relativeTimeBucket(epochMs, now);
42
+ if (bucket === null) return '';
43
+ const label = bucketLabel(bucket, t);
44
+ return bucket.unit === 'now' ? label : t('time.ago', { t: label });
45
+ }
46
+
9
47
  export function relativeTime(epochMs: number, t: TimeTranslate): string {
10
48
  if (!Number.isFinite(epochMs)) return '';
11
49
  const diff = Date.now() - epochMs;