@rooode/dsh-plugin-preview 0.1.17 → 0.1.18
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/lib/client.js +129 -43
- package/lib/index.js +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -394,75 +394,108 @@
|
|
|
394
394
|
return result;
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
-
function
|
|
398
|
-
// Priority 1: User manual override selection (if explicitly chosen by user)
|
|
397
|
+
function resolveActiveWorkspace(ctx) {
|
|
399
398
|
if (globalManualWorkspace && typeof globalManualWorkspace === 'string' && globalManualWorkspace.trim()) {
|
|
400
|
-
|
|
399
|
+
const p = globalManualWorkspace.trim().replace(/[\\/]+$/, '');
|
|
400
|
+
return { path: p, id: 'manual', title: getFileName(p) || p };
|
|
401
401
|
}
|
|
402
|
-
|
|
403
|
-
// Priority 2: Derive active workspace from clientCtx (workspaces + sessions)
|
|
404
|
-
if (clientCtx) {
|
|
402
|
+
if (ctx) {
|
|
405
403
|
try {
|
|
406
|
-
const sSnap =
|
|
407
|
-
const wSnap =
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
//
|
|
411
|
-
if (
|
|
412
|
-
const
|
|
413
|
-
|
|
414
|
-
|
|
404
|
+
const sSnap = ctx.sessions?.list?.getSnapshot?.();
|
|
405
|
+
const wSnap = ctx.workspaces?.list?.getSnapshot?.();
|
|
406
|
+
const curSessionId = sSnap?.current;
|
|
407
|
+
|
|
408
|
+
// 1. Session cwd or workspaceId
|
|
409
|
+
if (curSessionId && sSnap?.byId?.[curSessionId]) {
|
|
410
|
+
const sess = sSnap.byId[curSessionId];
|
|
411
|
+
let wsPath = sess.cwd;
|
|
412
|
+
let wsId = sess.workspaceId;
|
|
413
|
+
let wsTitle = sess.title;
|
|
414
|
+
|
|
415
|
+
if (sess.workspaceId && wSnap?.items) {
|
|
416
|
+
const match = wSnap.items.find(item => item.workspaceId === sess.workspaceId);
|
|
417
|
+
if (match) {
|
|
418
|
+
if (match.path) wsPath = match.path;
|
|
419
|
+
if (match.title) wsTitle = match.title;
|
|
420
|
+
wsId = match.workspaceId;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (wsPath && typeof wsPath === 'string' && wsPath.trim()) {
|
|
424
|
+
const clean = wsPath.trim().replace(/[\\/]+$/, '');
|
|
425
|
+
return {
|
|
426
|
+
path: clean,
|
|
427
|
+
id: wsId || clean,
|
|
428
|
+
title: wsTitle || getFileName(clean) || '工作区',
|
|
429
|
+
};
|
|
415
430
|
}
|
|
416
431
|
}
|
|
417
432
|
|
|
418
|
-
//
|
|
419
|
-
if (
|
|
420
|
-
const
|
|
421
|
-
if (
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
}
|
|
433
|
+
// 2. Find in wSnap.items by sessionIds
|
|
434
|
+
if (curSessionId && wSnap?.items) {
|
|
435
|
+
const match = wSnap.items.find(item => Array.isArray(item.sessionIds) && item.sessionIds.includes(curSessionId));
|
|
436
|
+
if (match?.path) {
|
|
437
|
+
const clean = match.path.trim().replace(/[\\/]+$/, '');
|
|
438
|
+
return {
|
|
439
|
+
path: clean,
|
|
440
|
+
id: match.workspaceId || clean,
|
|
441
|
+
title: match.title || getFileName(clean) || '工作区',
|
|
442
|
+
};
|
|
429
443
|
}
|
|
430
444
|
}
|
|
431
445
|
|
|
432
|
-
//
|
|
433
|
-
if (wSnap
|
|
446
|
+
// 3. Recent workspace
|
|
447
|
+
if (wSnap?.recentWorkspaceId && wSnap?.items) {
|
|
434
448
|
const recent = wSnap.items.find(item => item.workspaceId === wSnap.recentWorkspaceId);
|
|
435
|
-
if (recent
|
|
436
|
-
|
|
449
|
+
if (recent?.path) {
|
|
450
|
+
const clean = recent.path.trim().replace(/[\\/]+$/, '');
|
|
451
|
+
return {
|
|
452
|
+
path: clean,
|
|
453
|
+
id: recent.workspaceId || clean,
|
|
454
|
+
title: recent.title || getFileName(clean) || '工作区',
|
|
455
|
+
};
|
|
437
456
|
}
|
|
438
457
|
}
|
|
439
458
|
|
|
440
|
-
//
|
|
441
|
-
if (wSnap
|
|
459
|
+
// 4. First workspace item
|
|
460
|
+
if (wSnap?.items && wSnap.items.length > 0) {
|
|
442
461
|
const first = wSnap.items[0];
|
|
443
|
-
const
|
|
444
|
-
if (
|
|
445
|
-
|
|
462
|
+
const p = first.path || first.directory || first.cwd;
|
|
463
|
+
if (p && typeof p === 'string' && p.trim()) {
|
|
464
|
+
const clean = p.trim().replace(/[\\/]+$/, '');
|
|
465
|
+
return {
|
|
466
|
+
path: clean,
|
|
467
|
+
id: first.workspaceId || clean,
|
|
468
|
+
title: first.title || getFileName(clean) || '工作区',
|
|
469
|
+
};
|
|
446
470
|
}
|
|
447
471
|
}
|
|
448
472
|
} catch (e) {
|
|
449
|
-
console.warn('[Preview]
|
|
473
|
+
console.warn('[Preview] resolveActiveWorkspace error:', e);
|
|
450
474
|
}
|
|
451
475
|
}
|
|
452
476
|
|
|
453
|
-
// Priority 3: URL hash or search parameter
|
|
454
477
|
if (typeof location !== 'undefined') {
|
|
455
478
|
if (location.hash) {
|
|
456
479
|
const m = location.hash.match(/workspace=([^&]+)/);
|
|
457
|
-
if (m)
|
|
480
|
+
if (m) {
|
|
481
|
+
const p = decodeURIComponent(m[1]).replace(/[\\/]+$/, '');
|
|
482
|
+
return { path: p, id: p, title: getFileName(p) || p };
|
|
483
|
+
}
|
|
458
484
|
}
|
|
459
485
|
if (location.search) {
|
|
460
486
|
const m = location.search.match(/workspace=([^&]+)/);
|
|
461
|
-
if (m)
|
|
487
|
+
if (m) {
|
|
488
|
+
const p = decodeURIComponent(m[1]).replace(/[\\/]+$/, '');
|
|
489
|
+
return { path: p, id: p, title: getFileName(p) || p };
|
|
490
|
+
}
|
|
462
491
|
}
|
|
463
492
|
}
|
|
464
493
|
|
|
465
|
-
return '';
|
|
494
|
+
return { path: '.', id: 'default', title: '工作区' };
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
function getCurrentWorkspaceRoot() {
|
|
498
|
+
return resolveActiveWorkspace(clientCtx).path || '.';
|
|
466
499
|
}
|
|
467
500
|
|
|
468
501
|
function resolveAbsoluteFilePath(targetPath) {
|
|
@@ -1813,11 +1846,11 @@
|
|
|
1813
1846
|
}
|
|
1814
1847
|
}, [searchQuery, treeData]);
|
|
1815
1848
|
|
|
1816
|
-
// Listen to external workspace switch events (e.g. from Git plugin)
|
|
1849
|
+
// Listen to external workspace switch events (e.g. from DSH sidebar or Git plugin)
|
|
1817
1850
|
useEffect(() => {
|
|
1818
1851
|
const handleWsSwitch = (e) => {
|
|
1819
|
-
if (e.detail?.path
|
|
1820
|
-
|
|
1852
|
+
if (e.detail?.path) {
|
|
1853
|
+
setCurrentWs(e.detail.path);
|
|
1821
1854
|
}
|
|
1822
1855
|
};
|
|
1823
1856
|
window.addEventListener('dsh:workspace:switch', handleWsSwitch);
|
|
@@ -6399,6 +6432,59 @@
|
|
|
6399
6432
|
injectStyles();
|
|
6400
6433
|
setupFileInterceptors(ctx);
|
|
6401
6434
|
|
|
6435
|
+
// Subscribe to DSH Session & Workspace store changes (Left Sidebar updates)
|
|
6436
|
+
let lastTrackedSessionId = null;
|
|
6437
|
+
let lastTrackedWsPath = getCurrentWorkspaceRoot();
|
|
6438
|
+
|
|
6439
|
+
function handleDshSessionOrWorkspaceChange() {
|
|
6440
|
+
try {
|
|
6441
|
+
const sSnap = ctx.sessions?.list?.getSnapshot?.();
|
|
6442
|
+
const curSessionId = sSnap?.current;
|
|
6443
|
+
|
|
6444
|
+
// When user clicks a session on the left sidebar:
|
|
6445
|
+
if (curSessionId && curSessionId !== lastTrackedSessionId) {
|
|
6446
|
+
lastTrackedSessionId = curSessionId;
|
|
6447
|
+
// Clear manual override when user actively selects a session in the left sidebar
|
|
6448
|
+
if (globalManualWorkspace) {
|
|
6449
|
+
globalManualWorkspace = null;
|
|
6450
|
+
try { localStorage.removeItem(STORAGE_KEY_MANUAL_WS); } catch (e) {}
|
|
6451
|
+
}
|
|
6452
|
+
}
|
|
6453
|
+
|
|
6454
|
+
const activeWsInfo = resolveActiveWorkspace(ctx);
|
|
6455
|
+
const activeWsPath = activeWsInfo.path;
|
|
6456
|
+
|
|
6457
|
+
if (activeWsPath && activeWsPath !== lastTrackedWsPath) {
|
|
6458
|
+
lastTrackedWsPath = activeWsPath;
|
|
6459
|
+
syncCurrentWorkspaceTabs(activeWsPath);
|
|
6460
|
+
notifyStateChange();
|
|
6461
|
+
if (typeof window !== 'undefined') {
|
|
6462
|
+
window.dispatchEvent(new CustomEvent('dsh:workspace:switch', {
|
|
6463
|
+
detail: { path: activeWsPath, id: activeWsInfo.id, title: activeWsInfo.title }
|
|
6464
|
+
}));
|
|
6465
|
+
}
|
|
6466
|
+
}
|
|
6467
|
+
} catch (e) {
|
|
6468
|
+
console.warn('[Preview] Session/Workspace change handler error:', e);
|
|
6469
|
+
}
|
|
6470
|
+
}
|
|
6471
|
+
|
|
6472
|
+
if (ctx.sessions?.list?.subscribe) {
|
|
6473
|
+
ctx.sessions.list.subscribe(handleDshSessionOrWorkspaceChange);
|
|
6474
|
+
}
|
|
6475
|
+
if (ctx.workspaces?.list?.subscribe) {
|
|
6476
|
+
ctx.workspaces.list.subscribe(handleDshSessionOrWorkspaceChange);
|
|
6477
|
+
}
|
|
6478
|
+
|
|
6479
|
+
// Safety polling every 800ms for route or state changes
|
|
6480
|
+
setInterval(handleDshSessionOrWorkspaceChange, 800);
|
|
6481
|
+
|
|
6482
|
+
// Listen to popstate / hashchange
|
|
6483
|
+
if (typeof window !== 'undefined') {
|
|
6484
|
+
window.addEventListener('popstate', handleDshSessionOrWorkspaceChange);
|
|
6485
|
+
window.addEventListener('hashchange', handleDshSessionOrWorkspaceChange);
|
|
6486
|
+
}
|
|
6487
|
+
|
|
6402
6488
|
console.log('[Preview] Markdown Preview Client Plugin loaded successfully!');
|
|
6403
6489
|
|
|
6404
6490
|
// 1. Mount Unified Right Activity Rail Host into shell.overlay
|
package/lib/index.js
CHANGED
|
@@ -29,7 +29,7 @@ export class PreviewService extends Service {
|
|
|
29
29
|
handler: this.handleHttpRequest.bind(this),
|
|
30
30
|
});
|
|
31
31
|
});
|
|
32
|
-
console.log('[PreviewService] Registered /api/preview route on webServer (v0.1.
|
|
32
|
+
console.log('[PreviewService] Registered /api/preview route on webServer (v0.1.18)');
|
|
33
33
|
} else {
|
|
34
34
|
console.warn('[PreviewService] webServer not available yet in ctx');
|
|
35
35
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rooode/dsh-plugin-preview",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"description": "DeepSeek Harness Markdown 文档与工作空间文件浏览器右侧预览插件 (支持工作区文件树、文件夹创建与文件移动、JSON 交互结构树/格式化、Java/C++/Python/JS/TS/YAML/Go/Rust 多语言语法高亮与符号大纲、自动换行与多标签 FileTabs)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|