@restregular/dsh-notepad 0.5.0 → 0.7.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/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.5.0';
41
+ const VERSION = '0.7.0';
42
42
 
43
43
  /** Request body cap for note writes. */
44
44
  const BODY_LIMIT = 1024 * 1024;
package/lib/note-store.js CHANGED
@@ -3,13 +3,16 @@
3
3
  *
4
4
  * One note per workspace, kept at `<workspace>/.dsh/notepad.json`. A note is an
5
5
  * ordered list of text segments; each segment may be archived after it was
6
- * sent, and only archived segments can be deleted by the client.
6
+ * sent, and the Client may delete either archived or active segments (active
7
+ * deletion is irreversible and confirmed in the UI).
7
8
  *
8
9
  * Version 4 adds an optional card title and creation timestamp to every
9
- * segment. Version 2 stores the segment list under `segments` and repeats the
10
- * merged body under `text` so the file stays human readable and older builds
11
- * can still read the content. Version 1 files (a single `text`) and
12
- * hand-edited plain-text files are migrated on read as one segment.
10
+ * segment. Version 5 stores cards oldest-first; the Client reverses a version 4
11
+ * payload once while reading it. Version 2 stores the segment list under
12
+ * `segments` and repeats the merged body under `text` so the file stays human
13
+ * readable and older builds can still read the content. Version 1 files (a
14
+ * single `text`) and hand-edited plain-text files are migrated on read as one
15
+ * segment.
13
16
  *
14
17
  * @module dsh-notepad/lib/note-store
15
18
  */
@@ -39,8 +42,8 @@ export const MAX_SEGMENT_TITLE_CHARS = 200;
39
42
  /** Maximum characters kept for one creation timestamp. */
40
43
  export const MAX_SEGMENT_TIME_CHARS = 64;
41
44
 
42
- /** Storage envelope version. */
43
- export const NOTE_VERSION = 4;
45
+ /** Storage envelope version. Version 5 flips the default card order to oldest-first. */
46
+ export const NOTE_VERSION = 5;
44
47
 
45
48
  /** Maximum image references accepted on one segment. */
46
49
  export const MAX_IMAGES_PER_SEGMENT = 20;
