@restregular/dsh-notepad 0.4.0 → 0.6.0
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/README.md +43 -22
- package/client.js +1043 -166
- package/index.js +52 -3
- package/locale/en.json +1 -1
- package/locale/zh.json +1 -1
- package/package.json +5 -3
package/index.js
CHANGED
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
const ROUTE = '/dsh-notepad/api';
|
|
39
39
|
|
|
40
40
|
/** Plugin version mirrored in package.json. */
|
|
41
|
-
const VERSION = '0.
|
|
41
|
+
const VERSION = '0.6.0';
|
|
42
42
|
|
|
43
43
|
/** Request body cap for note writes. */
|
|
44
44
|
const BODY_LIMIT = 1024 * 1024;
|
|
@@ -55,6 +55,12 @@ const OPTIMIZE_TIMEOUT_MS = 120_000;
|
|
|
55
55
|
/** Default output cap for one optimized segment. */
|
|
56
56
|
const OPTIMIZE_MAX_TOKENS = 4096;
|
|
57
57
|
|
|
58
|
+
/** Entries kept in the in-process optimizer cache. */
|
|
59
|
+
const OPTIMIZE_CACHE_LIMIT = 64;
|
|
60
|
+
|
|
61
|
+
/** Maximum key + value characters kept in the optimizer cache. */
|
|
62
|
+
const OPTIMIZE_CACHE_CHARS = 2_000_000;
|
|
63
|
+
|
|
58
64
|
/** Shared instruction for the optional writing assistant. */
|
|
59
65
|
const OPTIMIZE_SYSTEM = [
|
|
60
66
|
'You are a writing assistant for a developer notepad.',
|
|
@@ -238,6 +244,41 @@ function cleanOptimizedText(value) {
|
|
|
238
244
|
return text;
|
|
239
245
|
}
|
|
240
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Results of earlier optimizer calls. Re-optimizing content that has not
|
|
249
|
+
* changed returns the previous answer instead of billing another model call.
|
|
250
|
+
* The cache is per host process and bounded by entry count and characters.
|
|
251
|
+
* @type {Map<string, string>}
|
|
252
|
+
*/
|
|
253
|
+
const optimizeCache = new Map();
|
|
254
|
+
let optimizeCacheChars = 0;
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* @param {string} key
|
|
258
|
+
* @param {string} text
|
|
259
|
+
*/
|
|
260
|
+
function cacheOptimizedText(key, text) {
|
|
261
|
+
const previous = optimizeCache.get(key);
|
|
262
|
+
if (previous !== undefined) {
|
|
263
|
+
optimizeCacheChars -= key.length + previous.length;
|
|
264
|
+
optimizeCache.delete(key);
|
|
265
|
+
}
|
|
266
|
+
optimizeCache.set(key, text);
|
|
267
|
+
optimizeCacheChars += key.length + text.length;
|
|
268
|
+
while (optimizeCache.size > OPTIMIZE_CACHE_LIMIT || optimizeCacheChars > OPTIMIZE_CACHE_CHARS) {
|
|
269
|
+
const oldest = optimizeCache.keys().next();
|
|
270
|
+
if (oldest.done === true) break;
|
|
271
|
+
const value = optimizeCache.get(oldest.value) ?? '';
|
|
272
|
+
optimizeCacheChars -= oldest.value.length + value.length;
|
|
273
|
+
optimizeCache.delete(oldest.value);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** Workspace + title + text: everything the optimizer prompt depends on. */
|
|
278
|
+
function optimizeCacheKey(root, title, text) {
|
|
279
|
+
return `${root}\u0000${title}\u0000${text}`;
|
|
280
|
+
}
|
|
281
|
+
|
|
241
282
|
/**
|
|
242
283
|
* Ask the currently selected default model to improve one note segment.
|
|
243
284
|
* The LLM service is optional: a deployment without one reports a stable
|
|
@@ -425,8 +466,16 @@ async function dispatchRequest(ctx, req, res) {
|
|
|
425
466
|
`Segment is too large to optimize (${text.length} characters; limit ${MAX_OPTIMIZE_CHARS}).`,
|
|
426
467
|
);
|
|
427
468
|
}
|
|
428
|
-
const
|
|
429
|
-
|
|
469
|
+
const title = typeof body.title === 'string' ? body.title : '';
|
|
470
|
+
const cacheKey = optimizeCacheKey(root, title, text);
|
|
471
|
+
const cached = optimizeCache.get(cacheKey);
|
|
472
|
+
if (typeof cached === 'string' && cached !== '') {
|
|
473
|
+
sendJson(res, { ok: true, root, text: cached, cached: true });
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
const optimized = await optimizeText(ctx, text, title);
|
|
477
|
+
cacheOptimizedText(cacheKey, optimized);
|
|
478
|
+
sendJson(res, { ok: true, root, text: optimized, cached: false });
|
|
430
479
|
return;
|
|
431
480
|
}
|
|
432
481
|
if (action !== 'note') {
|
package/locale/en.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"meta": {
|
|
3
3
|
"title": "Notepad",
|
|
4
|
-
"description": "A per-workspace floating notepad in the session view. New segment cards lead the list
|
|
4
|
+
"description": "A per-workspace floating notepad in the session view. New segment cards lead the list; an empty title is just a blank click target until clicked. Click an index to select, drag to reorder, merge a selection, move between cards with the arrow keys, and improve only the selected cards with AI — the button turns into undo and identical content reuses the previous answer. Insert and send buttons expand on hover into current-session / new-session groups, while replace stays a single button. Image chips open an in-panel preview; active segments can be deleted directly after a confirmation that warns the action cannot be undone. The footer shows one shortcut tip at a time and rotates on click; copy-all skips archived segments; sending follows the General Settings busy-send policy. Pending counts appear on the hidden launcher and the sidebar workspace row, auto refresh keeps the list scroll position, Ctrl+Shift+0 (or the header reset button) resets the panel geometry, and the panel never covers the host title bar."
|
|
5
5
|
}
|
|
6
6
|
}
|
package/locale/zh.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"meta": {
|
|
3
3
|
"title": "记事本",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "在会话界面显示一个按工作区共享的分段便签浮窗:新分段置顶,空标题点击后才显示输入框,点击序号选中,可拖拽排序、合并多段、用上下方向键切换分段;AI 优化只作用于选中的分段,优化后按钮变为撤销,相同内容直接复用上次结果;插入 / 发送按钮 hover 时横向展开为「当前会话 / 新会话」按钮组,替换按钮保持单键;图片支持面板内预览;可直接删除分段,但需弹窗二次确认并提示无法恢复;底部只显示一条快捷键提示,点击轮换;复制全部不包含归档分段;发送行为跟随「设置 > 通用设置」中的繁忙发送策略;支持粘贴或选择图片并以路径附件形式引入;隐藏按钮和侧边栏工作区显示未发送数量角标;自动刷新保持滚动位置,浮窗可调整尺寸,Ctrl+Shift+0 或标题栏复位按钮可复位位置和尺寸,且不会越过窗口标题栏。"
|
|
5
5
|
}
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@restregular/dsh-notepad",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Notepad — a per-workspace floating notepad in the DeepSeek Harness session view: newest segment cards first with
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Notepad — a per-workspace floating notepad in the DeepSeek Harness session view: newest segment cards first with click-to-edit titles, drag to reorder, merge selected segments, arrow-key navigation, AI improve limited to selected segments with undo and cached results, hover insert / send groups that also target a fresh session, in-panel image previews, direct delete with a confirmation, rotating shortcut tips, copy-all that skips archived segments, the General Settings busy-send policy, image chips with automatic file cleanup, pending-count badges on the hidden button and sidebar workspace, scroll-safe auto refresh, resizable title-bar-safe panel, Ctrl+Shift+0 geometry reset, and dark-mode styling. · 记事本 — 在 DeepSeek Harness 会话界面显示一个按工作区共享的分段便签浮窗:新分段置顶且空标题只在点击后显示输入框,可拖拽排序、合并选中分段、上下方向键切换分段、只对选中分段做 AI 优化,优化后按钮变为撤销并复用缓存结果;插入 / 发送按钮 hover 时展开为「当前会话 / 新会话」按钮组,图片支持面板内预览,可直接删除分段但需二次确认,底部快捷键提示可点击轮换,复制全部不再包含归档分段,发送行为跟随「设置 > 通用设置」中的繁忙发送策略;图片芯片删除时自动清理磁盘文件;隐藏按钮与侧边栏工作区显示未发送数量角标;自动刷新保持列表滚动位置;可调整尺寸,Ctrl+Shift+0 复位位置和尺寸,浮窗不会越过窗口标题栏,并适配深色模式。",
|
|
5
5
|
"icon": "./icon.svg",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "index.js",
|
|
@@ -34,7 +34,9 @@
|
|
|
34
34
|
"@deepseek-ai/dsh-client-ui-layout",
|
|
35
35
|
"@deepseek-ai/dsh-api-session-controller",
|
|
36
36
|
"@deepseek-ai/dsh-client-ui-session",
|
|
37
|
-
"@deepseek-ai/dsh-client-ui-conversation"
|
|
37
|
+
"@deepseek-ai/dsh-client-ui-conversation",
|
|
38
|
+
"@deepseek-ai/dsh-client-ui-workspace",
|
|
39
|
+
"@deepseek-ai/dsh-client-shortcuts"
|
|
38
40
|
]
|
|
39
41
|
}
|
|
40
42
|
},
|