dsh-remote-plugin 0.6.23 → 0.6.25
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/apk/dsh-remote.apk +0 -0
- package/gateway-stats.cjs +106 -84
- package/gateway.cjs +78 -7
- package/package.json +1 -1
- package/public/app.js +169 -250
- package/public/desktop/desktop.css +7 -0
- package/public/desktop/desktop.html +27 -4
- package/public/desktop/desktop.js +145 -21
- package/public/genui.css +2 -0
- package/public/genui.js +144 -0
- package/public/index.html +13 -28
- package/public/md.js +16 -3
- package/public/styles.css +4 -11
- package/public/update.json +12 -12
- package/public/version.json +1 -1
package/public/index.html
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
<link rel="manifest" href="manifest.webmanifest">
|
|
13
13
|
<link rel="icon" href="icon.svg" type="image/svg+xml">
|
|
14
14
|
<link rel="stylesheet" href="styles.css">
|
|
15
|
+
<link rel="stylesheet" href="genui.css">
|
|
15
16
|
</head>
|
|
16
17
|
<body>
|
|
17
18
|
<header class="topbar">
|
|
@@ -410,26 +411,6 @@
|
|
|
410
411
|
<div class="setting-name" data-i18n="settings.groupTests">功能测试</div>
|
|
411
412
|
</div>
|
|
412
413
|
</div>
|
|
413
|
-
<div class="settings-group feature-test-shell">
|
|
414
|
-
<div class="feature-test-head">
|
|
415
|
-
<div>
|
|
416
|
-
<div class="setting-name" data-i18n="settings.asrTestTitle">ASR 模型测试(小米手机)</div>
|
|
417
|
-
<div class="setting-desc expanded" data-i18n="settings.asrTestDesc">使用 Android 系统 SpeechRecognizer 验证小米/系统云端语音识别,不上传测试日志。</div>
|
|
418
|
-
</div>
|
|
419
|
-
</div>
|
|
420
|
-
<div class="feature-test-note" data-i18n="settings.asrTestInstruction">请保持页面在前台,朗读一段中文,包含停顿、数字和英文 API 名称。测试约 60 秒,会自动记录 partial、最终结果、重建 session 和错误。</div>
|
|
421
|
-
<div class="feature-test-actions">
|
|
422
|
-
<button id="btn-asr-test-start" class="mini-btn primary" type="button" data-i18n="settings.asrTestStart">开始测试</button>
|
|
423
|
-
<button id="btn-asr-test-stop" class="mini-btn" type="button" data-i18n="settings.asrTestStop" disabled>停止测试</button>
|
|
424
|
-
<button id="btn-asr-test-copy" class="mini-btn" type="button" data-i18n="settings.asrTestCopy" disabled>复制日志</button>
|
|
425
|
-
<button id="btn-asr-test-clear" class="mini-btn" type="button" data-i18n="settings.asrTestClear">清空日志</button>
|
|
426
|
-
<button id="btn-asr-test-permission" class="mini-btn hidden" type="button" data-i18n="settings.asrTestPermissionSettings">权限设置</button>
|
|
427
|
-
<button id="btn-asr-test-engine" class="mini-btn hidden" type="button" data-i18n="settings.asrTestEngineSettings">语音引擎设置</button>
|
|
428
|
-
</div>
|
|
429
|
-
<div id="asr-test-status" class="feature-test-status muted" role="status" data-i18n="settings.asrTestNativeOnly">仅 Android App 可用</div>
|
|
430
|
-
<div id="asr-test-summary" class="feature-test-summary"></div>
|
|
431
|
-
<pre id="asr-test-log" class="feature-test-log" data-i18n="settings.asrTestLogEmpty">暂无测试日志</pre>
|
|
432
|
-
</div>
|
|
433
414
|
</div>
|
|
434
415
|
|
|
435
416
|
<div id="settings-page-servers" class="settings-subpage hidden" data-motion-panel>
|
|
@@ -553,6 +534,11 @@
|
|
|
553
534
|
<div class="setting-row">
|
|
554
535
|
<div><div class="setting-name" data-i18n="settings.updateTitle">检查更新</div><div class="setting-desc" id="update-desc" data-i18n="settings.updateLoading">加载中…</div>
|
|
555
536
|
<button id="btn-download-update" class="mini-btn hidden" style="margin-top:6px" data-i18n="settings.downloadUpdate">下载并安装更新</button>
|
|
537
|
+
<div id="update-download-progress" class="update-download-progress hidden">
|
|
538
|
+
<div id="update-download-status" role="status" aria-live="polite"></div>
|
|
539
|
+
<progress id="update-download-bar" max="100" aria-label="APK download progress"></progress>
|
|
540
|
+
<div id="update-download-detail"></div>
|
|
541
|
+
</div>
|
|
556
542
|
<button id="btn-update-expand" class="mini-btn hidden" style="margin-top:6px" data-i18n="update.expand">展开</button></div>
|
|
557
543
|
<button id="btn-check-update" class="mini-btn" data-i18n="settings.check">检查</button>
|
|
558
544
|
</div>
|
|
@@ -982,7 +968,7 @@
|
|
|
982
968
|
'groups.drawerOpen': '切换服务器组', 'groups.drawerClose': '关闭组列表', 'groups.drawerEyebrow': '快速切换', 'groups.drawerTitle': '切换服务器组', 'groups.drawerCurrent': '当前连接组',
|
|
983
969
|
'groups.drawerManage': '管理服务器与组', 'groups.drawerManageDesc': '编辑、测速和调整组', 'groups.serverCount': '{count} 台服务器',
|
|
984
970
|
'stream.error': '事件流错误:{msg}',
|
|
985
|
-
'session.loading': '加载中…', 'session.unknown': '未知会话', 'session.running': '运行中', 'session.interrupted': '已中断',
|
|
971
|
+
'session.loading': '加载中…', 'session.unknown': '未知会话', 'session.untitled': '新会话', 'session.running': '运行中', 'session.interrupted': '已中断',
|
|
986
972
|
'session.stop': '停止本轮', 'session.history': '对话', 'session.errorMsg': '会话出错:{msg}', 'session.recovering': '恢复会话中…', 'session.recoveryReady': '会话已恢复', 'session.recoveryFailed': '会话恢复失败', 'session.recoveryCached': '正在查看缓存历史',
|
|
987
973
|
'session.confirmStop': '停止当前回合?排队中的消息不会被删除。', 'session.stopFailed': '停止失败', 'session.stopRequested': '已请求停止本轮', 'session.archive': '归档', 'session.archiveConfirm': '归档这个会话?归档后可在“显示已归档会话”中打开。', 'session.archiveFailed': '归档失败:{msg}', 'session.archived': '会话已归档', 'session.archiveTitle': '确认归档会话', 'session.archiveDesc': '归档后会话将从普通列表隐藏,但不会删除对话记录。', 'session.archiveConversation': '对话', 'session.archiveWorkspace': '工作区', 'session.archiveCancel': '取消', 'session.archiveConfirmAction': '确认归档', 'session.rename': '重命名会话', 'session.renameTitle': '重命名会话', 'session.renamePlaceholder': '输入新的会话名称', 'session.renameCancel': '取消', 'session.renameConfirm': '保存', 'session.renameEmpty': '会话名称不能为空', 'session.renameFailed': '重命名失败', 'session.renamed': '会话名称已更新',
|
|
988
974
|
'notify.approvalTitle': '工具审批', 'notify.approvalBody': '{tool} 需要批准', 'notify.questionTitle': 'DSH 提问', 'notify.questionBody': '需要你回答',
|
|
@@ -1034,7 +1020,7 @@
|
|
|
1034
1020
|
'fs.notFound': '目录不存在', 'fs.forbidden': '路径不在允许范围内;DSH 已登记工作区会自动放行,其他目录请配置 DSH_REMOTE_FS_ROOT',
|
|
1035
1021
|
'fs.loadFailed': '加载失败:{msg}', 'fs.loadFailedToast': '文件列表加载失败:{msg}',
|
|
1036
1022
|
'fs.emptyDir': '空目录', 'fs.dir': '目录',
|
|
1037
|
-
'fs.downloadStarted': '开始下载到「下载/dsh-remote」目录', 'fs.downloadFailed': '
|
|
1023
|
+
'fs.downloadStarted': '开始下载到「下载/dsh-remote」目录', 'fs.downloadFailed': '下载失败:{msg}',
|
|
1038
1024
|
'fs.downloadUnsupported': '当前 App 版本不支持系统下载,请先更新 App',
|
|
1039
1025
|
'fs.uploadCancelled': '已取消上传', 'fs.pausedErr': '已暂停', 'fs.cancelledErr': '已取消',
|
|
1040
1026
|
'fs.noTokenToast': '请先到「设置」页设置令牌', 'fs.tooLarge': '单文件超过 2GB 上限', 'fs.uploadBusy': '已有上传任务,先暂停或取消',
|
|
@@ -1050,6 +1036,7 @@
|
|
|
1050
1036
|
'update.found': '发现新版本 v{version}{notes}', 'update.foundTitle': '发现新版本', 'update.foundBody': 'v{version} 可更新',
|
|
1051
1037
|
'update.latestV': '已是最新 v{version}', 'update.latestRemote': '最新版本 v{version}', 'update.latestToast': '已是最新版本',
|
|
1052
1038
|
'update.checkFailedDesc': '检查失败:{msg}', 'update.checkFailed': '检查更新失败:{msg}',
|
|
1039
|
+
'update.phase.downloading': '正在下载…', 'update.phase.verifying': '正在校验安装包…', 'update.phase.complete': '下载完成', 'update.phase.legacy': '系统正在下载安装包;安装新版后可显示完整进度', 'update.busy': '已有更新下载正在进行',
|
|
1053
1040
|
'update.downloadStarted': '开始下载,完成后会弹出安装页', 'update.downloadFailed': '无法启动下载:{msg}',
|
|
1054
1041
|
'update.corrupted': '下载文件损坏,请重试', 'update.serverFileMissing': '服务器上还没有对应版本的文件,请稍后再试',
|
|
1055
1042
|
'update.installUnsupported': '当前版本不支持 App 内安装,已转浏览器下载',
|
|
@@ -1085,9 +1072,7 @@
|
|
|
1085
1072
|
'settings.modelNoModels': '暂无自定义模型,当前使用提供方默认目录', 'settings.modelCandidates': '发现的模型', 'settings.modelSelectAll': '全选', 'settings.modelSelectNone': '取消全选', 'settings.modelAddSelected': '加入选中模型',
|
|
1086
1073
|
'settings.modelAdded': '已加入模型目录', 'settings.modelSaved': '模型配置已保存', 'settings.modelSaveFailed': '保存模型配置失败:{msg}', 'settings.modelOpenConfigFailed': '打开配置文件失败:{msg}', 'settings.modelOpenedConfig': '已请求打开 DSH 配置文件',
|
|
1087
1074
|
'settings.modelLive': '保存后立即生效', 'settings.modelRestart': '保存后需重启 DSH 才生效',
|
|
1088
|
-
'settings.asrTestTitle': 'ASR 模型测试(小米手机)', 'settings.asrTestDesc': '使用 Android 系统 SpeechRecognizer 验证小米/系统云端语音识别,不上传测试日志。', 'settings.asrTestInstruction': '请保持页面在前台,朗读一段中文,包含停顿、数字和英文 API 名称。测试约 60 秒,会自动记录 partial、最终结果、重建 session 和错误。', 'settings.asrTestStart': '开始测试', 'settings.asrTestStop': '停止测试', 'settings.asrTestCopy': '复制日志', 'settings.asrTestClear': '清空日志', 'settings.asrTestPermissionSettings': '权限设置', 'settings.asrTestNativeOnly': '仅 Android App 可用', 'settings.asrTestWebUnsupported': '浏览器不支持原生 ASR 诊断,请在 Android App 中打开。', 'settings.asrTestConsent': '测试会使用麦克风,并可能将音频发送给 Android 系统默认语音识别服务。是否继续?', 'settings.asrTestStarted': 'ASR 测试已开始,请朗读测试内容', 'settings.asrTestStopped': 'ASR 测试已停止', 'settings.asrTestRestarting': '识别 session 重建中…', 'settings.asrTestPermission': '正在请求麦克风权限…', 'settings.asrTestPermissionDenied': '未授予麦克风权限,无法测试 ASR', 'settings.asrTestPermissionError': '系统语音识别服务未获麦克风授权,请打开权限设置后重试', 'settings.asrTestUnavailable': '当前设备没有可用的系统语音识别服务', 'settings.asrTestBusy': '已有 ASR 测试正在运行', 'settings.asrTestCopyOk': '测试日志已复制', 'settings.asrTestCopyFailed': '复制测试日志失败', 'settings.asrTestLogEmpty': '暂无测试日志', 'settings.asrTestMeta': '设备信息', 'settings.asrTestSummary': '测试摘要', 'settings.asrTestEvent': '事件日志', 'settings.asrTestCloud': '系统默认识别服务可能使用云端 ASR;本测试不上传日志', 'settings.asrTestStatus': '状态:{status}',
|
|
1089
1075
|
'settings.servers': '服务器地址(可多个)', 'settings.speedTest': '测速', 'settings.add': '添加',
|
|
1090
|
-
'settings.asrTestEngineSettings': '语音引擎设置',
|
|
1091
1076
|
'settings.scanTitle': '扫码连接', 'settings.scanDesc': '实时相机识别二维码,也可拍照/相册本地解码;无需谷歌服务', 'settings.scan': '扫码',
|
|
1092
1077
|
'settings.notifyTitle': '通知', 'settings.notifyDesc': '收到审批/提问时推送', 'settings.announcementHistoryTitle': '历史公告', 'settings.announcementHistoryDesc': '查看以前收到的公告', 'settings.announcementHistory': '查看记录',
|
|
1093
1078
|
'settings.testNotifyTitle': '测试通知', 'settings.testNotifyDesc': '立即排一条 3 秒后的本地通知,用于排查系统通知限制', 'settings.testNotify': '发送测试通知',
|
|
@@ -1215,7 +1200,7 @@
|
|
|
1215
1200
|
'groups.drawerOpen': 'Switch server group', 'groups.drawerClose': 'Close group list', 'groups.drawerEyebrow': 'QUICK SWITCH', 'groups.drawerTitle': 'Switch server group', 'groups.drawerCurrent': 'Current connection group',
|
|
1216
1201
|
'groups.drawerManage': 'Manage servers and groups', 'groups.drawerManageDesc': 'Edit, test, and organize groups', 'groups.serverCount': '{count} servers',
|
|
1217
1202
|
'stream.error': 'Event stream error: {msg}',
|
|
1218
|
-
'session.loading': 'Loading…', 'session.unknown': 'Unknown session', 'session.running': 'Running', 'session.interrupted': 'Interrupted',
|
|
1203
|
+
'session.loading': 'Loading…', 'session.unknown': 'Unknown session', 'session.untitled': 'New session', 'session.running': 'Running', 'session.interrupted': 'Interrupted',
|
|
1219
1204
|
'session.stop': 'Stop turn', 'session.history': 'Conversation', 'session.errorMsg': 'Session error: {msg}', 'session.recovering': 'Restoring session…', 'session.recoveryReady': 'Session ready', 'session.recoveryFailed': 'Session restore failed', 'session.recoveryCached': 'Viewing cached history',
|
|
1220
1205
|
'session.confirmStop': 'Stop the current turn? Queued messages will be kept.', 'session.stopFailed': 'Stop failed', 'session.stopRequested': 'Stop requested', 'session.archive': 'Archive', 'session.archiveConfirm': 'Archive this session? You can open it from “Show archived”.', 'session.archiveFailed': 'Archive failed: {msg}', 'session.archived': 'Session archived', 'session.archiveTitle': 'Confirm archive', 'session.archiveDesc': 'The session will be hidden from the normal list, but its conversation will not be deleted.', 'session.archiveConversation': 'Conversation', 'session.archiveWorkspace': 'Workspace', 'session.archiveCancel': 'Cancel', 'session.archiveConfirmAction': 'Archive session', 'session.rename': 'Rename session', 'session.renameTitle': 'Rename session', 'session.renamePlaceholder': 'Enter a new session name', 'session.renameCancel': 'Cancel', 'session.renameConfirm': 'Save', 'session.renameEmpty': 'Session name cannot be empty', 'session.renameFailed': 'Rename failed', 'session.renamed': 'Session name updated',
|
|
1221
1206
|
'notify.approvalTitle': 'Tool approval', 'notify.approvalBody': '{tool} needs approval', 'notify.questionTitle': 'DSH question', 'notify.questionBody': 'Needs your answer',
|
|
@@ -1267,7 +1252,7 @@
|
|
|
1267
1252
|
'fs.notFound': 'Directory not found', 'fs.forbidden': 'Path is outside the allowed roots. Registered DSH workspaces are allowed automatically; configure DSH_REMOTE_FS_ROOT for other directories.',
|
|
1268
1253
|
'fs.loadFailed': 'Load failed: {msg}', 'fs.loadFailedToast': 'Failed to load file list: {msg}',
|
|
1269
1254
|
'fs.emptyDir': 'Empty directory', 'fs.dir': 'Directory',
|
|
1270
|
-
'fs.downloadStarted': 'Downloading to "Download/dsh-remote"', 'fs.downloadFailed': '
|
|
1255
|
+
'fs.downloadStarted': 'Downloading to "Download/dsh-remote"', 'fs.downloadFailed': 'Download failed: {msg}',
|
|
1271
1256
|
'fs.downloadUnsupported': 'This app version cannot download to the system folder, please update',
|
|
1272
1257
|
'fs.uploadCancelled': 'Upload cancelled', 'fs.pausedErr': 'Paused', 'fs.cancelledErr': 'Cancelled',
|
|
1273
1258
|
'fs.noTokenToast': 'Set a token in Settings first', 'fs.tooLarge': 'File exceeds the 2GB limit', 'fs.uploadBusy': 'Another upload is active, pause or cancel it first',
|
|
@@ -1283,6 +1268,7 @@
|
|
|
1283
1268
|
'update.found': 'New version v{version}{notes}', 'update.foundTitle': 'Update available', 'update.foundBody': 'v{version} is available',
|
|
1284
1269
|
'update.latestV': 'Up to date v{version}', 'update.latestRemote': 'Latest version v{version}', 'update.latestToast': 'Already up to date',
|
|
1285
1270
|
'update.checkFailedDesc': 'Check failed: {msg}', 'update.checkFailed': 'Update check failed: {msg}',
|
|
1271
|
+
'update.phase.downloading': 'Downloading…', 'update.phase.verifying': 'Verifying APK…', 'update.phase.complete': 'Download complete', 'update.phase.legacy': 'System download started; install this update for full progress', 'update.busy': 'An update is already downloading',
|
|
1286
1272
|
'update.downloadStarted': 'Downloading, the install page will open when ready', 'update.downloadFailed': 'Could not start download: {msg}',
|
|
1287
1273
|
'update.corrupted': 'Downloaded file is corrupted, please retry', 'update.serverFileMissing': 'The file for this version is not on the server yet, please try again later',
|
|
1288
1274
|
'update.installUnsupported': 'This version cannot install in-app, opening browser download',
|
|
@@ -1318,9 +1304,7 @@
|
|
|
1318
1304
|
'settings.modelNoModels': 'No custom models; using the provider default catalog', 'settings.modelCandidates': 'Discovered models', 'settings.modelSelectAll': 'Select all', 'settings.modelSelectNone': 'Clear selection', 'settings.modelAddSelected': 'Add selected models',
|
|
1319
1305
|
'settings.modelAdded': 'Models added to the catalog', 'settings.modelSaved': 'Model configuration saved', 'settings.modelSaveFailed': 'Could not save model configuration: {msg}', 'settings.modelOpenConfigFailed': 'Could not open config file: {msg}', 'settings.modelOpenedConfig': 'Requested DSH config file',
|
|
1320
1306
|
'settings.modelLive': 'Takes effect immediately', 'settings.modelRestart': 'Restart DSH to apply',
|
|
1321
|
-
'settings.asrTestTitle': 'ASR model test (Xiaomi)', 'settings.asrTestDesc': 'Use Android SpeechRecognizer to test Xiaomi/system cloud speech recognition. Test logs are not uploaded.', 'settings.asrTestInstruction': 'Keep this page in the foreground and read Chinese text containing pauses, numbers, and an English API name. The test runs for about 60 seconds and records partial/final results, session rebuilds, and errors.', 'settings.asrTestStart': 'Start test', 'settings.asrTestStop': 'Stop test', 'settings.asrTestRestarting': 'Rebuilding recognition session…', 'settings.asrTestCopy': 'Copy log', 'settings.asrTestClear': 'Clear log', 'settings.asrTestPermissionSettings': 'Permission settings', 'settings.asrTestNativeOnly': 'Available only in the Android app', 'settings.asrTestWebUnsupported': 'Native ASR diagnostics are unavailable in a browser. Open this page in the Android app.', 'settings.asrTestConsent': 'This test uses the microphone and may send audio to the Android system default speech recognition service. Continue?', 'settings.asrTestStarted': 'ASR test started; read the test content aloud', 'settings.asrTestStopped': 'ASR test stopped', 'settings.asrTestPermission': 'Requesting microphone permission…', 'settings.asrTestPermissionDenied': 'Microphone permission was not granted; ASR cannot be tested', 'settings.asrTestPermissionError': 'The system speech service lacks microphone authorization. Open permission settings and try again.', 'settings.asrTestUnavailable': 'No system speech recognition service is available on this device', 'settings.asrTestBusy': 'An ASR test is already running', 'settings.asrTestCopyOk': 'Test log copied', 'settings.asrTestCopyFailed': 'Could not copy the test log', 'settings.asrTestLogEmpty': 'No test log yet', 'settings.asrTestMeta': 'Device information', 'settings.asrTestSummary': 'Test summary', 'settings.asrTestEvent': 'Event log', 'settings.asrTestCloud': 'The system default recognition service may use cloud ASR; this test does not upload logs', 'settings.asrTestStatus': 'Status: {status}',
|
|
1322
1307
|
'settings.servers': 'Servers (one or more)', 'settings.speedTest': 'Test', 'settings.add': 'Add',
|
|
1323
|
-
'settings.asrTestEngineSettings': 'Speech engine settings',
|
|
1324
1308
|
'settings.scanTitle': 'Scan to pair', 'settings.scanDesc': 'Use the live camera or photo/gallery QR decoding; no Google services required', 'settings.scan': 'Scan',
|
|
1325
1309
|
'settings.notifyTitle': 'Notifications', 'settings.notifyDesc': 'Push on approvals / questions', 'settings.announcementHistoryTitle': 'Announcement history', 'settings.announcementHistoryDesc': 'Review announcements you received before', 'settings.announcementHistory': 'View history',
|
|
1326
1310
|
'settings.testNotifyTitle': 'Test notification', 'settings.testNotifyDesc': 'Schedule a local notification in 3 seconds to verify the notification pipeline', 'settings.testNotify': 'Send test notification',
|
|
@@ -1390,6 +1374,7 @@
|
|
|
1390
1374
|
<script src="jsqr.min.js"></script>
|
|
1391
1375
|
<script src="i18n.js"></script>
|
|
1392
1376
|
<script src="theme.js"></script>
|
|
1377
|
+
<script src="genui.js"></script>
|
|
1393
1378
|
<script src="md.js"></script>
|
|
1394
1379
|
<script src="vendor/gsap/gsap.min.js"></script>
|
|
1395
1380
|
<script src="motion.js"></script>
|
package/public/md.js
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* 同时支持浏览器全局 window.mdToHtml 与 Node CommonJS module.exports。
|
|
7
7
|
*/
|
|
8
8
|
(function (root, factory) {
|
|
9
|
-
if (typeof module === 'object' && module.exports) module.exports = factory()
|
|
10
|
-
else root.mdToHtml = factory()
|
|
11
|
-
})(typeof self !== 'undefined' ? self : this, function () {
|
|
9
|
+
if (typeof module === 'object' && module.exports) module.exports = factory(require('./genui.js'))
|
|
10
|
+
else root.mdToHtml = factory(root.DshGenUi)
|
|
11
|
+
})(typeof self !== 'undefined' ? self : this, function (genui) {
|
|
12
12
|
'use strict'
|
|
13
13
|
|
|
14
14
|
function escapeHtml(s) {
|
|
@@ -172,6 +172,19 @@
|
|
|
172
172
|
var code = parts[i]
|
|
173
173
|
code = code.replace(/^\n/, '')
|
|
174
174
|
if (code.slice(-1) === '\n') code = code.slice(0, -1)
|
|
175
|
+
var fence = code.match(/^([^\n]*)\n([\s\S]*)$/)
|
|
176
|
+
// Wait for the closing fence: streaming partial JSON stays readable as source.
|
|
177
|
+
if (genui && fence && i < parts.length - 1 && fence[2].length <= 200000) {
|
|
178
|
+
var language = fence[1].trim().toLowerCase()
|
|
179
|
+
try {
|
|
180
|
+
if (/^(?:dsh-ui|json dsh-ui|dsh-ui json)$/.test(language)) {
|
|
181
|
+
out += genui.render(JSON.parse(fence[2])); continue
|
|
182
|
+
}
|
|
183
|
+
if (language === 'html' || language === 'htm') {
|
|
184
|
+
out += genui.html(fence[2]) + '<details><summary>HTML / 源码</summary><pre><code>' + escapeHtml(fence[2]) + '</code></pre></details>'; continue
|
|
185
|
+
}
|
|
186
|
+
} catch (_) { /* Invalid or over-budget specs remain source, never execute. */ }
|
|
187
|
+
}
|
|
175
188
|
out += '<pre><code>' + escapeHtml(code) + '</code></pre>'
|
|
176
189
|
} else {
|
|
177
190
|
var escaped = escapeHtml(parts[i])
|
package/public/styles.css
CHANGED
|
@@ -907,15 +907,6 @@ button.overview-attention-item, button.overview-session-item { cursor:pointer; }
|
|
|
907
907
|
.model-editor-actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 2px; }
|
|
908
908
|
.model-editor-error { margin: 0; color: var(--dsr-error); font-size: 12px; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
909
909
|
.model-readonly { color: var(--dsr-warning); font-size: 12px; }
|
|
910
|
-
.feature-test-shell { padding: 14px; }
|
|
911
|
-
.feature-test-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--dsr-line); }
|
|
912
|
-
.feature-test-note { margin-top: 12px; padding: 10px 11px; border: 1px solid var(--dsr-info-line); border-radius: 9px; background: var(--dsr-info-soft); color: var(--dsr-info); font-size: 12px; line-height: 1.55; }
|
|
913
|
-
.feature-test-actions { display: flex; flex-wrap: wrap; gap: 7px; padding: 12px 0 8px; }
|
|
914
|
-
.feature-test-status { min-height: 20px; padding: 4px 0; font-size: 12px; }
|
|
915
|
-
.feature-test-status.error { color: var(--dsr-error); }
|
|
916
|
-
.feature-test-status.ok { color: var(--dsr-success); }
|
|
917
|
-
.feature-test-summary { margin-top: 6px; color: var(--dsr-text); font-size: 12px; line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
918
|
-
.feature-test-log { max-height: 420px; min-height: 170px; margin: 10px 0 0; padding: 11px; overflow: auto; border: 1px solid var(--dsr-line); border-radius: 9px; background: var(--dsr-bg-2); color: var(--dsr-text); font: 11px/1.55 ui-monospace, SFMono-Regular, Consolas, monospace; white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
919
910
|
@media (max-width: 520px) {
|
|
920
911
|
.model-settings-head { flex-direction: column; }
|
|
921
912
|
.model-settings-head .setting-actions { width: 100%; justify-content: flex-start; }
|
|
@@ -926,8 +917,6 @@ button.overview-attention-item, button.overview-session-item { cursor:pointer; }
|
|
|
926
917
|
.model-reasoning-entry .model-input:nth-child(2), .model-reasoning-entry .model-input:nth-child(3) { grid-column: 1 / -1; }
|
|
927
918
|
.model-reasoning-entry .model-entry-remove { grid-column: 2; grid-row: 1; }
|
|
928
919
|
.model-reasoning-default { grid-template-columns: 1fr; gap: 4px; }
|
|
929
|
-
.feature-test-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
930
|
-
.feature-test-actions .mini-btn { width: 100%; }
|
|
931
920
|
}
|
|
932
921
|
.setting-row {
|
|
933
922
|
display: flex; align-items: center; justify-content: space-between; gap: 10px;
|
|
@@ -1326,3 +1315,7 @@ button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible
|
|
|
1326
1315
|
.overview-pulse-card { grid-template-columns:1fr auto; }
|
|
1327
1316
|
.overview-metric-grid { grid-template-columns:repeat(4,minmax(0,1fr)); }
|
|
1328
1317
|
}
|
|
1318
|
+
|
|
1319
|
+
.update-download-progress { margin-top: 12px; font-size: 12px; line-height: 1.6; overflow-wrap: anywhere; }
|
|
1320
|
+
.update-download-progress progress { display: block; width: 100%; height: 10px; margin: 7px 0; accent-color: var(--dsr-accent, #2563eb); }
|
|
1321
|
+
#update-download-detail { color: var(--dsr-text-muted); font-variant-numeric: tabular-nums; }
|
package/public/update.json
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.6.
|
|
2
|
+
"version": "0.6.25",
|
|
3
3
|
"apkUrl": "dsh-remote.apk",
|
|
4
|
-
"sha256": "
|
|
5
|
-
"releasedAt": "2026-09-
|
|
6
|
-
"notes": "0.6.
|
|
4
|
+
"sha256": "56e3aa905bcc4a746c604af7b09a5bfe50c21deafd1b04756a345bd03cc44828",
|
|
5
|
+
"releasedAt": "2026-09-16T06:56:53.046Z",
|
|
6
|
+
"notes": "0.6.25:适配 DSH 0.1.5 的实时思考、文件消息与 V3 会话统计;修复 Windows 跨盘文件访问和空会话持久归档;完善 APK 下载进度与校验;新增 dsh-ui 常用组件及柱状图、折线图、环形图只读预览,HTML 代码块支持隔离预览,未支持的高级组件保留原始规格。",
|
|
7
7
|
"history": [
|
|
8
|
+
{
|
|
9
|
+
"version": "0.6.25",
|
|
10
|
+
"notes": "0.6.25:适配 DSH 0.1.5 的实时思考、文件消息与 V3 会话统计;修复 Windows 跨盘文件访问和空会话持久归档;完善 APK 下载进度与校验;新增 dsh-ui 常用组件及柱状图、折线图、环形图只读预览,HTML 代码块支持隔离预览,未支持的高级组件保留原始规格。"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"version": "0.6.24",
|
|
14
|
+
"notes": "0.6.24:同步 App 与宽屏客户端的会话命名体验;未命名会话显示为“新会话”并保留短标识,创建会话时可选择指定工作区;补充空会话清理与相关回归验证。"
|
|
15
|
+
},
|
|
8
16
|
{
|
|
9
17
|
"version": "0.6.23",
|
|
10
18
|
"notes": "0.6.23:加强 DSH 版本兼容。旧版点号 RPC 与新版 slash Remote API 可自动协商和回退,修复部分新版 DSH 中 host.describe、创建会话等请求返回 404 的问题;DSH 重启或升级后会重新识别协议并恢复实时通道。反馈时可由用户选择附带脱敏兼容性诊断,便于定位接口问题;诊断不包含令牌、Cookie、对话内容或文件路径。"
|
|
@@ -36,14 +44,6 @@
|
|
|
36
44
|
{
|
|
37
45
|
"version": "0.6.16",
|
|
38
46
|
"notes": "0.6.16:Windows 端 DSH 服务启动/重启接入 Windows Service(实验性功能),启动后继续检查 DSH HTTP 与 mux/host 实时通道;空对话退出时清理 App 本地残留;网关控制台主机 IP 改为可逐项启用的地址表,关闭地址不再进入配对二维码、诊断和防火墙建议;Android 设置新增模型配置、自定义模型思考深度档位和小米/系统 ASR 功能测试,支持复制设备、权限、partial/final、session 重建和错误诊断日志。"
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
"version": "0.6.15",
|
|
42
|
-
"notes": "0.6.15:修复拖拽候选项拦截普通竖向滑动的问题,卡片中间也可自然滚动;仅在长按真正进入拖拽后锁定页面,并补充指针结束、取消、失焦和页面隐藏时的解锁清理。保留边缘自动滚动、占位符同步重排、主列表/工作台工作区与组内对话拖动。"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"version": "0.6.14",
|
|
46
|
-
"notes": "0.6.14-rc.7:将 Android 后台轮询服务接入与前台 App 相同的 client ID,修复 Dalvik 后台请求被显示为第二台未知设备;保留旧记录的顺序无关迁移;补齐文件上传请求的持久设备 ID;实时扫码继续使用 Worker 解码并降低取样负载;修复非用户来源的 DSH user/message 被误显示为用户输入;新增子代理折叠、排队消息插话、运行中提示和按轮次稳定排序;Markdown 支持 GFM 表格。"
|
|
47
47
|
}
|
|
48
48
|
]
|
|
49
49
|
}
|
package/public/version.json
CHANGED