@@ -358,9 +361,11 @@ export function mergeSegments(segments) {
358
361
  export function parseNote(raw, mtimeMs) {
359
362
  let segmentsInput;
360
363
  let updatedAt;
364
+ let version = null;
361
365
  try {
362
366
  const parsed = JSON.parse(raw);
363
367
  if (parsed !== null && typeof parsed === 'object') {
368
+ if (Number.isFinite(parsed.version)) version = parsed.version;
364
369
  if (Array.isArray(parsed.segments)) segmentsInput = parsed.segments;
365
370
  else if (typeof parsed.text === 'string') segmentsInput = parsed.text;
366
371
  if (typeof parsed.updatedAt === 'string') updatedAt = parsed.updatedAt;
@@ -379,6 +384,7 @@ export function parseNote(raw, mtimeMs) {
379
384
  if (segment !== null) segments.push(segment);
380
385
  }
381
386
  return {
387
+ version,
382
388
  segments,
383
389
  text: mergeSegments(segments),
384
390
  updatedAt: updatedAt ?? (typeof mtimeMs === 'number' ? new Date(mtimeMs).toISOString() : null),
@@ -400,7 +406,7 @@ export async function readNote(root) {
400
406
  raw = await fs.readFile(file, 'utf8');
401
407
  } catch (error) {
402
408
  if (error?.code === 'ENOENT') {
403
- return { segments: [], text: '', updatedAt: null, mtimeMs: null, exists: false, size: 0 };
409
+ return { version: null, segments: [], text: '', updatedAt: null, mtimeMs: null, exists: false, size: 0 };
404
410
  }
405
411
  throw error;
406
412
  }
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; an empty title is just a placeholder 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. Paste or pick images as path-based chips; removing a chip cleans up plugin-owned files. Pending counts appear on the hidden launcher and the sidebar workspace row. Insert, replace, or send one or many; sending archives automatically. Archived segments can be shown, hidden, restored, and deleted. Auto refresh keeps the list scroll position, Ctrl+Shift+0 resets the panel geometry, the panel never covers the host title bar, and it is resizable and dark-mode aware."
4
+ "description": "A per-workspace floating notepad in the session view. Cards run oldest-to-newest, Enter splits after the source card, Backspace at the start of a card merges it into the previous one, and an empty card is deleted immediately (Backspace in it also removes it). 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, send and archive+delete groups wait briefly before expanding on hover; insert/send include current-session and new-session actions, while replace and archive stay single-click primaries. Image chips open an in-panel preview; non-empty delete asks for confirmation and 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, the textarea only shows a scrollbar at its height limit, Ctrl+Shift+R (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": "在会话界面显示一个按工作区共享的分段便签浮窗:新分段置顶,空标题点击后才显示输入框,点击序号选中,可拖拽排序、合并多段、用上下方向键切换分段;AI 优化只作用于选中的分段,优化后按钮变为撤销,相同内容直接复用上次结果;支持粘贴或选择图片并以路径附件形式引入,删除图片芯片会清理插件目录里的文件;隐藏按钮和侧边栏工作区显示未发送数量角标;支持单段/多段插入、替换与发送,发送后自动归档,归档可显示、隐藏、恢复与删除;自动刷新保持滚动位置,浮窗可调整尺寸,Ctrl+Shift+0 复位位置和尺寸,且不会越过窗口标题栏。"
4
+ "description": "在会话界面显示一个按工作区共享的分段便签浮窗:分段从旧到新、从上到下排列,回车拆分后新卡片紧跟原卡片,在段首按 Backspace 会与上一段合并;空标题点击后才显示输入框;点击序号选中,可拖拽排序、合并多段、用上下方向键切换分段;AI 优化只作用于选中的分段,优化后按钮变为撤销,相同内容复用上次结果;插入、发送、归档+删除按钮 hover 稍候才横向展开为细圆角按钮组(插入/发送含当前会话与新会话,替换保持单键);图片支持面板内预览;空分段删除无需确认,空段内按 Backspace 自动删除,其它分段删除需二次确认并提示无法恢复;底部只显示一条快捷键提示,点击轮换;复制全部不包含归档分段;发送行为跟随「设置 > 通用设置」中的繁忙发送策略;隐藏按钮和侧边栏工作区显示未发送数量角标;自动刷新保持滚动位置,分段文本达到最大高度才出现滚动条;浮窗可调整尺寸,Ctrl+Shift+R 或标题栏复位按钮可复位位置和尺寸,且不会越过窗口标题栏。"
5
5
  }
6
6
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@restregular/dsh-notepad",
3
- "version": "0.5.0",
4
- "description": "Notepad — a per-workspace floating notepad in the DeepSeek Harness session view: newest segment cards first with titles that appear only after a click, drag to reorder, merge selected segments, arrow keys to move between cards, AI improve limited to the selected segments with a one-click undo and cached results, image chips with automatic file cleanup, pending-count badges on the hidden button and the sidebar workspace, batch insert / replace / send, archive management, scroll position kept across automatic refreshes, resizable panel, Ctrl+Shift+0 geometry reset, a title-bar-safe position, and dark-mode styling. · 记事本 — 在 DeepSeek Harness 会话界面显示一个按工作区共享的分段便签浮窗:新分段置顶且空标题只在点击后显示输入框,可拖拽排序、合并选中分段、上下方向键切换分段、只对选中分段做 AI 优化,优化后按钮变为撤销并复用相同内容的缓存结果;图片芯片删除时自动清理磁盘文件;隐藏按钮与侧边栏工作区显示未发送数量角标;支持单段/多段插入、替换与发送,发送自动归档,归档可显示隐藏和恢复删除;自动刷新保持列表滚动位置;可调整尺寸,Ctrl+Shift+0 复位位置和尺寸,浮窗不会越过窗口标题栏,并适配深色模式。",
3
+ "version": "0.7.0",
4
+ "description": "Notepad — a per-workspace floating notepad in the DeepSeek Harness session view: oldest-first segment cards with click-to-edit titles, Enter split after the source, Backspace merge into the previous card, drag to reorder, merge selected segments, arrow-key navigation, AI improve with undo and cached results, delayed hover groups for insert / send / archive-delete (including fresh-session variants), in-panel image previews, empty-segment deletion without a prompt, 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, a textarea that only scrolls at its height limit, resizable title-bar-safe panel, Ctrl+Shift+R geometry reset, and dark-mode styling. · 记事本 — 在 DeepSeek Harness 会话界面显示一个按工作区共享的分段便签浮窗:分段按从旧到新、从上到下排列,回车拆分后新卡片紧跟原卡片,在段首按 Backspace 会与上一段合并;空标题只在点击后显示输入框;可拖拽排序、合并选中分段、上下方向键切换分段、只对选中分段做 AI 优化并可撤销 / 复用缓存;插入、发送、归档+删除按钮 hover 稍候才展开为细边框按钮组(插入/发送含新会话变体);图片支持面板内预览;空分段删除无需确认,空段内按 Backspace 自动删除;底部快捷键提示点击轮换;复制全部排除归档;发送跟随「设置 > 通用设置」的繁忙发送策略;图片芯片删除时自动清理磁盘文件;隐藏按钮与侧边栏工作区显示未发送数量角标;自动刷新保持滚动位置;分段文本到最大高度才出现滚动条;可调整尺寸,Ctrl+Shift+R 复位位置和尺寸,浮窗不会越过窗口标题栏,并适配深色模式。",
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
  },