@senguoyun/dsh-arkme 0.1.42 → 0.1.44

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.
Files changed (194) hide show
  1. package/docs/avatar-diagnostics.md +36 -0
  2. package/docs/consumer-plugin-contract.md +18 -1
  3. package/docs/emoji-presentation.md +54 -0
  4. package/docs/member-event-cache.md +49 -0
  5. package/docs/resizable-composer-verification.md +45 -0
  6. package/docs/resizable-note-detail-verification.md +41 -0
  7. package/lib/client.js +146175 -88561
  8. package/lib/client.js.map +1 -1
  9. package/lib/index.js +998 -41
  10. package/lib/persistent-extension.js +1 -1
  11. package/lib/{persistent-runtime-LJ4nj7os.js → persistent-runtime-CEGGFpR7.js} +24478 -3867
  12. package/lib/sdk.js +27 -0
  13. package/lib/types/arkme-emoji-text.d.ts +26 -0
  14. package/lib/types/arkme-emoji-text.d.ts.map +1 -0
  15. package/lib/types/arkme-service.d.ts +37 -2
  16. package/lib/types/arkme-service.d.ts.map +1 -1
  17. package/lib/types/avatar-diagnostics.d.ts +20 -0
  18. package/lib/types/avatar-diagnostics.d.ts.map +1 -0
  19. package/lib/types/chat-realtime.d.ts +27 -0
  20. package/lib/types/chat-realtime.d.ts.map +1 -1
  21. package/lib/types/client/ArkmeAppUpdateDialog.d.ts.map +1 -1
  22. package/lib/types/client/ArkmeCalendarSurface.d.ts.map +1 -1
  23. package/lib/types/client/ArkmeLongArticleDialog.d.ts.map +1 -1
  24. package/lib/types/client/ArkmeMarkdownBody.d.ts +11 -0
  25. package/lib/types/client/ArkmeMarkdownBody.d.ts.map +1 -0
  26. package/lib/types/client/ArkmeMarkdownComposerInput.d.ts +10 -0
  27. package/lib/types/client/ArkmeMarkdownComposerInput.d.ts.map +1 -0
  28. package/lib/types/client/ArkmeMemberEventProfile.d.ts +10 -0
  29. package/lib/types/client/ArkmeMemberEventProfile.d.ts.map +1 -0
  30. package/lib/types/client/ArkmeMessagePreparingIndicator.d.ts +6 -0
  31. package/lib/types/client/ArkmeMessagePreparingIndicator.d.ts.map +1 -0
  32. package/lib/types/client/ArkmeNoteDetails.d.ts.map +1 -1
  33. package/lib/types/client/ArkmeRecordingSurface.d.ts +7 -3
  34. package/lib/types/client/ArkmeRecordingSurface.d.ts.map +1 -1
  35. package/lib/types/client/ArkmeRelatedQuickNotes.d.ts.map +1 -1
  36. package/lib/types/client/ArkmeRichComposerInput.d.ts +6 -1
  37. package/lib/types/client/ArkmeRichComposerInput.d.ts.map +1 -1
  38. package/lib/types/client/ArkmeRichContent.d.ts.map +1 -1
  39. package/lib/types/client/ArkmeRichText.d.ts +7 -3
  40. package/lib/types/client/ArkmeRichText.d.ts.map +1 -1
  41. package/lib/types/client/ArkmeSettingsSurface.d.ts +3 -3
  42. package/lib/types/client/ArkmeSettingsSurface.d.ts.map +1 -1
  43. package/lib/types/client/ArkmeSidebar.d.ts +7 -0
  44. package/lib/types/client/ArkmeSidebar.d.ts.map +1 -1
  45. package/lib/types/client/ArkmeUpdateSurfaces.d.ts +2 -1
  46. package/lib/types/client/ArkmeUpdateSurfaces.d.ts.map +1 -1
  47. package/lib/types/client/ArkmeWorldSurface.d.ts.map +1 -1
  48. package/lib/types/client/api.d.ts +10 -2
  49. package/lib/types/client/api.d.ts.map +1 -1
  50. package/lib/types/client/app-update-store.d.ts +8 -1
  51. package/lib/types/client/app-update-store.d.ts.map +1 -1
  52. package/lib/types/client/arkme-emoji.d.ts +3 -12
  53. package/lib/types/client/arkme-emoji.d.ts.map +1 -1
  54. package/lib/types/client/arkme-theme.d.ts +1 -0
  55. package/lib/types/client/arkme-theme.d.ts.map +1 -1
  56. package/lib/types/client/avatar-image-runtime.d.ts.map +1 -1
  57. package/lib/types/client/avatar-image-store.d.ts +8 -0
  58. package/lib/types/client/avatar-image-store.d.ts.map +1 -1
  59. package/lib/types/client/composer-draft-store.d.ts +4 -0
  60. package/lib/types/client/composer-draft-store.d.ts.map +1 -1
  61. package/lib/types/client/conversation-resize-anchor.d.ts +12 -0
  62. package/lib/types/client/conversation-resize-anchor.d.ts.map +1 -0
  63. package/lib/types/client/interwoven-moments.d.ts +7 -2
  64. package/lib/types/client/interwoven-moments.d.ts.map +1 -1
  65. package/lib/types/client/markdown-editor.d.ts +28 -0
  66. package/lib/types/client/markdown-editor.d.ts.map +1 -0
  67. package/lib/types/client/member-event-cache.d.ts +24 -0
  68. package/lib/types/client/member-event-cache.d.ts.map +1 -0
  69. package/lib/types/client/member-event-hints.d.ts +11 -0
  70. package/lib/types/client/member-event-hints.d.ts.map +1 -0
  71. package/lib/types/client/member-event-timeline.d.ts +60 -0
  72. package/lib/types/client/member-event-timeline.d.ts.map +1 -0
  73. package/lib/types/client/message-preparing-reporter.d.ts +41 -0
  74. package/lib/types/client/message-preparing-reporter.d.ts.map +1 -0
  75. package/lib/types/client/message-preparing-store.d.ts +29 -0
  76. package/lib/types/client/message-preparing-store.d.ts.map +1 -0
  77. package/lib/types/client/realtime-client-events.d.ts +3 -1
  78. package/lib/types/client/realtime-client-events.d.ts.map +1 -1
  79. package/lib/types/client/recordings/ArkmeRecordingImportDialog.d.ts.map +1 -1
  80. package/lib/types/client/recordings/ArkmeRecordingTimeline.d.ts +2 -1
  81. package/lib/types/client/recordings/ArkmeRecordingTimeline.d.ts.map +1 -1
  82. package/lib/types/client/recordings/RecordingDesktopIcon.d.ts +19 -0
  83. package/lib/types/client/recordings/RecordingDesktopIcon.d.ts.map +1 -0
  84. package/lib/types/client/recordings/RecordingTranscriptButton.d.ts +3 -0
  85. package/lib/types/client/recordings/RecordingTranscriptButton.d.ts.map +1 -0
  86. package/lib/types/client/recordings/RecordingTranscriptComparison.d.ts +8 -0
  87. package/lib/types/client/recordings/RecordingTranscriptComparison.d.ts.map +1 -0
  88. package/lib/types/client/recordings/RecordingTranscriptForward.d.ts +8 -0
  89. package/lib/types/client/recordings/RecordingTranscriptForward.d.ts.map +1 -0
  90. package/lib/types/client/recordings/RecordingTranscriptSearch.d.ts +10 -0
  91. package/lib/types/client/recordings/RecordingTranscriptSearch.d.ts.map +1 -0
  92. package/lib/types/client/recordings/RecordingTranscriptText.d.ts +9 -0
  93. package/lib/types/client/recordings/RecordingTranscriptText.d.ts.map +1 -0
  94. package/lib/types/client/recordings/prepare-recording-transcript-comparison.d.ts +9 -0
  95. package/lib/types/client/recordings/prepare-recording-transcript-comparison.d.ts.map +1 -0
  96. package/lib/types/client/recordings/recording-forward-attempt.d.ts +18 -0
  97. package/lib/types/client/recordings/recording-forward-attempt.d.ts.map +1 -0
  98. package/lib/types/client/recordings/recording-forward-client.d.ts +5 -0
  99. package/lib/types/client/recordings/recording-forward-client.d.ts.map +1 -0
  100. package/lib/types/client/recordings/recording-transcript-comparison.d.ts +3 -0
  101. package/lib/types/client/recordings/recording-transcript-comparison.d.ts.map +1 -0
  102. package/lib/types/client/recordings/recording-transcript-search.d.ts +11 -0
  103. package/lib/types/client/recordings/recording-transcript-search.d.ts.map +1 -0
  104. package/lib/types/client/recordings/useRecordingPlayback.d.ts +4 -0
  105. package/lib/types/client/recordings/useRecordingPlayback.d.ts.map +1 -1
  106. package/lib/types/client/redesign/contacts/AlphabeticalContactList.d.ts.map +1 -1
  107. package/lib/types/client/redesign/contacts/ContactDirectorySurface.d.ts.map +1 -1
  108. package/lib/types/client/redesign/contacts/DirectoryDetailPane.d.ts.map +1 -1
  109. package/lib/types/client/redesign/contacts/TeamDetailPane.d.ts +5 -0
  110. package/lib/types/client/redesign/contacts/TeamDetailPane.d.ts.map +1 -0
  111. package/lib/types/client/redesign/contacts/contact-directory-state.d.ts +3 -0
  112. package/lib/types/client/redesign/contacts/contact-directory-state.d.ts.map +1 -1
  113. package/lib/types/client/redesign/contacts/contacts-tab-store.d.ts.map +1 -1
  114. package/lib/types/client/use-member-event-timeline.d.ts +31 -0
  115. package/lib/types/client/use-member-event-timeline.d.ts.map +1 -0
  116. package/lib/types/client/use-message-preparing.d.ts +14 -0
  117. package/lib/types/client/use-message-preparing.d.ts.map +1 -0
  118. package/lib/types/client/use-resizable-composer.d.ts +18 -0
  119. package/lib/types/client/use-resizable-composer.d.ts.map +1 -0
  120. package/lib/types/client/use-resizable-note-detail.d.ts +17 -0
  121. package/lib/types/client/use-resizable-note-detail.d.ts.map +1 -0
  122. package/lib/types/hashtag.d.ts +1 -1
  123. package/lib/types/hashtag.d.ts.map +1 -1
  124. package/lib/types/host-api.d.ts +3 -1
  125. package/lib/types/host-api.d.ts.map +1 -1
  126. package/lib/types/index.d.ts +1 -0
  127. package/lib/types/index.d.ts.map +1 -1
  128. package/lib/types/local-database.d.ts +4 -1
  129. package/lib/types/local-database.d.ts.map +1 -1
  130. package/lib/types/markdown.d.ts +43 -0
  131. package/lib/types/markdown.d.ts.map +1 -0
  132. package/lib/types/openapi-capability-gateway.d.ts +78 -0
  133. package/lib/types/openapi-capability-gateway.d.ts.map +1 -0
  134. package/lib/types/openapi-mcp/controller.d.ts +14 -7
  135. package/lib/types/openapi-mcp/controller.d.ts.map +1 -1
  136. package/lib/types/openapi-mcp/execution-fence.d.ts.map +1 -1
  137. package/lib/types/openapi-mcp/types.d.ts +20 -0
  138. package/lib/types/openapi-mcp/types.d.ts.map +1 -1
  139. package/lib/types/record-reedit-contract.d.ts +66 -0
  140. package/lib/types/record-reedit-contract.d.ts.map +1 -0
  141. package/lib/types/recording-forward-contract.d.ts +30 -0
  142. package/lib/types/recording-forward-contract.d.ts.map +1 -0
  143. package/lib/types/recording-forward-presentation.d.ts +6 -0
  144. package/lib/types/recording-forward-presentation.d.ts.map +1 -0
  145. package/lib/types/recording-import-contract.d.ts +3 -4
  146. package/lib/types/recording-import-contract.d.ts.map +1 -1
  147. package/lib/types/recording-import-shared.d.ts +19 -13
  148. package/lib/types/recording-import-shared.d.ts.map +1 -1
  149. package/lib/types/recording-presentation.d.ts +21 -5
  150. package/lib/types/recording-presentation.d.ts.map +1 -1
  151. package/lib/types/sdk/index.d.ts +20 -2
  152. package/lib/types/sdk/index.d.ts.map +1 -1
  153. package/lib/types/services/calendar-service.d.ts.map +1 -1
  154. package/lib/types/services/chat-realtime-service.d.ts +22 -0
  155. package/lib/types/services/chat-realtime-service.d.ts.map +1 -1
  156. package/lib/types/services/chat-service.d.ts +11 -1
  157. package/lib/types/services/chat-service.d.ts.map +1 -1
  158. package/lib/types/services/contact-directory-service.d.ts +0 -2
  159. package/lib/types/services/contact-directory-service.d.ts.map +1 -1
  160. package/lib/types/services/media-service.d.ts.map +1 -1
  161. package/lib/types/services/member-event-service.d.ts +25 -0
  162. package/lib/types/services/member-event-service.d.ts.map +1 -0
  163. package/lib/types/services/message-action-infrastructure.d.ts.map +1 -1
  164. package/lib/types/services/profile-service.d.ts +5 -0
  165. package/lib/types/services/profile-service.d.ts.map +1 -1
  166. package/lib/types/services/record-service.d.ts +17 -2
  167. package/lib/types/services/record-service.d.ts.map +1 -1
  168. package/lib/types/services/recording-forward-gateway.d.ts +19 -0
  169. package/lib/types/services/recording-forward-gateway.d.ts.map +1 -0
  170. package/lib/types/services/recording-import-gateway.d.ts.map +1 -1
  171. package/lib/types/services/recording-service.d.ts +18 -1
  172. package/lib/types/services/recording-service.d.ts.map +1 -1
  173. package/lib/types/services/related-quick-note-service.d.ts.map +1 -1
  174. package/lib/types/services/service.d.ts +12 -4
  175. package/lib/types/services/service.d.ts.map +1 -1
  176. package/lib/types/services/source-service.d.ts +5 -0
  177. package/lib/types/services/source-service.d.ts.map +1 -1
  178. package/lib/types/services/team-service.d.ts +55 -0
  179. package/lib/types/services/team-service.d.ts.map +1 -0
  180. package/lib/types/state-store.d.ts +4 -1
  181. package/lib/types/state-store.d.ts.map +1 -1
  182. package/lib/types/tools/business/index.d.ts.map +1 -1
  183. package/lib/types/tools/business/records/index.d.ts.map +1 -1
  184. package/lib/types/tools/business/records/reedit.d.ts +2 -0
  185. package/lib/types/tools/business/records/reedit.d.ts.map +1 -0
  186. package/lib/types/tools/ports/records.d.ts +5 -0
  187. package/lib/types/tools/ports/records.d.ts.map +1 -1
  188. package/lib/types/tools/prompts/business.d.ts.map +1 -1
  189. package/lib/types/tools/registry/registrar.d.ts.map +1 -1
  190. package/lib/types/tools/shared/conversational-confirmation.d.ts +2 -1
  191. package/lib/types/tools/shared/conversational-confirmation.d.ts.map +1 -1
  192. package/lib/types/types.d.ts +209 -7
  193. package/lib/types/types.d.ts.map +1 -1
  194. package/package.json +22 -6
