@zhe_xuan/dsh-paper-desk 0.3.0 → 0.3.2

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 CHANGED
@@ -148,7 +148,8 @@ AI 侧栏里每条回答右下角有 **「生成卡片」**:打开编辑器,
148
148
  本插件是标准 DSH 插件包(`dsh.bundle` + `cordis.patch.yml` + `lib/` 预构建产物),可以:
149
149
 
150
150
  - 从本地目录安装:`dsh plugin --profile <profile> add /path/to/dsh-paper-desk`
151
- - 从 npm 安装(发布后):`dsh plugin --profile <profile> add dsh-paper-desk`
151
+ - 从 npm 安装:`dsh plugin --profile <profile> add @zhe_xuan/dsh-paper-desk`
152
+ (npm 上因与已有包 `dsh-paperdesk` 名称相近,包发布在 `@zhe_xuan` scope 下)
152
153
  - 发布到社区市场:需要在 npm 发布,并向 [awesome-dsh-plugin](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin) 提交一个条目(市场 dshmarket 从该列表同步)。
153
154
 
154
155
  完整步骤、市场条目模板和自检清单见 **[docs/PUBLISHING.md](docs/PUBLISHING.md)**。
Binary file
package/lib/client.js CHANGED
@@ -1430,10 +1430,10 @@ window.__ModuleLoader__.load({
1430
1430
  var zh = {
1431
1431
  // ── panel registration (used by client/index.tsx) ──────────────────────
1432
1432
  "title": "\u8BBA\u6587\u5E93 PaperDesk",
1433
- "description": "\u7BA1\u7406\u8BBA\u6587\uFF1A\u5BFC\u5165 PDF\u3001\u81EA\u52A8\u8865\u5168\u5143\u6570\u636E\u3001\u8BB0\u7B14\u8BB0\u4E0E\u9AD8\u4EAE\uFF0C\u5E76\u8BA9 Agent \u7CBE\u8BFB\u8BBA\u6587\u3002",
1433
+ "description": "\u7BA1\u7406\u8BBA\u6587\uFF1A\u5BFC\u5165 PDF\u3001\u81EA\u52A8\u8865\u5168\u5143\u6570\u636E\u3001\u8BB0\u7B14\u8BB0\u4E0E\u9AD8\u4EAE\uFF0C\u5E76\u8BA9 AI \u5E2E\u4F60\u8BFB\u8BBA\u6587\u3002",
1434
1434
  // ── app shell ──────────────────────────────────────────────────────────
1435
1435
  "app.title": "\u8BBA\u6587\u5E93 \xB7 PaperDesk",
1436
- "app.subtitle": "PDF \u8BBA\u6587\u5E93 \xB7 \u7B14\u8BB0 \xB7 Agent \u7CBE\u8BFB \xB7 \u7F51\u76D8\u540C\u6B65",
1436
+ "app.subtitle": "PDF \u8BBA\u6587\u5E93 \xB7 \u7B14\u8BB0 \xB7 AI \u52A9\u8BFB \xB7 \u7F51\u76D8\u540C\u6B65",
1437
1437
  "app.lang.zh": "\u4E2D\u6587",
1438
1438
  "app.lang.en": "English",
1439
1439
  "app.lang.label": "\u754C\u9762\u8BED\u8A00",
@@ -1603,7 +1603,7 @@ window.__ModuleLoader__.load({
1603
1603
  "annotations.saveFailed": "\u4FDD\u5B58\u6279\u6CE8\u5931\u8D25",
1604
1604
  "annotations.deleteFailed": "\u5220\u9664\u6279\u6CE8\u5931\u8D25",
1605
1605
  "annotations.askTitle": "\u9488\u5BF9\u8FD9\u6761\u6279\u6CE8\u95EE Agent",
1606
- "annotations.askDesc": "\u95EE\u9898\u4F1A\u548C\u5F15\u7528\u539F\u6587\u4E00\u8D77\u5E26\u7ED9 Agent\uFF0C\u5E76\u5728\u65B0\u4F1A\u8BDD\u4E2D\u53D1\u9001\u3002",
1606
+ "annotations.askDesc": "\u95EE\u9898\u4F1A\u548C\u5F15\u7528\u539F\u6587\u4E00\u8D77\u53D1\u7ED9 AI \u52A9\u8BFB\uFF0C\u5E76\u5728\u53F3\u4FA7\u9762\u677F\u4E2D\u7EE7\u7EED\u3002",
1607
1607
  "annotations.askPlaceholder": "\u60F3\u95EE\u4EC0\u4E48\uFF1F",
1608
1608
  "annotations.askSubmit": "\u53D1\u9001",
1609
1609
  "annotations.askFailed": "\u65E0\u6CD5\u5411 Agent \u63D0\u95EE",
@@ -1691,13 +1691,14 @@ window.__ModuleLoader__.load({
1691
1691
  "notes.conflict.diskLoaded": "\u5DF2\u52A0\u8F7D\u78C1\u76D8\u4E0A\u7684\u7248\u672C",
1692
1692
  "notes.retry": "\u91CD\u65B0\u52A0\u8F7D",
1693
1693
  // ── in-panel AI drawer ─────────────────────────────────────────────────
1694
- "ai.title": "AI \u89E3\u8BFB",
1695
- "ai.emptyHint": "\u9009\u62E9\u4E0A\u9762\u7684\u4EFB\u52A1\uFF0C\u8BA9 Agent \u5728\u8FD9\u91CC\u7CBE\u8BFB\u8FD9\u7BC7\u8BBA\u6587\u3002",
1694
+ "ai.title": "AI \u52A9\u8BFB",
1695
+ "ai.emptyHint": "\u70B9\u4E0A\u65B9\u4EFB\u52A1\u5FEB\u901F\u5F00\u59CB\uFF0C\u6216\u5728\u4E0B\u65B9\u76F4\u63A5\u63D0\u95EE\u3002",
1696
1696
  "ai.thinking": "\u6B63\u5728\u601D\u8003\u2026",
1697
1697
  "ai.attaching": "\u6B63\u5728\u8FDE\u63A5\u4F1A\u8BDD\u2026",
1698
1698
  "ai.stop": "\u505C\u6B62",
1699
1699
  "ai.send": "\u53D1\u9001",
1700
1700
  "ai.placeholder": "\u7EE7\u7EED\u63D0\u95EE\u2026\uFF08Enter \u53D1\u9001\uFF0CShift+Enter \u6362\u884C\uFF09",
1701
+ "ai.composingHint": "\u8F93\u5165\u6CD5\u9009\u8BCD\u4E2D\uFF1A\u6309 Enter \u5B8C\u6210\u9009\u8BCD\uFF0C\u518D\u6309\u4E00\u6B21 Enter \u53D1\u9001",
1701
1702
  "ai.saveToNotes": "\u4FDD\u5B58\u5230\u7B14\u8BB0",
1702
1703
  "ai.saved": "\u5DF2\u4FDD\u5B58\u5230\u7B14\u8BB0",
1703
1704
  "ai.saveFailed": "\u4FDD\u5B58\u5230\u7B14\u8BB0\u5931\u8D25",
@@ -1708,15 +1709,15 @@ window.__ModuleLoader__.load({
1708
1709
  "ai.openInSessionFailed": "\u65E0\u6CD5\u6253\u5F00\u5B8C\u6574\u4F1A\u8BDD",
1709
1710
  "ai.jumpHint": "\u5F15\u7528\u9875",
1710
1711
  "ai.retry": "\u91CD\u8BD5",
1711
- "ai.error": "AI \u89E3\u8BFB\u5931\u8D25",
1712
+ "ai.error": "AI \u52A9\u8BFB\u5931\u8D25",
1712
1713
  "ai.attachFailed": "\u65E0\u6CD5\u8FDE\u63A5 AI \u4F1A\u8BDD",
1713
1714
  "ai.nothingToSave": "\u8FD8\u6CA1\u6709\u53EF\u4FDD\u5B58\u7684\u56DE\u590D",
1714
1715
  "ai.scrolledUpHint": "\u8DF3\u5230\u6700\u65B0",
1715
1716
  "ai.newAnswer": "\u6709\u65B0\u56DE\u590D",
1716
1717
  "ai.reasoning": "\u63A8\u7406\u8FC7\u7A0B",
1717
1718
  // ── agent assist ───────────────────────────────────────────────────────
1718
- "assist.title": "Agent \u7CBE\u8BFB",
1719
- "assist.hint": "\u5728\u53F3\u4FA7\u9762\u677F\u4E2D\u8FD0\u884C Agent",
1719
+ "assist.title": "AI \u52A9\u8BFB",
1720
+ "assist.hint": "\u5728\u53F3\u4FA7\u9762\u677F\u4E2D\u8BA9 AI \u5E2E\u4F60\u8BFB\u8FD9\u7BC7\u8BBA\u6587",
1720
1721
  "assist.summary": "\u603B\u7ED3",
1721
1722
  "assist.method": "\u65B9\u6CD5\u7CBE\u8BFB",
1722
1723
  "assist.critique": "\u5BA1\u9605",
@@ -1725,8 +1726,8 @@ window.__ModuleLoader__.load({
1725
1726
  "assist.quote": "\u9488\u5BF9\u9009\u4E2D\u5185\u5BB9\u63D0\u95EE",
1726
1727
  "assist.custom": "\u81EA\u5B9A\u4E49",
1727
1728
  "assist.failed": "\u65E0\u6CD5\u542F\u52A8\u65B0\u4F1A\u8BDD",
1728
- "assist.question.title": "\u5411 Agent \u63D0\u95EE",
1729
- "assist.question.desc": "\u95EE\u9898\u4F1A\u5E26\u7740\u9009\u4E2D\u5185\u5BB9\u4E00\u8D77\u53D1\u9001\u7ED9\u53F3\u4FA7\u9762\u677F\u4E2D\u7684 Agent\u3002",
1729
+ "assist.question.title": "\u5411 AI \u52A9\u8BFB\u63D0\u95EE",
1730
+ "assist.question.desc": "\u95EE\u9898\u4F1A\u5E26\u7740\u9009\u4E2D\u5185\u5BB9\u4E00\u8D77\u53D1\u9001\u5230\u53F3\u4FA7 AI \u52A9\u8BFB\u9762\u677F\u3002",
1730
1731
  "assist.question.placeholder": "\u8F93\u5165\u4F60\u7684\u95EE\u9898\u2026",
1731
1732
  "assist.question.ask": "\u5F00\u59CB\u63D0\u95EE",
1732
1733
  // ── sync ───────────────────────────────────────────────────────────────
@@ -1841,7 +1842,7 @@ window.__ModuleLoader__.load({
1841
1842
  "aria.tagFilter": "\u6309\u6807\u7B7E\u7B5B\u9009",
1842
1843
  "aria.sort": "\u6392\u5E8F\u65B9\u5F0F",
1843
1844
  "aria.notesEditor": "\u7B14\u8BB0\u7F16\u8F91\u5668",
1844
- "aria.assistBar": "Agent \u7CBE\u8BFB\u64CD\u4F5C",
1845
+ "aria.assistBar": "AI \u52A9\u8BFB\u64CD\u4F5C",
1845
1846
  "aria.rating": "\u8BC4\u5206",
1846
1847
  "aria.language": "\u5207\u6362\u754C\u9762\u8BED\u8A00",
1847
1848
  "aria.readerTabs": "\u8BBA\u6587\u5185\u5BB9\u6807\u7B7E",
@@ -1851,7 +1852,7 @@ window.__ModuleLoader__.load({
1851
1852
  "cards.create": "\u65B0\u5EFA\u5361\u7247",
1852
1853
  "cards.loading": "\u6B63\u5728\u52A0\u8F7D\u5361\u7247\u2026",
1853
1854
  "cards.empty": "\u8FD8\u6CA1\u6709\u5361\u7247",
1854
- "cards.emptyHint": "\u4ECE AI \u89E3\u8BFB\u7684\u56DE\u7B54\u751F\u6210\u5361\u7247\uFF0C\u628A\u7ED3\u8BBA\u6C89\u6DC0\u5728\u7B14\u8BB0\u65C1\u8FB9\u3002",
1855
+ "cards.emptyHint": "\u4ECE AI \u52A9\u8BFB\u7684\u56DE\u7B54\u751F\u6210\u5361\u7247\uFF0C\u628A\u7ED3\u8BBA\u6C89\u6DC0\u5728\u7B14\u8BB0\u65C1\u8FB9\u3002",
1855
1856
  "cards.editorCreate": "\u751F\u6210\u5361\u7247",
1856
1857
  "cards.editorEdit": "\u7F16\u8F91\u5361\u7247",
1857
1858
  "cards.editorHint": "\u5361\u7247\u4FDD\u5B58\u5728\u8BBA\u6587\u76EE\u5F55\u7684 cards.json \u4E2D\uFF0C\u53EF\u4EE5\u7F16\u8F91\u540E\u518D\u63D2\u5165\u7B14\u8BB0\u3002",
@@ -1915,10 +1916,10 @@ window.__ModuleLoader__.load({
1915
1916
  var en = {
1916
1917
  // ── panel registration (used by client/index.tsx) ──────────────────────
1917
1918
  "title": "PaperDesk Library",
1918
- "description": "Manage papers: import PDFs, enrich metadata, take notes and let the agent deep-read them.",
1919
+ "description": "Manage papers: import PDFs, enrich metadata, take notes and let AI help you read them.",
1919
1920
  // ── app shell ──────────────────────────────────────────────────────────
1920
1921
  "app.title": "PaperDesk \xB7 Library",
1921
- "app.subtitle": "PDF library \xB7 notes \xB7 agent deep-reads \xB7 cloud sync",
1922
+ "app.subtitle": "PDF library \xB7 notes \xB7 AI reading \xB7 cloud sync",
1922
1923
  "app.lang.zh": "\u4E2D\u6587",
1923
1924
  "app.lang.en": "English",
1924
1925
  "app.lang.label": "Interface language",
@@ -2177,12 +2178,13 @@ window.__ModuleLoader__.load({
2177
2178
  "notes.retry": "Reload",
2178
2179
  // ── in-panel AI drawer ─────────────────────────────────────────────────
2179
2180
  "ai.title": "AI reading",
2180
- "ai.emptyHint": "Pick a task above and let the agent read this paper right here.",
2181
+ "ai.emptyHint": "Pick a task above to start, or ask below.",
2181
2182
  "ai.thinking": "Thinking\u2026",
2182
2183
  "ai.attaching": "Connecting the session\u2026",
2183
2184
  "ai.stop": "Stop",
2184
2185
  "ai.send": "Send",
2185
2186
  "ai.placeholder": "Ask a follow-up\u2026 (Enter to send, Shift+Enter for a newline)",
2187
+ "ai.composingHint": "IME composing: press Enter to finish the candidate, then press Enter again to send",
2186
2188
  "ai.saveToNotes": "Save to notes",
2187
2189
  "ai.saved": "Saved to notes",
2188
2190
  "ai.saveFailed": "Failed to save to notes",
@@ -2200,8 +2202,8 @@ window.__ModuleLoader__.load({
2200
2202
  "ai.newAnswer": "New answer",
2201
2203
  "ai.reasoning": "Reasoning",
2202
2204
  // ── agent assist ───────────────────────────────────────────────────────
2203
- "assist.title": "Agent deep-read",
2204
- "assist.hint": "runs the agent in the side panel",
2205
+ "assist.title": "AI reading",
2206
+ "assist.hint": "Read this paper with AI in the side panel",
2205
2207
  "assist.summary": "Summary",
2206
2208
  "assist.method": "Method deep-dive",
2207
2209
  "assist.critique": "Critique",
@@ -2210,8 +2212,8 @@ window.__ModuleLoader__.load({
2210
2212
  "assist.quote": "Ask about selection",
2211
2213
  "assist.custom": "Custom",
2212
2214
  "assist.failed": "Could not start a new session",
2213
- "assist.question.title": "Ask the agent",
2214
- "assist.question.desc": "The question and the selection are sent to the agent in the side panel.",
2215
+ "assist.question.title": "Ask the AI reader",
2216
+ "assist.question.desc": "The question and the selection are sent to the AI panel on the right.",
2215
2217
  "assist.question.placeholder": "Type your question\u2026",
2216
2218
  "assist.question.ask": "Ask",
2217
2219
  // ── sync ───────────────────────────────────────────────────────────────
@@ -2326,7 +2328,7 @@ window.__ModuleLoader__.load({
2326
2328
  "aria.tagFilter": "Filter by tag",
2327
2329
  "aria.sort": "Sort order",
2328
2330
  "aria.notesEditor": "Notes editor",
2329
- "aria.assistBar": "Agent deep-read actions",
2331
+ "aria.assistBar": "AI reading actions",
2330
2332
  "aria.rating": "Rating",
2331
2333
  "aria.language": "Switch interface language",
2332
2334
  "aria.readerTabs": "Paper content tabs",
@@ -6458,7 +6460,6 @@ window.__ModuleLoader__.load({
6458
6460
  // client/AiPanel.tsx
6459
6461
  var import_react6 = require("react");
6460
6462
  var import_jsx_runtime7 = require("react/jsx-runtime");
6461
- var PANEL_TASKS = ["summary", "method", "critique", "related"];
6462
6463
  function collectCitedPages(rows) {
6463
6464
  const text = rows.filter((row) => row.kind === "assistant").map((row) => row.text).join("\n");
6464
6465
  const pages = [];
@@ -6485,19 +6486,21 @@ window.__ModuleLoader__.load({
6485
6486
  return value.length > 90 ? `${value.slice(0, 90)}\u2026` : value;
6486
6487
  }
6487
6488
  function AiPanel(props) {
6488
- const { ai, busyTask, labels, onRunTask, onAsk, onStop, onSaveToNotes, onCopy, onOpenInSession, onJumpPage, onCreateCard } = props;
6489
+ const { ai, labels, onAsk, onStop, onSaveToNotes, onCopy, onOpenInSession, onJumpPage, onCreateCard } = props;
6489
6490
  const subscribe = (0, import_react6.useCallback)((listener) => ai.subscribe(listener), [ai]);
6490
6491
  const getSnapshot = (0, import_react6.useCallback)(() => ai.getSnapshot(), [ai]);
6491
6492
  const snapshot = (0, import_react6.useSyncExternalStore)(subscribe, getSnapshot);
6492
6493
  const [draft, setDraft] = (0, import_react6.useState)("");
6494
+ const [sending, setSending] = (0, import_react6.useState)(false);
6495
+ const [composing, setComposing] = (0, import_react6.useState)(false);
6496
+ const composingRef = (0, import_react6.useRef)(false);
6493
6497
  const [follow, setFollow] = (0, import_react6.useState)(true);
6494
6498
  const [hasNew, setHasNew] = (0, import_react6.useState)(false);
6495
6499
  const scrollRef = (0, import_react6.useRef)(null);
6496
- const inputRef = (0, import_react6.useRef)(null);
6497
6500
  const rows = snapshot.rows;
6498
6501
  const running = snapshot.status === "running";
6499
6502
  const attaching = snapshot.status === "attaching";
6500
- const disabled = running || attaching;
6503
+ const disabled = running || attaching || sending;
6501
6504
  const answer = ai.lastAnswer();
6502
6505
  const pages = (0, import_react6.useMemo)(() => collectCitedPages(rows), [rows]);
6503
6506
  const lastPrompt = (0, import_react6.useMemo)(() => {
@@ -6540,19 +6543,17 @@ window.__ModuleLoader__.load({
6540
6543
  setFollow(true);
6541
6544
  setHasNew(false);
6542
6545
  };
6543
- const focusFollowUp = () => {
6544
- inputRef.current?.focus();
6545
- };
6546
6546
  const send = async () => {
6547
6547
  const text = draft.trim();
6548
6548
  if (text === "" || disabled) return;
6549
- setDraft("");
6550
6549
  setFollow(true);
6551
- await onAsk(text);
6552
- };
6553
- const runTask = (task) => {
6554
- if (disabled || busyTask !== null) return;
6555
- void onRunTask(task);
6550
+ setSending(true);
6551
+ try {
6552
+ const accepted = await onAsk(text);
6553
+ if (accepted) setDraft("");
6554
+ } finally {
6555
+ setSending(false);
6556
+ }
6556
6557
  };
6557
6558
  const retryLast = (prompt) => {
6558
6559
  if (disabled) return;
@@ -6590,21 +6591,6 @@ window.__ModuleLoader__.load({
6590
6591
  }
6591
6592
  };
6592
6593
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "pd-ai", role: "region", "aria-label": labels.title, children: [
6593
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "pd-ai-tasks", role: "group", "aria-label": labels.title, children: [
6594
- PANEL_TASKS.map((task) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6595
- Button,
6596
- {
6597
- size: "sm",
6598
- variant: "ghost",
6599
- disabled: disabled || busyTask !== null,
6600
- loading: busyTask === task,
6601
- onClick: () => runTask(task),
6602
- children: labels.taskLabels[task]
6603
- },
6604
- task
6605
- )),
6606
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { size: "sm", variant: "ghost", disabled: disabled || busyTask !== null, onClick: focusFollowUp, children: labels.taskLabels.questions })
6607
- ] }),
6608
6594
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "pd-ai-body", children: [
6609
6595
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "pd-ai-scroll", ref: scrollRef, onScroll, children: [
6610
6596
  attaching ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "pd-ai-thinking", children: [
@@ -6627,7 +6613,7 @@ window.__ModuleLoader__.load({
6627
6613
  `cite-${page}`
6628
6614
  )) }) : null
6629
6615
  ] }, row.id)),
6630
- running ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "pd-ai-thinking", children: [
6616
+ running || sending ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "pd-ai-thinking", children: [
6631
6617
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Spinner, { size: 11, label: labels.thinking }),
6632
6618
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: labels.thinking })
6633
6619
  ] }) : null
@@ -6685,7 +6671,6 @@ window.__ModuleLoader__.load({
6685
6671
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
6686
6672
  "textarea",
6687
6673
  {
6688
- ref: inputRef,
6689
6674
  className: "pd-textarea pd-ai-input",
6690
6675
  rows: 2,
6691
6676
  value: draft,
@@ -6693,8 +6678,17 @@ window.__ModuleLoader__.load({
6693
6678
  "aria-label": labels.placeholder,
6694
6679
  disabled,
6695
6680
  onChange: (event) => setDraft(event.target.value),
6681
+ onCompositionStart: () => {
6682
+ composingRef.current = true;
6683
+ setComposing(true);
6684
+ },
6685
+ onCompositionEnd: () => {
6686
+ composingRef.current = false;
6687
+ setComposing(false);
6688
+ },
6696
6689
  onKeyDown: (event) => {
6697
- if (event.key !== "Enter" || event.shiftKey || event.nativeEvent.isComposing) return;
6690
+ if (event.key !== "Enter" || event.shiftKey) return;
6691
+ if (composingRef.current || event.nativeEvent.isComposing || event.keyCode === 229) return;
6698
6692
  event.preventDefault();
6699
6693
  void send();
6700
6694
  }
@@ -6710,7 +6704,8 @@ window.__ModuleLoader__.load({
6710
6704
  children: labels.send
6711
6705
  }
6712
6706
  )
6713
- ] })
6707
+ ] }),
6708
+ composing ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "pd-ai-ime-hint", role: "status", children: labels.composingHint }) : null
6714
6709
  ] })
6715
6710
  ] });
6716
6711
  }
@@ -9106,6 +9101,7 @@ window.__ModuleLoader__.load({
9106
9101
  newAnswer: t("ai.newAnswer"),
9107
9102
  reasoning: t("ai.reasoning"),
9108
9103
  createCard: t("cards.createFromAnswer"),
9104
+ composingHint: t("ai.composingHint"),
9109
9105
  taskLabels: {
9110
9106
  summary: t("assist.summary"),
9111
9107
  method: t("assist.method"),
@@ -9323,25 +9319,6 @@ window.__ModuleLoader__.load({
9323
9319
  children: t("annotations.toggle", { n: annotationItems.length })
9324
9320
  }
9325
9321
  ),
9326
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
9327
- Button,
9328
- {
9329
- size: "sm",
9330
- variant: "ghost",
9331
- icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(IconSpark, { size: 13 }),
9332
- "aria-pressed": drawerButtonPressed(drawer, "ai"),
9333
- onClick: () => {
9334
- if (tab !== "read") {
9335
- setTab("read");
9336
- openDrawer("ai");
9337
- return;
9338
- }
9339
- toggleDrawer("ai");
9340
- },
9341
- title: t("ai.title"),
9342
- children: t("ai.title")
9343
- }
9344
- ),
9345
9322
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
9346
9323
  Button,
9347
9324
  {
@@ -9433,10 +9410,21 @@ window.__ModuleLoader__.load({
9433
9410
  }
9434
9411
  ),
9435
9412
  /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "pd-assist-inline", role: "group", "aria-label": t("aria.assistBar"), title: t("assist.hint"), children: [
9436
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "pd-assist-inline-label", children: [
9437
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(IconSpark, { size: 12 }),
9438
- t("assist.title")
9439
- ] }),
9413
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
9414
+ Button,
9415
+ {
9416
+ size: "sm",
9417
+ variant: "ghost",
9418
+ icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(IconSpark, { size: 12 }),
9419
+ "aria-pressed": drawerButtonPressed(drawer, "ai"),
9420
+ onClick: () => {
9421
+ setTab("read");
9422
+ openDrawer("ai");
9423
+ },
9424
+ title: t("assist.hint"),
9425
+ children: t("assist.title")
9426
+ }
9427
+ ),
9440
9428
  ASSIST_TASKS.map((task) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
9441
9429
  Button,
9442
9430
  {
@@ -9593,7 +9581,7 @@ window.__ModuleLoader__.load({
9593
9581
  busyTask: assistBusy,
9594
9582
  labels: aiLabels,
9595
9583
  onRunTask: (task) => runTask(task),
9596
- onAsk: (text2) => void onAiAsk(text2),
9584
+ onAsk: (text2) => onAiAsk(text2),
9597
9585
  onStop: () => void onAiStop(),
9598
9586
  onSaveToNotes: (text2) => void onAiSaveToNotes(text2),
9599
9587
  onCopy: (text2) => void onAiCopy(text2),
@@ -15157,6 +15145,13 @@ window.__ModuleLoader__.load({
15157
15145
  .pd-ai-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; }
15158
15146
  .pd-ai-actions .pd-btn { min-height: 24px; padding: 2px 6px; color: ${FG_22}; font-size: 11.5px; }
15159
15147
  .pd-ai-actions .pd-btn:hover:not(:disabled) { color: ${FG2}; }
15148
+ .pd-ai-ime-hint {
15149
+ margin-top: 3px;
15150
+ color: ${FG_22};
15151
+ font-size: 11px;
15152
+ line-height: 1.4;
15153
+ }
15154
+
15160
15155
  .pd-ai-inputRow { display: flex; align-items: flex-end; gap: 6px; }
15161
15156
  .pd-ai-input { flex: 1 1 auto; min-height: 34px; max-height: 120px; resize: vertical; font-size: 12px; padding: 6px 8px; }
15162
15157
 
@@ -16583,10 +16578,10 @@ window.__ModuleLoader__.load({
16583
16578
  const handleAiAsk = (0, import_react13.useCallback)(
16584
16579
  async (question) => {
16585
16580
  const paperId = selectedId;
16586
- if (paperId === null) return;
16581
+ if (paperId === null) return false;
16587
16582
  const text = question.trim();
16588
- if (text === "") return;
16589
- if (!await ensureAiPaper(paperId)) return;
16583
+ if (text === "") return false;
16584
+ if (!await ensureAiPaper(paperId)) return false;
16590
16585
  try {
16591
16586
  const emptyThread = ai.getSnapshot().rows.length === 0;
16592
16587
  const title = detail?.meta.title ?? paperId;
@@ -16597,8 +16592,10 @@ window.__ModuleLoader__.load({
16597
16592
  if (!result.ok) {
16598
16593
  pushToast("error", result.error !== void 0 && result.error !== "" ? result.error : tRef.current("ai.error"));
16599
16594
  }
16595
+ return result.ok;
16600
16596
  } catch (error) {
16601
16597
  reportError(error, "ai.error");
16598
+ return false;
16602
16599
  }
16603
16600
  },
16604
16601
  [selectedId, ai, ensureAiPaper, pushToast, reportError]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhe_xuan/dsh-paper-desk",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "PaperDesk: a Mendeley-style paper library for DeepSeek Harness — import PDFs, keep notes and highlights, ask the agent to explain papers, and sync the library folder through your cloud drive.",
5
5
  "type": "module",
6
6
  "license": "MIT",