@awiki/dsh-plugin 0.2.1 → 0.2.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 +2 -2
- package/README.zh.md +2 -2
- package/lib/client.js +67 -14
- package/lib/client.js.map +1 -1
- package/lib/types/client/AwikiOverlay.d.ts.map +1 -1
- package/lib/types/client/AwikiOverlay.js +27 -2
- package/lib/types/client/AwikiOverlay.js.map +1 -1
- package/lib/types/client/controller.d.ts +7 -0
- package/lib/types/client/controller.d.ts.map +1 -1
- package/lib/types/client/controller.js +42 -12
- package/lib/types/client/controller.js.map +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +1 -0
- package/lib/types/client/index.js.map +1 -1
- package/lib/types/client/slots.d.ts +2 -0
- package/lib/types/client/slots.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ TypeScript SDK `identity.json`; create a new Rust-backed identity after upgradin
|
|
|
19
19
|
- Register one deployment-level AWiki identity from the Web UI.
|
|
20
20
|
- Open the top-left AWiki account menu to sign out locally without deleting the encrypted identity or message database; **Resume** restores the same DID and Handle, including across DSH restarts.
|
|
21
21
|
- Reuse that identity across the root Agent and its subagents.
|
|
22
|
-
- Direct-message and existing-group conversation lists, unread counts, latest-message previews, and persisted display names. Opening a conversation keeps loading feedback inside the history and lands on the newest message; scrolling up reveals a latest-message control that counts newer arrivals without interrupting reading.
|
|
22
|
+
- Direct-message and existing-group conversation lists, unread counts, latest-message previews, and persisted display names. Opening a conversation keeps loading feedback inside the history and lands on the newest message; scrolling up reveals a latest-message control that counts newer arrivals without interrupting reading. A conversation is marked read only after its newest rendered message reaches the visible bottom.
|
|
23
23
|
- Text messages plus one attachment per message, with Enter-to-send, Shift+Enter line breaks, optimistic sending bubbles, image previews, and SHA verification.
|
|
24
24
|
- A draggable circular launcher, adaptive popup placement, dark mode, and remembered active conversation.
|
|
25
25
|
- User-triggered AI summaries for up to 50 recent or unread messages, kept only in runtime memory with explicit stale, retry, copy, and source-navigation states.
|
|
@@ -36,7 +36,7 @@ group administration, realtime push, or multiple attachments in one message.
|
|
|
36
36
|
Install the official public npm package:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
pnpm add @awiki/dsh-plugin@
|
|
39
|
+
pnpm add @awiki/dsh-plugin@latest
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
`@awiki/dsh-plugin` is the canonical package identity starting with
|
package/README.zh.md
CHANGED
|
@@ -13,7 +13,7 @@ Rust 身份。
|
|
|
13
13
|
- 在 Web UI 中注册一个部署级 AWiki 身份,根 Agent 与子 Agent 共用。
|
|
14
14
|
- 点击 AWiki 面板左上角图标可打开账户菜单;普通退出只锁定本机会话,不删除加密身份或消息数据库,重新进入及重启 DSH 后仍恢复同一个 DID 和 Handle。
|
|
15
15
|
- 注册失败时保留手机号、Handle、验证码和本机待注册密钥;注册未开放、验证码状态失效和提交冲突会给出对应的安全处理提示。
|
|
16
|
-
-
|
|
16
|
+
- 私聊和已有群聊列表、未读角标、最新消息预览、时间更新与昵称持久化。打开会话时在消息区内显示加载状态并落到最新消息;向上阅读时显示下滑箭头,新消息到达后在同一控件中累计数量且不打断阅读位置。只有最新一条已渲染消息到达可视区域底部后,当前会话才会自动标记为已读。
|
|
17
17
|
- 文本和单附件消息;Enter 发送、Shift+Enter 换行,发送中立即显示带 loading 动画的乐观气泡,并支持图片预览、附件说明与 SHA 校验。
|
|
18
18
|
- 圆形可拖动入口、自适应四角弹窗、深色模式和当前会话记忆。
|
|
19
19
|
- 用户点击后才生成的 AI 对话总结:最多处理 50 条最近或未读消息,按会话保留本次运行期缓存,并支持过期提示、重试、复制与跳转原消息。
|
|
@@ -29,7 +29,7 @@ Rust 身份。
|
|
|
29
29
|
安装公开发布的官方 npm 包:
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
pnpm add @awiki/dsh-plugin@
|
|
32
|
+
pnpm add @awiki/dsh-plugin@latest
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
从 `0.2.0-rc.4` 起,`@awiki/dsh-plugin` 是唯一规范包名。原
|
package/lib/client.js
CHANGED
|
@@ -5451,6 +5451,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5451
5451
|
generation = 0;
|
|
5452
5452
|
disposed = false;
|
|
5453
5453
|
polling = false;
|
|
5454
|
+
markReadInFlight = /* @__PURE__ */ new Map();
|
|
5454
5455
|
unreadAtOpen = /* @__PURE__ */ new Map();
|
|
5455
5456
|
summaryBaselines = /* @__PURE__ */ new Map();
|
|
5456
5457
|
/** @param remote - generated Host Remote namespace. */
|
|
@@ -5560,6 +5561,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5560
5561
|
if (this.timer !== void 0) clearInterval(this.timer);
|
|
5561
5562
|
this.timer = void 0;
|
|
5562
5563
|
this.polling = false;
|
|
5564
|
+
this.markReadInFlight.clear();
|
|
5563
5565
|
}
|
|
5564
5566
|
/**
|
|
5565
5567
|
* Request one phone verification challenge.
|
|
@@ -5716,24 +5718,51 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5716
5718
|
})
|
|
5717
5719
|
});
|
|
5718
5720
|
if (!loaded.ok) return loaded;
|
|
5719
|
-
|
|
5720
|
-
if (!marked.ok) return this.fail(marked.error);
|
|
5721
|
-
if (!this.current(generation) || this.view.selectedConversationId !== conversationId) return {
|
|
5721
|
+
return {
|
|
5722
5722
|
ok: true,
|
|
5723
5723
|
value: void 0
|
|
5724
5724
|
};
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5725
|
+
}
|
|
5726
|
+
/**
|
|
5727
|
+
* Mark the selected conversation read after the UI proves its newest message is visible.
|
|
5728
|
+
* Repeated scroll and layout notifications share one Host request, while a failed
|
|
5729
|
+
* background attempt keeps the unread badge so reaching the bottom can retry.
|
|
5730
|
+
*/
|
|
5731
|
+
async markSelectedConversationRead() {
|
|
5732
|
+
if (this.disposed) return {
|
|
5733
|
+
ok: false,
|
|
5734
|
+
error: "AWiki 插件已卸载"
|
|
5735
|
+
};
|
|
5736
|
+
const conversation = this.selectedConversation();
|
|
5737
|
+
if (conversation === void 0 || (conversation.unreadCount ?? 0) <= 0) return {
|
|
5734
5738
|
ok: true,
|
|
5735
5739
|
value: void 0
|
|
5736
5740
|
};
|
|
5741
|
+
const existing = this.markReadInFlight.get(conversation.id);
|
|
5742
|
+
if (existing !== void 0) return existing;
|
|
5743
|
+
const conversationId = conversation.id;
|
|
5744
|
+
const generation = this.generation;
|
|
5745
|
+
const operation = (async () => {
|
|
5746
|
+
const result = await call(() => this.remote.markConversationRead({ conversationId }));
|
|
5747
|
+
if (!result.ok) return result;
|
|
5748
|
+
if (this.current(generation)) this.publish({
|
|
5749
|
+
...this.view,
|
|
5750
|
+
conversations: this.view.conversations.map((current) => current.id === conversationId ? {
|
|
5751
|
+
...current,
|
|
5752
|
+
unreadCount: 0
|
|
5753
|
+
} : current)
|
|
5754
|
+
});
|
|
5755
|
+
return {
|
|
5756
|
+
ok: true,
|
|
5757
|
+
value: void 0
|
|
5758
|
+
};
|
|
5759
|
+
})();
|
|
5760
|
+
this.markReadInFlight.set(conversationId, operation);
|
|
5761
|
+
try {
|
|
5762
|
+
return await operation;
|
|
5763
|
+
} finally {
|
|
5764
|
+
if (this.markReadInFlight.get(conversationId) === operation) this.markReadInFlight.delete(conversationId);
|
|
5765
|
+
}
|
|
5737
5766
|
}
|
|
5738
5767
|
/**
|
|
5739
5768
|
* Load one older history page before the currently rendered messages.
|
|
@@ -6991,6 +7020,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6991
7020
|
const summaryPanelId = (0, react.useId)();
|
|
6992
7021
|
selectedConversationId.current = view.selectedConversationId;
|
|
6993
7022
|
const visibleSendingDraft = sendingDraft?.conversationId === view.selectedConversationId ? sendingDraft : null;
|
|
7023
|
+
const markSelectedConversationReadAtBottom = () => {
|
|
7024
|
+
const node = history.current;
|
|
7025
|
+
const newestRendered = view.messages.at(-1);
|
|
7026
|
+
if (node === null || selected === void 0 || newestRendered === void 0 || (selected.unreadCount ?? 0) <= 0 || view.pending === "加载消息" || selected.lastMessageAt !== void 0 && newestRendered.sentAt < selected.lastMessageAt || node.scrollHeight - node.scrollTop - node.clientHeight > HISTORY_BOTTOM_THRESHOLD) return;
|
|
7027
|
+
props.markSelectedConversationRead();
|
|
7028
|
+
};
|
|
6994
7029
|
const scrollHistoryToLatest = (smooth) => {
|
|
6995
7030
|
const node = history.current;
|
|
6996
7031
|
if (node === null) return;
|
|
@@ -7003,6 +7038,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7003
7038
|
historyPinnedToBottom.current = true;
|
|
7004
7039
|
setHistoryAwayFromBottom(false);
|
|
7005
7040
|
setUnseenMessageCount(0);
|
|
7041
|
+
if (!smooth || reduceMotion || typeof node.scrollTo !== "function") markSelectedConversationReadAtBottom();
|
|
7006
7042
|
};
|
|
7007
7043
|
const syncHistoryPosition = () => {
|
|
7008
7044
|
const node = history.current;
|
|
@@ -7010,8 +7046,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7010
7046
|
const atBottom = node.scrollHeight - node.scrollTop - node.clientHeight <= HISTORY_BOTTOM_THRESHOLD;
|
|
7011
7047
|
historyPinnedToBottom.current = atBottom;
|
|
7012
7048
|
setHistoryAwayFromBottom(!atBottom);
|
|
7013
|
-
if (atBottom)
|
|
7049
|
+
if (atBottom) {
|
|
7050
|
+
setUnseenMessageCount(0);
|
|
7051
|
+
markSelectedConversationReadAtBottom();
|
|
7052
|
+
}
|
|
7014
7053
|
};
|
|
7054
|
+
(0, react.useLayoutEffect)(() => {
|
|
7055
|
+
markSelectedConversationReadAtBottom();
|
|
7056
|
+
}, [
|
|
7057
|
+
selected?.id,
|
|
7058
|
+
selected?.lastMessageAt,
|
|
7059
|
+
selected?.unreadCount,
|
|
7060
|
+
view.messages,
|
|
7061
|
+
view.pending
|
|
7062
|
+
]);
|
|
7015
7063
|
(0, react.useLayoutEffect)(() => {
|
|
7016
7064
|
const conversationId = view.selectedConversationId;
|
|
7017
7065
|
if (conversationId !== previousConversationId.current) {
|
|
@@ -7036,7 +7084,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7036
7084
|
messageId: view.messages.at(-1)?.id ?? null
|
|
7037
7085
|
};
|
|
7038
7086
|
scrollHistoryToLatest(false);
|
|
7039
|
-
if (pendingInitialImages.current.size === 0)
|
|
7087
|
+
if (pendingInitialImages.current.size === 0) {
|
|
7088
|
+
conversationAwaitingBottom.current = null;
|
|
7089
|
+
markSelectedConversationReadAtBottom();
|
|
7090
|
+
}
|
|
7040
7091
|
return;
|
|
7041
7092
|
}
|
|
7042
7093
|
const previous = previousMessageTail.current;
|
|
@@ -7067,6 +7118,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
7067
7118
|
if (!pendingInitialImages.current.delete(messageId)) return;
|
|
7068
7119
|
if (history.current !== null) scrollHistoryToLatest(false);
|
|
7069
7120
|
if (pendingInitialImages.current.size === 0) conversationAwaitingBottom.current = null;
|
|
7121
|
+
if (pendingInitialImages.current.size === 0) markSelectedConversationReadAtBottom();
|
|
7070
7122
|
};
|
|
7071
7123
|
const viewSummarySource = (messageId) => {
|
|
7072
7124
|
if (selected === void 0) return;
|
|
@@ -8522,6 +8574,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
8522
8574
|
loadMoreConversations: () => controller.loadMoreConversations(),
|
|
8523
8575
|
startDirectChat: (handle) => controller.startDirectChat(handle),
|
|
8524
8576
|
selectConversation: (conversationId) => controller.selectConversation(conversationId),
|
|
8577
|
+
markSelectedConversationRead: () => controller.markSelectedConversationRead(),
|
|
8525
8578
|
loadOlderHistory: () => controller.loadOlderHistory(),
|
|
8526
8579
|
summarizeConversation: () => controller.summarizeConversation(),
|
|
8527
8580
|
setSummaryCollapsed: (conversationId, collapsed) => {
|