@@ -0,0 +1,36 @@
1
+ # 头像失败诊断日志
2
+
3
+ 诊断标记:`[ArkmeAvatarDiag]`。仅追加失败日志,不修改头像展示、缓存、并发限制或重试策略。
4
+ 需要发布包含本改动的插件后才生效;不自动修改本机已安装包。
5
+
6
+ ## 下次复现时
7
+
8
+ 先保留日志、记录发生时间和目标用户,再重启客户端,避免丢失故障现场。
9
+ macOS 生产版日志位于 `~/Library/Application Support/Arkme Harness/`:
10
+
11
+ - `logs/desktop-startup.log`:Browser 头像加载失败,由桌面壳捕获 renderer console。
12
+ - `logs/harness.log`:Host 资料请求、头像引用和图片读取失败。
13
+ - 账号隔离实例的 Host 日志可能位于 `dsh-containers/<scope>/logs/harness.log`,具体以启动日志中的实例路径为准。
14
+
15
+ 先筛选 `[ArkmeAvatarDiag]`,再按发生时间、`viewerUserId` 和 `targetUserId` / `referenceTargetUserId` 对账。
16
+ 例如 1D3E 的目标用户 ID 是 `21698`。批量资料失败的目标位于 `targetUserIds`。
17
+
18
+ | event | 含义 |
19
+ | --- | --- |
20
+ | `profile_fetch_failed` | 批量资料请求失败,尚未生成头像引用 |
21
+ | `profile_missing` | 成功响应漏掉了请求的用户资料 |
22
+ | `profile_avatar_rejected` | 非空头像值被地址安全校验拒绝 |
23
+ | `private_avatar_seal_failed` | 私聊头像引用生成失败 |
24
+ | `image_read_failed` | Host 最终无法读取用户头像 |
25
+ | `image_load_failed` | Browser 头像共享缓存收到加载失败 |
26
+
27
+ `trigger=load` 表示普通加载,`revalidate` 表示重验证;不代表新增重试。
28
+ `hasCachedImage=false` 表示这次失败没有旧图片可保留,可能显示默认头像。
29
+ `durationMillis` 包含排队时间。`httpStatus` 是 Host 错误状态,`upstreamStatus`(存在时)是底层服务或图片下载的 HTTP 状态。
30
+ 引用中的 `referenceViewerUserId` / `referenceTargetUserId` 只是解析出的诊断提示,不参与授权校验。
31
+
32
+ 日志以单行 JSON 输出,避免桌面桥接把字段变成 `[object Object]`。不记录原始头像引用、签名 URL、图片内容、昵称、token、错误全文或堆栈。
33
+ 正常图片加载、未设置头像及合法 phone_avatar 默认头像不记录错误;共享并发读取只记一次,旧账号请求在切换后的预期取消不记 Browser 错误。
34
+
35
+ 已确认的恢复慢机制仍保持原样:首次加载失败后,相同引用的普通渲染不触发重试;周期维护约 10–12 分钟。
36
+ 本次日志用于确认真实复现的首次失败阶段,不预先认定为超时或鉴权问题。
@@ -77,6 +77,23 @@ if ((await arkme.capabilities()).features.extensionPreviews === true && userConf
77
77
 
78
78
  The SDK communicates only with the same-origin Provider route. Consumers must not read OS credential-store entries, SQLite files, state files, or tokens directly.
79
79
 
80
+ ## Team capability
81
+
82
+ `capabilities().features.teamDirectory`, `teamMembers`, and `teamGovernance` advertise the complete Team contract. Consumers call `listTeams()` or `resolveTeams()` to obtain an opaque, account-scoped `teamRef`, then pass that reference unchanged to `listTeamMembers()`. A display name or public Jotmo ID must never be substituted for `teamRef`; member `userRef` and Team `teamRef` are distinct reference types and are not interchangeable.
83
+
84
+ `createTeams()` requires one stable idempotency key per item. `joinTeamsByJotmoID()` accepts only the exact public Team Jotmo ID and reports whether the current account is the owner, was already a member, or joined now. Both mutations must originate from a current same-origin human UI action. Consumers must not receive, persist, or reconstruct the managed OpenAPI credential, backend numeric IDs, owner request IDs, or internal cursors.
85
+
86
+ Member identity is an enrichment owned outside Team membership. `identityState=unavailable` or `incomplete` keeps the authoritative membership row visible while telling the Consumer not to invent a display identity. A member may include a Host-resolved `avatarRef` or `avatarFallback`; avatar enrichment failure never removes the authoritative membership row. Consumers discard Team pages and cursors on account change, propagate `AbortSignal`, and retry from a fresh list after an authorization or lifecycle error.
87
+
88
+ | Capability | Built-in UI | Browser SDK | DSH model Tool | Shared owner |
89
+ | --- | --- | --- | --- | --- |
90
+ | List/resolve my Teams | Contacts → Team directory | `listTeams()`, `resolveTeams()` | `list_my_teams`, `resolve_my_teams` | OpenAPI Team capability registry → Team query owner |
91
+ | List Team members | Team detail with loading, partial identity, pagination and retry states | `listTeamMembers()` | `list_team_members` | OpenAPI Team capability registry → Team membership owner + public identity batch reader |
92
+ | Create Team | No built-in entry | `createTeams()` from a confirmed same-origin UI | `create_teams` after explicit user intent | OpenAPI Team capability registry → existing Team create command |
93
+ | Join by public ID | No built-in entry | `joinTeamsByJotmoID()` from a confirmed same-origin UI | `join_teams_by_jotmo_id` after explicit user intent | OpenAPI Team capability registry → existing Team join command |
94
+
95
+ The built-in UI and Browser SDK enter through the same injected `TeamServicePort`; model Tools use the OpenAPI MCP projection of the same capability definitions. REST and MCP therefore share one authorization, validation, idempotency, cursor, error, and result contract without routing model traffic through the browser Host.
96
+
80
97
  `capabilities().features.myExtensions` advertises the current-account extension inventory. `myExtensions()` merges only Host-approved live Cordis, Profile-resolved and cloud-owned facts; consumers must use its states and `publish` result without rescanning Profile files or inferring ownership from names. Every publishable item carries one Host-derived route: `dynamic-cordis-v2` means `artifactContractVersion=2` and `artifactKind=dsh-bundle-tgz` for a live current-session Dynamic Cordis Package; `profile-native-v3` means `artifactContractVersion=3` and `artifactKind=dsh-native-package-tgz` for an installed or Profile-local DSH Bundle. Callers pass `ownedRef` unchanged and never choose a mode themselves. A GitHub repository URL is optional provenance metadata, not a third upload route, publication credential or cloud clone/build request. A third-party registry/Git dependency appears only when its actually resolved package declares `dsh.bundle.patch`; it is a V3 publication candidate rather than an assertion that the current account authored the upstream code. `publisher_role` is server-owned: explicit values win, while historical rows without a role resolve to importer only when they have GitHub provenance. Consumers never submit this role. `ownedRef` is short-lived and account-bound. `publishMyExtension()` requires a current explicit human request and can publish only the exact Cordis Package, resolved Bundle directory or local Bundle tgz behind that ref; consumers must refresh the list after expiry or account switch. Profile paths, Agent IDs, source archives, artifact upload requests and signing material never enter this contract.
81
98
 
82
99
  Plugin update discovery and acknowledgement are lifecycle concerns owned by the bundled Arkme UI. They are intentionally absent from the public Browser SDK, Host `arkmeData` service and model tool catalog. Consumers must not invoke raw `plugin.update.*` operations or attempt to mutate a DSH profile.
@@ -129,7 +146,7 @@ Interaction flow:
129
146
  点击微信 -> 显示 Flutter AppBridge OAuth 缺失说明,不发起伪请求
130
147
  ```
131
148
 
132
- `readImage(avatarRef)` resolves an opaque image reference returned by `profile()` or `listSources()`. Private chats expose one optional `avatarRef`. Groups expose the preferred additive `groupAvatar` presentation plus legacy `avatarRefs`: `groupAvatar.slots` preserves the server-selected order for up to five members, including safe phone-default or generic fallbacks when a real image is absent, while legacy `avatarRefs` contains only resolvable real images. `memberCount`, `strategy`, and `computedAtMillis` describe the snapshot without exposing member or session identities. The Provider refreshes an authorized public profile image before downloading it and returns bounded PNG/JPEG/WebP/GIF base64 bytes; signed URLs, STS credentials and bearer tokens never enter the browser contract. Consumers must use `imageDataUrl()` (or decode the payload themselves) instead of concatenating OSS URLs or fetching an avatar reference directly.
149
+ `readImage(avatarRef)` resolves an opaque image reference returned by `profile()`, `listSources()` or `listTeamMembers()`. Private chats and Team members expose one optional `avatarRef`. Groups expose the preferred additive `groupAvatar` presentation plus legacy `avatarRefs`: `groupAvatar.slots` preserves the server-selected order for up to five members, including safe phone-default or generic fallbacks when a real image is absent, while legacy `avatarRefs` contains only resolvable real images. `memberCount`, `strategy`, and `computedAtMillis` describe the snapshot without exposing member or session identities. The Provider refreshes an authorized public profile image before downloading it and returns bounded PNG/JPEG/WebP/GIF base64 bytes; signed URLs, STS credentials and bearer tokens never enter the browser contract. Consumers must use `imageDataUrl()` (or decode the payload themselves) instead of concatenating OSS URLs or fetching an avatar reference directly.
133
150
 
134
151
  `capabilities().features.worldFeed === true` advertises the additive World read contract. `worldFeed()` returns account-bound opaque `recordRef`, `avatarRef`, and `imageRefs` values; it never exposes stable record IDs, bearer tokens, `file_asset://` references, or signed OSS URLs. File-asset avatars are batch-resolved by the Provider. Resolution failure is best-effort and must keep the feed readable with its declared fallback avatar.
135
152
 
@@ -0,0 +1,54 @@
1
+ # 表情展示合同
2
+
3
+ 原始正文继续保存 jm_emoji / im_emoji token、Unicode 和既有媒体引用,不把展示转换写回正文。
4
+ 插件的 arkme-emoji-text 持有无资源依赖的表情目录、解析和安全截断;Browser 只关联内嵌 SVG。
5
+
6
+ - 应用内用户内容经 ArkmeRichText;先识别完整 URL,再解析普通文本中的表情。正文保留原有链接行为,preview 只展示,不发起链接标题请求或产生交互元素。
7
+ - 纯文本出口经 arkmeEmojiPlainText;未知编码原样保留。图片表情包继续走 contentBlocks 媒体链,不从文字猜测。
8
+ - 视觉省略用 CSS;响应限长保护完整 token 和 Unicode 字素簇,并保留原有长度预算与截断标记。
9
+ - 编辑器保留自己的光标、mention 和草稿模型,共享目录与序列化规则。
10
+ - SVG 失败退化为可读 Unicode;图片提供语义名称。单个富文本块内含表情图片的复制选区转为 Unicode,同时保留 HTML 中的链接与格式;不含表情或跨块的选区保留浏览器原生复制。不得为每条文本新增网络请求、缓存或订阅。
11
+
12
+ ## 能力与验收范围
13
+
14
+ | 消费面 / owner | 本次范围 | 验证 |
15
+ | --- | --- | --- |
16
+ | UI | 日历、时间轴与详情抽屉的延展父引用、相关快记、转发选择弹窗与转发详情、录音/长文卡片及已有 Unicode 展示入口 | 同一组 token、组合表情和混合内容贯穿实际组件;预览无请求/额外交互;失败与复制 |
17
+ | Host | 既有内容投影使用共享安全截断,不改权限、查询或持久化合同 | 日历、相关快记、消息签名快照与两类转发快照的内容完整性测试 |
18
+ | Tools / SDK | 不新增能力,继续消费同一 Host;不复制转换逻辑 | 现有日历和相关快记入口兼容测试 |
19
+ | Client / Harness | 无原生桥或装配协议变化 | 独立制品安装、隔离页面验收;已安装客户端和生产发布不在本次授权内 |
20
+
21
+ 开发基线:插件 official/dev e7563b9e5fa84284032aeb0c7cd3a7020e1e0c44;提交 PR 前已合入最新 dev a055b4b15647741647c07acb368e68f958a74492 的 Markdown 合同。
22
+ 客户端只读参考 master 02f86d21dc3c2c94b01c4cd0e1f5f4bdda6bdeae。
23
+ 性能边界:解析工作随本次文本长度增长,不持有跨内容缓存;预览不新增 I/O。
24
+
25
+ ## 本次验证
26
+
27
+ - 原始基线相关测试 203 项通过;修改后 typecheck、build 和制品清单检查通过。
28
+ - 最新基线集成后全量:4024 项通过、5 项跳过、16 项失败。16 项失败全部在未修改的 dev/a055b4b 对应测试中逐项复现,失败集合完全一致;涉及 Markdown 基线的旧 UI/Host 参数断言、identity 与 service-architecture 清单。没有新增失败。
29
+ - 官方 DSH 0.1.1-rc.2(源码参考标签 dsh-v0.1.1-rc.2,b150a551)通过 plugin CLI 安装独立 tgz;使用带空格的全新 DSH_HOME 和独立凭据命名空间。最终安装的 client.js 与构建输出摘要一致。
30
+ - Chromium 实际页面使用浏览器路由固定样例,不使用真实账号:日历、时间轴父引用、详情父引用和相关快记均成功加载两种 token 对应的 SVG;未知 token 与 Unicode 保留,预览没有链接节点或链接元数据请求。
31
+ - 实际复制快捷键产生 Unicode 文本;验证监听器阻止写入系统剪贴板。模拟缺失图片资源后成功退化为 Unicode。
32
+ - 最终制品 SHA-256:bbad76d87ceb19e6e306e07c00ccea80a6811686c0758c91c4a5dcea1c73ef7b,版本保持 0.1.43。制品不含测试、node_modules、本机路径或验收端口。
33
+ - 上述是隔离 DSH Browser 页面验收,不等同于真实账号的远端数据验收、已安装 Electron 客户端替换或 Windows/Linux 验收;未发布或提交 PR。性能只验证无新增预览请求,不声称测得吞吐或帧率提升。
34
+
35
+ ## 深入审查与修复
36
+
37
+ | 问题 | 修复及证据 |
38
+ | --- | --- |
39
+ | P2:转发对象弹窗的最近消息与底部摘要绕过公共渲染 | 统一使用 preview 模式;实际弹窗加载 4 个表情图片,无链接节点;选择对象、填写附言、发送一次并关闭弹窗均验证通过,提交保留 actionRefs 与原始附言 token |
40
+ | P2:表情优先解析会拆开 URL 参数 | 由已有链接解析器先确定 URL 边界,再将普通文本交给唯一表情解析器;body/preview 都覆盖含 token 的完整 URL |
41
+ | P2:普通选区复制被无条件接管,含链接选区只留下纯文本 | 仅转换选区内的已知表情图片;保留 text/html 的原始 href;真实复制快捷键验证普通选区不接管、表情转 Unicode、链接不丢失,测试阻止写入系统剪贴板 |
42
+ | P2:历史转发摘要用冒号猜作者,破坏 token、URL 和时间 | 摘要整体作为内容显示;作者只从结构化字段取得。摘要-only 记录显示通用摘要标签,复现样例均通过 |
43
+ | P2:消息操作签名快照、普通记录/Agent 转发快照会写入半个 token | 使用共享安全截断并保留原有预算;公共读取→签名引用→转发写入测试与 Agent 网关测试证明原始正文保留,写入摘要不含半个 token |
44
+ | 清理:Browser 有重复解析包装和松散的 run 类型;目录继承 Object 原型 | 删除包装层,直接消费无资源依赖的判别联合类型;Browser 目录不再将 constructor / __proto__ 视为表情 |
45
+
46
+ 架构边界:表情目录与文本语义归插件公共层,SVG 和复制归 Browser;聊天关系、普通记录和 Agent 的来源身份、授权、幂等仍由原 owner 持有。仅共用无副作用的文本函数,不合并不同消息协议,不转换持久化原始正文。
47
+
48
+ 没有新增状态机、计时器、订阅、缓存或数据库字段。图片组件仅保留当前资源是否加载失败的局部状态;没有新增兼容开关、双轨解析或过渡协议。jm_emoji / im_emoji 和摘要-only 读取属于既有历史数据合同。未修改提示词、版本字段或根 README。
49
+
50
+ 表情修复快照已通过官方 CLI 装入独立 Profile,并在 Electron 验收客户端加载(代码摘要一致);转发弹窗和历史详情完成了固定业务样例的真实页面复验。最新 Markdown 基线的集成完成单测、类型检查与打包,尚未重新进行真机账号验收。
51
+
52
+ 输入区目标预览追加验收:延展与重新编辑共用的目标摘要已接入 preview 模式,102 项相关测试、typecheck 与 build 通过;原稿、重新编辑草稿及延展提交引用均保持原始数据。
53
+
54
+ Markdown 集成:保留 text_format、代码块与业务标签的 AST 边界,只对普通正文文本渲染表情;新增复合样例验证正文渲染、行内/块级代码保留原文、URL 参数值不变。
@@ -0,0 +1,49 @@
1
+ # 群成员变动记录的临时缓存
2
+
3
+ 退群记录使用插件客户端的共享内存缓存,不引入 SWR,不写本地磁盘或后端存储。
4
+ 缓存按登录环境、账号和群的 opaque source key 隔离;目前事件类型固定为 `left`。
5
+
6
+ ## 请求规则
7
+
8
+ - 第一次进入群聊:等待快记窗口和群主身份就绪,查询当前时间范围。
9
+ - 五分钟内再次进入:复用记录、查询范围、分页游标和空结果。最新窗口复用原截止时间,避免每次以新的当前时间查询。
10
+ - 超过五分钟再次进入:先展示已缓存记录,再查询当前窗口。有效期只在进入时判断,没有定时校准、轮询、聚焦刷新或网络恢复刷新。
11
+ - 历史滚动:只查询未覆盖的范围;密集事件的下一页仍由真实滚动触发。游标始终携带原查询范围,不拼接到新的时间窗口。
12
+ - 加载旧游标不延长首页的有效期。未加载的分页不能被当作完整历史。
13
+ - 查询失败保留已有记录,不自动重试;同群两秒失败冷却跨视图切换保留。
14
+
15
+ ## 缓存的首帧恢复
16
+
17
+ 展示缓存与发起查询分别控制。成员列表刷新时,群主身份会暂时变为未知;快记也可能仍在后台加载。
18
+ 这两种等待只阻止新的事件查询,不隐藏同账号、同群已授权读取的缓存。
19
+ Hook 在渲染阶段通过只读 `peek` 同步取得记录,按已恢复的快记窗口过滤,避免先渲染空列表再等待 Effect 插入退群提示。
20
+ 组件重新挂载、尚无快记窗口时,使用缓存中上次同模式的窗口,不借用其他群或其他模式的窗口。
21
+ 没有缓存的首次进入仍等待群主身份和快记窗口。明确撤销权限时,首帧就隐藏记录并清理缓存。
22
+
23
+ ## 生命周期和通知
24
+
25
+ `member-event-cache.ts` 持有每群的 `MemberEventTimeline`,组件只是订阅者。
26
+ 离开视图停止通知触发的查询和视图更新,已发出的请求可以完成并填充缓存;再次进入复用同一请求与分页状态。
27
+
28
+ 全局 SSE 消费者通过 `member-event-hints.ts` 通知缓存:
29
+
30
+ - 正在查看的群沿用 300 毫秒合并、两秒最小刷新间隔和串行请求。
31
+ - 非当前群只记录变动,不发请求;再次进入查询一次。
32
+ - 事件 ID 去重状态保留在缓存中,请求按发起时的通知版本记录结果。请求期间的新通知继续有效。
33
+ - 历史定位视图只刷新其历史窗口;这不能把最新窗口误标为已更新。
34
+
35
+ 退出登录或切换账号、环境会销毁缓存并取消请求,迟到结果不能写回。
36
+ 确认失去群主身份或服务端拒绝访问会清除对应群记录;身份加载中的临时禁用不会清缓存。
37
+ 名称点击和发起私聊仍沿用原服务端权限校验。
38
+
39
+ ## 容量与展示
40
+
41
+ 保留最近使用的 20 个群。离开视图后的缓存每群最多保留 1,000 条事件和 200 个查询范围;当前正在浏览的列表不因缓存限额截断。
42
+ 淘汰事件时同步丢弃覆盖这些事件的查询范围,避免出现“记录已淘汰,但被误判为已经加载”的缺口。
43
+
44
+ 快记与成员变动继续按发生时间和稳定 ID 合并。历史定位过滤当前窗口,不混入未来记录;名称高亮和资料卡行为保持原实现。
45
+
46
+ ## 验证
47
+
48
+ 回归测试覆盖切群和重新挂载的首帧、身份及快记加载中的缓存显示、空结果、过期后展示旧数据、失败冷却、跨视图游标、历史范围缺口、容量淘汰、权限撤销、账号隔离、后台群通知及请求期间新通知。
49
+ 请求入口和共享缓存通过真实 Hook / 控制器运行,接口边界使用可控响应记录实际发起的调用。
@@ -0,0 +1,45 @@
1
+ # Resizable chat composer verification
2
+
3
+ - Base: official `origin/dev`, `4b8b40346be695774900997da4d6ce2f5a05e970`.
4
+ - Branch: `codex/c20260904-resizable-composer`.
5
+ - Scope: shared Arkme chat composer, client presentation only. No changes to DSH, plugin version, authentication or message sending.
6
+ - Behavior: 6px top drag target, vertical resize cursor, 1px green border while hovered/dragged/focused, local browser height preference, double-click/Enter reset, arrow/Home/End keyboard controls, viewport height limit, pointer capture and cursor cleanup.
7
+
8
+ ## Capability coverage
9
+
10
+ | Surface | Result |
11
+ | --- | --- |
12
+ | UI | Implemented and exercised in the installed plugin on Windows. |
13
+ | Tools | N/A: visual browser layout preference; no new business operation. |
14
+ | SDK | N/A: no Host API or shared business capability introduced. |
15
+ | Host | N/A: no Host storage or routes; localStorage contains only an editor height. |
16
+
17
+ ## Verification
18
+
19
+ - Relevant pre-change composer tests: 8 passed.
20
+ - Composer presentation/draft tests after integration: 18 passed.
21
+ - Resize, auth ownership and retained-surface tests after SSR fix: 15 passed.
22
+ - TypeScript check and diff whitespace check passed.
23
+ - Full suite: 3106 passed, 26 failed, 4 skipped; 16 failed suites and one additional suite-load failure within those suites. Not an all-green result. Remaining failures include Windows ACL command/module errors, fixture/source newline checksums, packaging/workflow expectations and timeouts. They have not all been independently reproduced on a clean baseline.
24
+ - Standard build passed after temporarily normalizing the credential helper's six checksum inputs to LF. Original checkout line endings were restored afterward; no helper source changes are part of this patch.
25
+ - Generated npm tarball, verified its client bundle hash matches the build, and installed it through official DSH `0.1.1-rc.1` into a fresh isolated profile. No link-based installation or DSH source edits.
26
+ - Actual browser: upward drag changed editor height from 38px to 191px; green rounded border visible; reload and reopening conversation restored 191px; double-click reset to 38px. No test message sent.
27
+ - Windows verified. macOS/Linux not exercised; this change adds no native/platform-specific code.
28
+
29
+ The earlier sidebar-width PR is separate and is not included in this branch's dev baseline. No production deployment or replacement of the user's running instance is included.
30
+
31
+ ## Follow-up: message viewport anchoring
32
+
33
+ - Confirmed missing behavior: a shrinking message viewport did not preserve its previous bottom distance, leaving latest messages below the visible region.
34
+ - Added a viewport ResizeObserver: when previously within 80px of the bottom, keep the latest message visible; while reading history, preserve scrollTop. Handles resize-generated scroll events arriving before the observer, reset/expansion, short lists and observer disposal.
35
+ - Composer bounds now use the actual chat area's available height; observers reconnect when the composer appears or the conversation changes. Switching conversation clears active drag/hover/focus state. Keyboard focus and pointer hover are tracked independently.
36
+ - Relevant resize/auth/retained-surface tests: 18 passed. Typecheck and standard build passed (same temporary LF build normalization described above).
37
+ - Full follow-up suite: 3108 passed, 27 failed, 4 skipped. Includes a recording-service timeout under the full parallel run; not an all-green result.
38
+ - Installed a new immutable tarball into a separate official DSH profile; preserved the previous preview instance.
39
+ - Browser verified: composer grew from 96px to 284px and the latest message moved upward by the same 188px, keeping the gap above the input. While reading older messages, increasing input height by 200px retained the same messages at the same top positions instead of jumping to the latest message.
40
+
41
+ ## Pre-PR review
42
+
43
+ - Reviewed the complete integration, pointer lifecycle, optional storage, observer cleanup, history anchoring, scope changes and height bounds. No new blocking finding identified.
44
+ - Re-fetched official dev; base remains unchanged with no integration conflict.
45
+ - Re-ran seven targeted suites: 36 tests passed. The separate recording-service rerun from the follow-up passed; full-suite failures above remain disclosed rather than presumed resolved.
@@ -0,0 +1,41 @@
1
+ # Resizable note detail
2
+
3
+ - Base: official dev `4b8b40346be695774900997da4d6ce2f5a05e970`.
4
+ - Branch: `codex/c20260904-resizable-detail`.
5
+ - Scope: shared right-edge overlay for normal/forwarded quick notes and interwoven details. Does not change message sending, underlying conversation layout, versions, root README or DSH sources.
6
+ - Left-edge 10px pointer target, 3px green highlight, ew-resize cursor; pointer capture, cancellation/unmount cleanup, keyboard support, double-click reset and optional localStorage width memory.
7
+ - Requested parity: default/minimum width 405px, maximum max(405px, 60% of available width). Containers narrower than 405px cap both bounds to the available width to prevent overflow. Previously saved preferences are clamped to the new bounds.
8
+
9
+ ## Coverage
10
+
11
+ | Surface | Evidence |
12
+ | --- | --- |
13
+ | UI | Shared resize hook integrated into both detail owners; unit and drawer tests. |
14
+ | Tools | N/A: no business capability, browser layout preference only. |
15
+ | SDK | N/A: no public service/API changes. |
16
+ | Host | N/A: no Host routes or persistence changes. |
17
+
18
+ - Before change: 17 drawer tests passed. Final targeted coverage: 22 tests passed across identity, resize and drawer suites.
19
+ - Typecheck passed. Standard build passed after temporary LF normalization of the existing credential-helper checksum inputs; original line endings restored, no helper source diff.
20
+ - Latest full-suite run: 3102 passed, 30 failed, 4 skipped. One documentation identity failure was subsequently corrected and the identity suite passed in the targeted rerun. Remaining failures include Windows ACL/module issues, fixture checksums and other areas; not all were independently reproduced on an untouched baseline. Full-suite status is not green.
21
+ - Packaged tarball installed via official DSH 0.1.1-rc.1 into a new isolated profile; existing preview instances preserved. No link installation or production deployment.
22
+ - Windows is the exercised platform; macOS/Linux not verified.
23
+ - Installed-package browser verification: final bounds verified at 405px minimum/default and approximately 554px maximum for a 924px container (60%). Green full-height divider confirmed. Earlier persistence verification confirmed the dragged width survived closing/reopening the detail. No messages sent or note data changed.
24
+ - Scope review: no blocking issue identified in the resize change. Emoji rendering is untouched; the preview base does not include the separate sidebar emoji asset fix. This PR intentionally does not merge that work.
25
+
26
+ ## Updated dev integration (2026-09-04)
27
+
28
+ - The earlier preview above is superseded. Merged official dev `4f093d0cff3ae98588ee8d9fc85c7bcf5d247696` without conflicts. The remote fetch configuration tracked only master, so fetching dev alone had left the old origin/dev reference unchanged; this run explicitly refreshed that reference.
29
+ - Sidebar preview rendering now inherits dev's `ArkmeRichText` with 20px application emoji assets and matches master `8fea757ff81170311393036240a0c292afd3737a` in the emoji implementation. No separate emoji feature patch or version bump was authored; package metadata is inherited from dev.
30
+ - Reviewed the complete five-file diff against updated dev, including the automatically merged detail shell. The resize scope remains client-only; Tools/SDK/Host remain N/A.
31
+ - Targeted resize/drawer/sidebar/identity suites: 28 tests passed. Typecheck and build passed. The existing credential-helper source files were temporarily normalized to LF for build verification and restored byte-for-byte afterward.
32
+ - Full suite: 3549 passed, 55 failed, 4 skipped (22 failed suites). This is not an all-green result and the failures are not all proven pre-existing. No unrelated test fixes are included.
33
+ - A fresh isolated official DSH 0.1.1-rc.1 profile installed the immutable tarball. Installed client SHA256 matches the build. Windows browser verified detail width 405px -> 495px by pointer drag and back to 405px on Enter; targeted 28 tests passed again after review. Sidebar renderer and emoji assets are unchanged from current master. No messages sent or note content changed.
34
+
35
+ ## Review follow-up: regression coverage and baseline comparison
36
+
37
+ - Added five tests covering parent resize/recovery and observer cleanup, pointer cancellation, lost pointer capture, unavailable storage, all resize keys and the window-resize fallback without ResizeObserver.
38
+ - Compared full suites against an untouched worktree at dev `4f093d0cff3ae98588ee8d9fc85c7bcf5d247696`. This identified two PR-specific outdated assertions still requiring 372px in interwoven and forwarded details. Updated both to the intended 405px default, container cap and accessible resize separator; retained their other content and authorization assertions.
39
+ - Expanded relevant suites: 88 passed. Typecheck and diff check passed. Review found no remaining confirmed resize implementation defect. No runtime code, emoji assets, metadata or version changes in this follow-up; the existing installed client remains byte-identical to the build.
40
+ - Clean dev full run: 3546 passed, 56 failed, 4 skipped. Final PR full run: 3552 passed, 57 failed, 4 skipped. All 56 baseline failing test identities also fail in the PR. The one additional recording-service timeout passes when rerun alone, and its implementation/test files are identical to dev. The suite-load failure is `spawnSync pnpm ENOENT` on both revisions. This comparison does not claim the whole repository is green or repair unrelated baseline issues.
41
+ - Remaining platform evidence limitation: macOS/Linux were not exercised. Windows pointer interaction evidence from the unchanged runtime above remains applicable.