@zhin.js/client 2.1.9 → 2.1.11

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 (70) hide show
  1. package/README.md +6 -0
  2. package/client/console-events.ts +37 -0
  3. package/client/index.ts +44 -2
  4. package/client/mediaSrc.test.ts +15 -0
  5. package/client/mediaSrc.ts +59 -12
  6. package/client/message-content/MarkdownContent.tsx +128 -0
  7. package/client/message-content/markdown.test.ts +48 -0
  8. package/client/message-content/markdown.ts +247 -0
  9. package/client/persistence/idb-store.test.ts +11 -0
  10. package/client/persistence/idb-store.ts +20 -4
  11. package/client/websocket/index.ts +6 -1
  12. package/client/websocket/manager.test.ts +145 -12
  13. package/client/websocket/manager.ts +189 -17
  14. package/client/websocket/types.ts +5 -0
  15. package/client/workroom/WorkroomRunsPage.tsx +248 -0
  16. package/client/{orchestration/registerOrchestrationConsole.test.ts → workroom/registerWorkroomConsole.test.ts} +8 -8
  17. package/client/workroom/registerWorkroomConsole.ts +17 -0
  18. package/dist/console-events.d.ts +7 -0
  19. package/dist/console-events.d.ts.map +1 -0
  20. package/dist/console-events.js +26 -0
  21. package/dist/console-events.js.map +1 -0
  22. package/dist/index.d.ts +6 -3
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +7 -3
  25. package/dist/index.js.map +1 -1
  26. package/dist/mediaSrc.d.ts.map +1 -1
  27. package/dist/mediaSrc.js +66 -12
  28. package/dist/mediaSrc.js.map +1 -1
  29. package/dist/message-content/MarkdownContent.d.ts +11 -0
  30. package/dist/message-content/MarkdownContent.d.ts.map +1 -0
  31. package/dist/message-content/MarkdownContent.js +68 -0
  32. package/dist/message-content/MarkdownContent.js.map +1 -0
  33. package/dist/message-content/markdown.d.ts +47 -0
  34. package/dist/message-content/markdown.d.ts.map +1 -0
  35. package/dist/message-content/markdown.js +219 -0
  36. package/dist/message-content/markdown.js.map +1 -0
  37. package/dist/persistence/idb-store.d.ts +3 -0
  38. package/dist/persistence/idb-store.d.ts.map +1 -1
  39. package/dist/persistence/idb-store.js +13 -3
  40. package/dist/persistence/idb-store.js.map +1 -1
  41. package/dist/websocket/index.d.ts +1 -1
  42. package/dist/websocket/index.d.ts.map +1 -1
  43. package/dist/websocket/index.js +1 -1
  44. package/dist/websocket/index.js.map +1 -1
  45. package/dist/websocket/manager.d.ts +19 -0
  46. package/dist/websocket/manager.d.ts.map +1 -1
  47. package/dist/websocket/manager.js +176 -18
  48. package/dist/websocket/manager.js.map +1 -1
  49. package/dist/websocket/types.d.ts +4 -0
  50. package/dist/websocket/types.d.ts.map +1 -1
  51. package/dist/websocket/types.js.map +1 -1
  52. package/dist/workroom/WorkroomRunsPage.d.ts +2 -0
  53. package/dist/workroom/WorkroomRunsPage.d.ts.map +1 -0
  54. package/dist/workroom/WorkroomRunsPage.js +64 -0
  55. package/dist/workroom/WorkroomRunsPage.js.map +1 -0
  56. package/dist/workroom/registerWorkroomConsole.d.ts +4 -0
  57. package/dist/workroom/registerWorkroomConsole.d.ts.map +1 -0
  58. package/dist/workroom/registerWorkroomConsole.js +16 -0
  59. package/dist/workroom/registerWorkroomConsole.js.map +1 -0
  60. package/package.json +3 -3
  61. package/client/orchestration/OrchestrationRunsPage.tsx +0 -217
  62. package/client/orchestration/registerOrchestrationConsole.ts +0 -17
  63. package/dist/orchestration/OrchestrationRunsPage.d.ts +0 -2
  64. package/dist/orchestration/OrchestrationRunsPage.d.ts.map +0 -1
  65. package/dist/orchestration/OrchestrationRunsPage.js +0 -65
  66. package/dist/orchestration/OrchestrationRunsPage.js.map +0 -1
  67. package/dist/orchestration/registerOrchestrationConsole.d.ts +0 -4
  68. package/dist/orchestration/registerOrchestrationConsole.d.ts.map +0 -1
  69. package/dist/orchestration/registerOrchestrationConsole.js +0 -16
  70. package/dist/orchestration/registerOrchestrationConsole.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,gCAAgC,EAChC,SAAS,EACT,eAAe,EACf,cAAc,EACd,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,4BAA4B,GAClC,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAG9E,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAG7E,OAAO,EACL,GAAG,EACH,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,oBAAoB,GAC1B,MAAM,OAAO,CAAC;AAGf,cAAc,aAAa,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAErE,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,KAAK,aAAa,GACnB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAE3C,OAAO,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,aAAa,EACb,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,aAAa,EACb,kBAAkB,EAClB,iCAAiC,EACjC,oBAAoB,EACpB,KAAK,kCAAkC,EACvC,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,GAC/B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAC/F,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAE5F,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,GACjC,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,gCAAgC,EAChC,gCAAgC,EAChC,SAAS,EACT,eAAe,EACf,cAAc,EACd,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,4BAA4B,EACjC,oBAAoB,EACpB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,GAC3B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,wBAAwB,EACxB,KAAK,+BAA+B,GACrC,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAG9E,OAAO,EACL,eAAe,EACf,SAAS,EACT,KAAK,oBAAoB,GAC1B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,aAAa,GACnB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAG7E,OAAO,EACL,GAAG,EACH,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,oBAAoB,GAC1B,MAAM,OAAO,CAAC;AAGf,cAAc,aAAa,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAErE,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,KAAK,aAAa,GACnB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAE3C,OAAO,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,aAAa,EACb,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,aAAa,EACb,kBAAkB,EAClB,iCAAiC,EACjC,oBAAoB,EACpB,KAAK,kCAAkC,EACvC,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,GAC/B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAE7E,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,GACjC,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -1,8 +1,12 @@
1
1
  // Types
2
2
  export * from "./types";
3
- export { ENDPOINT_RPC, ENDPOINT_MANAGEMENT_CAPABILITIES, INBOX_RPC, SIDE_EVENT_PUSH, SIDE_EVENT_RPC, normalizeConsolePushMessage, normalizeConsolePushType, parseConsoleInboxEvent, } from "@zhin.js/console-protocol";
3
+ export { ENDPOINT_RPC, CONSOLE_EVENT_RECOVERY_GAP_EVENT, ENDPOINT_MANAGEMENT_CAPABILITIES, INBOX_RPC, SIDE_EVENT_PUSH, SIDE_EVENT_RPC, normalizeConsolePushMessage, normalizeConsolePushType, parseConsoleInboxEvent, parseConsoleSseFrame, } from "@zhin.js/console-protocol";
4
+ export { fetchConsoleEventHistory, } from './console-events.js';
4
5
  // Media URL resolution
5
6
  export { resolveMediaSrc, pickMediaRawUrl } from "./mediaSrc";
7
+ // Safe rich message rendering (Markdown + code blocks; no raw HTML execution)
8
+ export { MarkdownContent, CodeBlock, } from "./message-content/MarkdownContent.js";
9
+ export { parseMarkdown, parseMarkdownInline, highlightCodeLine, isSafeMarkdownHref, } from "./message-content/markdown.js";
6
10
  // Segment IM visibility (inbox vs agent panel)
7
11
  export { segmentsForImDelivery, segmentsForAgentPanel } from "./segments.js";
8
12
  // Console app singleton (pagemanager / registry style)
@@ -14,7 +18,7 @@ export { createRegistryStore, useRegistry, } from "./store/createRegistryStore.j
14
18
  export { cn } from "./console-utils/cn.js";
15
19
  export { apiFetch, getApiBase, getToken, resolveApiUrl, resolveWebSocketUrl, } from "./console-utils/remoteApi.js";
16
20
  export { fetchConsoleEntries, createPluginRegisterHostApi, getRegisterFn, loadConsoleEntries, registerConsolePluginsFromEntries, resolveEntryRegister, } from "./bootstrap/loadConsoleEntries.js";
17
- export { registerOrchestrationConsole } from "./orchestration/registerOrchestrationConsole.js";
18
- export { default as OrchestrationRunsPage } from "./orchestration/OrchestrationRunsPage.js";
21
+ export { registerWorkroomConsole } from "./workroom/registerWorkroomConsole.js";
22
+ export { default as WorkroomRunsPage } from "./workroom/WorkroomRunsPage.js";
19
23
  export { startAgentSession, continueAgentSession, subscribeAgentStream, iterateAgentStreamNdjson, foldAgentStreamNdjson, } from "./agent-stream.js";
20
24
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,gCAAgC,EAChC,SAAS,EACT,eAAe,EACf,cAAc,EACd,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,GAMvB,MAAM,2BAA2B,CAAC;AAEnC,uBAAuB;AACvB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAkB,MAAM,YAAY,CAAC;AAE9E,+CAA+C;AAC/C,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE7E,uDAAuD;AACvD,OAAO,EACL,GAAG,GAQJ,MAAM,OAAO,CAAC;AAEf,iCAAiC;AACjC,cAAc,aAAa,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAErE,OAAO,EACL,mBAAmB,EACnB,WAAW,GAEZ,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAE3C,OAAO,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,aAAa,EACb,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,aAAa,EACb,kBAAkB,EAClB,iCAAiC,EACjC,oBAAoB,GAIrB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAC/F,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAE5F,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,GAGtB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,gCAAgC,EAChC,gCAAgC,EAChC,SAAS,EACT,eAAe,EACf,cAAc,EACd,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EAWtB,oBAAoB,GAcrB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,wBAAwB,GAEzB,MAAM,qBAAqB,CAAC;AAE7B,uBAAuB;AACvB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAkB,MAAM,YAAY,CAAC;AAE9E,8EAA8E;AAC9E,OAAO,EACL,eAAe,EACf,SAAS,GAEV,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,GAKnB,MAAM,+BAA+B,CAAC;AAEvC,+CAA+C;AAC/C,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE7E,uDAAuD;AACvD,OAAO,EACL,GAAG,GAQJ,MAAM,OAAO,CAAC;AAEf,iCAAiC;AACjC,cAAc,aAAa,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAErE,OAAO,EACL,mBAAmB,EACnB,WAAW,GAEZ,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAE3C,OAAO,EACL,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,aAAa,EACb,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,aAAa,EACb,kBAAkB,EAClB,iCAAiC,EACjC,oBAAoB,GAIrB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAE7E,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,GAGtB,MAAM,mBAAmB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mediaSrc.d.ts","sourceRoot":"","sources":["../client/mediaSrc.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AAUnD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAC9B,IAAI,GAAE,SAAmB,GACxB,MAAM,GAAG,SAAS,CAyBpB;AAED,oDAAoD;AACpD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAwB7F"}
1
+ {"version":3,"file":"mediaSrc.d.ts","sourceRoot":"","sources":["../client/mediaSrc.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AAsDnD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAC9B,IAAI,GAAE,SAAmB,GACxB,MAAM,GAAG,SAAS,CA4BpB;AAED,oDAAoD;AACpD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAwB7F"}
package/dist/mediaSrc.js CHANGED
@@ -1,7 +1,57 @@
1
1
  const BASE64_PROTO = 'base64://';
2
- const SAFE_URL_SCHEMES = ['data:', 'blob:', 'http://', 'https://'];
3
- function isSafeUrl(url) {
4
- return SAFE_URL_SCHEMES.some((scheme) => url.startsWith(scheme));
2
+ const SAFE_DATA_MIME = Object.freeze({
3
+ image: new Set(['image/avif', 'image/gif', 'image/jpeg', 'image/png', 'image/webp']),
4
+ video: new Set(['video/mp4', 'video/ogg', 'video/webm']),
5
+ audio: new Set(['audio/mpeg', 'audio/mp4', 'audio/ogg', 'audio/wav', 'audio/webm']),
6
+ });
7
+ function resolveSafeRemoteUrl(value) {
8
+ try {
9
+ const parsed = new URL(value);
10
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:' && parsed.protocol !== 'blob:') {
11
+ return undefined;
12
+ }
13
+ if (parsed.username || parsed.password)
14
+ return undefined;
15
+ return parsed.href;
16
+ }
17
+ catch {
18
+ return undefined;
19
+ }
20
+ }
21
+ function resolveSafeDataUrl(value, kind) {
22
+ if (!value.startsWith('data:'))
23
+ return undefined;
24
+ const separator = value.indexOf(',');
25
+ if (separator < 0)
26
+ return undefined;
27
+ const header = value.slice('data:'.length, separator).toLowerCase();
28
+ if (!header.endsWith(';base64'))
29
+ return undefined;
30
+ const mime = header.slice(0, -';base64'.length);
31
+ if (!SAFE_DATA_MIME[kind].has(mime))
32
+ return undefined;
33
+ const payload = compactBase64(value.slice(separator + 1));
34
+ return payload ? `data:${mime};base64,${payload}` : undefined;
35
+ }
36
+ function compactBase64(value) {
37
+ let compact = '';
38
+ for (const character of value) {
39
+ if (character === ' ' || character === '\n' || character === '\r' || character === '\t')
40
+ continue;
41
+ const code = character.charCodeAt(0);
42
+ const allowed = (code >= 48 && code <= 57)
43
+ || (code >= 65 && code <= 90)
44
+ || (code >= 97 && code <= 122)
45
+ || character === '+' || character === '/' || character === '=';
46
+ if (!allowed)
47
+ return undefined;
48
+ compact += character;
49
+ }
50
+ const padding = compact.indexOf('=');
51
+ if (padding >= 0 && (compact.length - padding > 2 || compact.slice(padding).replace(/=/g, '') !== '')) {
52
+ return undefined;
53
+ }
54
+ return compact || undefined;
5
55
  }
6
56
  /**
7
57
  * 将消息段中的 url/file 等转为浏览器可用的媒体地址。
@@ -19,22 +69,26 @@ export function resolveMediaSrc(raw, kind = 'image') {
19
69
  const s = raw.trim();
20
70
  if (!s)
21
71
  return undefined;
22
- if (isSafeUrl(s)) {
23
- return s;
24
- }
72
+ const dataUrl = resolveSafeDataUrl(s, kind);
73
+ if (dataUrl)
74
+ return dataUrl;
75
+ const remoteUrl = resolveSafeRemoteUrl(s);
76
+ if (remoteUrl)
77
+ return remoteUrl;
25
78
  if (!s.startsWith(BASE64_PROTO)) {
26
- return isSafeUrl(s) ? s : undefined;
79
+ return undefined;
27
80
  }
28
- const payload = s.slice(BASE64_PROTO.length).replace(/^\s+/, '');
81
+ const payload = s.slice(BASE64_PROTO.length).trimStart();
29
82
  if (!payload)
30
83
  return undefined;
31
84
  // 已是 type/subtype;base64, 片段(不含 data: 前缀)
32
- if (/^[\w+.-]+\/[\w+.-]+;base64,/i.test(payload)) {
33
- return `data:${payload}`;
85
+ const declared = resolveSafeDataUrl(`data:${payload}`, kind);
86
+ if (declared) {
87
+ return declared;
34
88
  }
35
89
  const defaultMime = kind === 'image' ? 'image/png' : kind === 'video' ? 'video/mp4' : 'audio/mpeg';
36
- const b64 = payload.replace(/\s/g, '');
37
- return `data:${defaultMime};base64,${b64}`;
90
+ const b64 = compactBase64(payload);
91
+ return b64 ? `data:${defaultMime};base64,${b64}` : undefined;
38
92
  }
39
93
  /** 从 segment.data 取常见媒体字段(优先 canonical MediaRef) */
40
94
  export function pickMediaRawUrl(data) {
@@ -1 +1 @@
1
- {"version":3,"file":"mediaSrc.js","sourceRoot":"","sources":["../client/mediaSrc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mediaSrc.js","sourceRoot":"","sources":["../client/mediaSrc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface MarkdownContentProps {
2
+ readonly text: string;
3
+ readonly className?: string;
4
+ }
5
+ export declare function CodeBlock({ code, language, closed }: {
6
+ readonly code: string;
7
+ readonly language?: string;
8
+ readonly closed?: boolean;
9
+ }): import("react").JSX.Element;
10
+ export declare function MarkdownContent({ text, className }: MarkdownContentProps): import("react").JSX.Element;
11
+ //# sourceMappingURL=MarkdownContent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownContent.d.ts","sourceRoot":"","sources":["../../client/message-content/MarkdownContent.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAwBD,wBAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,QAAa,EAAE,MAAa,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,+BAkDjJ;AAED,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,oBAAoB,+BAyCxE"}
@@ -0,0 +1,68 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Fragment, useMemo, useState } from 'react';
3
+ import { highlightCodeLine, parseMarkdown, } from './markdown.js';
4
+ function InlineContent({ content }) {
5
+ const nodes = [];
6
+ content.forEach((token, index) => {
7
+ const key = `${token.type}-${index}`;
8
+ const value = token.value.split('\n').map((line, lineIndex, lines) => (_jsxs(Fragment, { children: [line, lineIndex < lines.length - 1 ? _jsx("br", {}) : null] }, `${key}-line-${lineIndex}`)));
9
+ if (token.type === 'strong')
10
+ nodes.push(_jsx("strong", { children: value }, key));
11
+ else if (token.type === 'emphasis')
12
+ nodes.push(_jsx("em", { children: value }, key));
13
+ else if (token.type === 'strike')
14
+ nodes.push(_jsx("del", { children: value }, key));
15
+ else if (token.type === 'code')
16
+ nodes.push(_jsx("code", { className: "im-inline-code", children: token.value }, key));
17
+ else if (token.type === 'link')
18
+ nodes.push(_jsx("a", { href: token.href, target: token.href.startsWith('#') ? undefined : '_blank', rel: "noreferrer", className: "im-message-link", children: value }, key));
19
+ else
20
+ nodes.push(_jsx(Fragment, { children: value }, key));
21
+ });
22
+ return _jsx(_Fragment, { children: nodes });
23
+ }
24
+ export function CodeBlock({ code, language = '', closed = true }) {
25
+ const [copied, setCopied] = useState(false);
26
+ const [wrapped, setWrapped] = useState(false);
27
+ const [expanded, setExpanded] = useState(false);
28
+ const lines = useMemo(() => code.split('\n'), [code]);
29
+ const isLong = lines.length > 18 || code.length > 1800;
30
+ const visibleLines = isLong && !expanded ? lines.slice(0, 18) : lines;
31
+ const copy = async () => {
32
+ try {
33
+ await navigator.clipboard.writeText(code);
34
+ setCopied(true);
35
+ window.setTimeout(() => setCopied(false), 1600);
36
+ }
37
+ catch {
38
+ setCopied(false);
39
+ }
40
+ };
41
+ return (_jsxs("figure", { className: "zhin-code-block", children: [_jsxs("figcaption", { className: "zhin-code-toolbar", children: [_jsx("span", { className: "zhin-code-language", children: language || 'plain text' }), !closed ? _jsx("span", { className: "zhin-code-streaming", children: "\u751F\u6210\u4E2D" }) : null, _jsxs("span", { className: "zhin-code-actions", children: [_jsx("button", { type: "button", onClick: () => setWrapped((value) => !value), "aria-pressed": wrapped, children: wrapped ? '不折行' : '折行' }), _jsx("button", { type: "button", onClick: () => void copy(), children: copied ? '已复制' : '复制' })] })] }), _jsx("pre", { className: wrapped ? 'zhin-code-pre zhin-code-pre--wrap' : 'zhin-code-pre', children: _jsx("code", { children: visibleLines.map((line, lineIndex) => (_jsxs("span", { className: "zhin-code-line", children: [_jsx("span", { className: "zhin-code-line-number", "aria-hidden": "true", children: lineIndex + 1 }), _jsxs("span", { className: "zhin-code-line-content", children: [highlightCodeLine(line, language).map((token, tokenIndex) => (_jsx("span", { className: `zhin-code-token zhin-code-token--${token.kind}`, children: token.value }, `${token.kind}-${tokenIndex}`))), '\n'] })] }, `${lineIndex}-${line}`))) }) }), isLong ? (_jsx("button", { type: "button", className: "zhin-code-expand", onClick: () => setExpanded((value) => !value), children: expanded ? '收起代码' : `展开其余 ${lines.length - visibleLines.length} 行` })) : null] }));
42
+ }
43
+ export function MarkdownContent({ text, className }) {
44
+ const blocks = useMemo(() => parseMarkdown(text), [text]);
45
+ return (_jsx("div", { className: ['im-markdown-body', 'zhin-markdown', className].filter(Boolean).join(' '), children: blocks.map((block, index) => {
46
+ if (block.type === 'heading') {
47
+ const Heading = `h${block.level}`;
48
+ return _jsx(Heading, { className: `im-markdown-heading im-markdown-heading-${block.level}`, children: _jsx(InlineContent, { content: block.content }) }, index);
49
+ }
50
+ if (block.type === 'paragraph')
51
+ return _jsx("p", { className: "im-markdown-paragraph", children: _jsx(InlineContent, { content: block.content }) }, index);
52
+ if (block.type === 'quote')
53
+ return _jsx("blockquote", { className: "im-markdown-quote", children: _jsx(InlineContent, { content: block.content }) }, index);
54
+ if (block.type === 'rule')
55
+ return _jsx("hr", { className: "zhin-markdown-rule" }, index);
56
+ if (block.type === 'code')
57
+ return _jsx(CodeBlock, { code: block.value, language: block.language, closed: block.closed }, index);
58
+ if (block.type === 'list') {
59
+ const List = block.ordered ? 'ol' : 'ul';
60
+ return (_jsx(List, { className: `im-markdown-list${block.ordered ? ' im-markdown-list-ordered' : ''}`, children: block.items.map((item, itemIndex) => (_jsxs("li", { className: item.checked === undefined ? undefined : 'zhin-markdown-task', children: [item.checked === undefined ? null : _jsx("input", { type: "checkbox", checked: item.checked, readOnly: true, "aria-label": item.checked ? '已完成' : '未完成' }), _jsx(InlineContent, { content: item.content })] }, itemIndex))) }, index));
61
+ }
62
+ if (block.type === 'table') {
63
+ return (_jsx("div", { className: "zhin-markdown-table-wrap", children: _jsxs("table", { className: "zhin-markdown-table", children: [_jsx("thead", { children: _jsx("tr", { children: block.header.map((cell, cellIndex) => _jsx("th", { children: _jsx(InlineContent, { content: cell }) }, cellIndex)) }) }), _jsx("tbody", { children: block.rows.map((row, rowIndex) => _jsx("tr", { children: row.map((cell, cellIndex) => _jsx("td", { children: _jsx(InlineContent, { content: cell }) }, cellIndex)) }, rowIndex)) })] }) }, index));
64
+ }
65
+ return null;
66
+ }) }));
67
+ }
68
+ //# sourceMappingURL=MarkdownContent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownContent.js","sourceRoot":"","sources":["../../client/message-content/MarkdownContent.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ export type MarkdownInline = {
2
+ readonly type: 'text';
3
+ readonly value: string;
4
+ } | {
5
+ readonly type: 'strong' | 'emphasis' | 'strike' | 'code';
6
+ readonly value: string;
7
+ } | {
8
+ readonly type: 'link';
9
+ readonly value: string;
10
+ readonly href: string;
11
+ };
12
+ export type MarkdownBlock = {
13
+ readonly type: 'heading';
14
+ readonly level: number;
15
+ readonly content: MarkdownInline[];
16
+ } | {
17
+ readonly type: 'paragraph' | 'quote';
18
+ readonly content: MarkdownInline[];
19
+ } | {
20
+ readonly type: 'list';
21
+ readonly ordered: boolean;
22
+ readonly items: ReadonlyArray<{
23
+ readonly content: MarkdownInline[];
24
+ readonly checked?: boolean;
25
+ }>;
26
+ } | {
27
+ readonly type: 'code';
28
+ readonly language: string;
29
+ readonly value: string;
30
+ readonly closed: boolean;
31
+ } | {
32
+ readonly type: 'table';
33
+ readonly header: ReadonlyArray<MarkdownInline[]>;
34
+ readonly rows: ReadonlyArray<ReadonlyArray<MarkdownInline[]>>;
35
+ } | {
36
+ readonly type: 'rule';
37
+ };
38
+ export type CodeTokenKind = 'plain' | 'comment' | 'string' | 'number' | 'keyword' | 'literal';
39
+ export interface CodeToken {
40
+ readonly kind: CodeTokenKind;
41
+ readonly value: string;
42
+ }
43
+ export declare function isSafeMarkdownHref(href: string): boolean;
44
+ export declare function parseMarkdownInline(value: string): MarkdownInline[];
45
+ export declare function parseMarkdown(value: string): MarkdownBlock[];
46
+ export declare function highlightCodeLine(line: string, language?: string): CodeToken[];
47
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../client/message-content/markdown.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpF;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7E,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,EAAE,CAAA;CAAE,GACxF;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,EAAE,CAAA;CAAE,GAC5E;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CAAE,GACvJ;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GACtG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,cAAc,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,aAAa,CAAC,cAAc,EAAE,CAAC,CAAC,CAAA;CAAE,GAC3I;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9B,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAE9F,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAOD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKxD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAyCnE;AAiBD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CA+F5D;AAgBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAK,GAAG,SAAS,EAAE,CA6C1E"}
@@ -0,0 +1,219 @@
1
+ // Excluding another opening bracket from link labels prevents the regexp
2
+ // engine from rescanning an attacker-controlled run of `[` characters.
3
+ const INLINE_PATTERN = /(`[^`\n]+`)|(\*\*[^*\n]+\*\*|__[^_\n]+__)|(~~[^~\n]+~~)|(\*[^*\n]+\*|_[^_\n]+_)|(\[[^\[\]\n]+\]\([^\s()]+(?:\s+"[^"\n]*")?\))|(https?:\/\/[^\s<>()]+)/g;
4
+ const TABLE_DIVIDER = /^\s*\|?\s*:?-{3,}:?\s*(?:\|\s*:?-{3,}:?\s*)+\|?\s*$/;
5
+ export function isSafeMarkdownHref(href) {
6
+ const value = href.trim();
7
+ if (!value)
8
+ return false;
9
+ if (/^(https?:|mailto:)/i.test(value))
10
+ return true;
11
+ return /^(\/|#|\.\/|\.\.\/)/.test(value);
12
+ }
13
+ export function parseMarkdownInline(value) {
14
+ const tokens = [];
15
+ let cursor = 0;
16
+ let match;
17
+ INLINE_PATTERN.lastIndex = 0;
18
+ while ((match = INLINE_PATTERN.exec(value)) !== null) {
19
+ if (match.index > cursor)
20
+ tokens.push({ type: 'text', value: value.slice(cursor, match.index) });
21
+ const raw = match[0];
22
+ if (match[1]) {
23
+ tokens.push({ type: 'code', value: raw.slice(1, -1) });
24
+ }
25
+ else if (match[2]) {
26
+ tokens.push({ type: 'strong', value: raw.slice(2, -2) });
27
+ }
28
+ else if (match[3]) {
29
+ tokens.push({ type: 'strike', value: raw.slice(2, -2) });
30
+ }
31
+ else if (match[4]) {
32
+ tokens.push({ type: 'emphasis', value: raw.slice(1, -1) });
33
+ }
34
+ else if (match[5]) {
35
+ const parsed = raw.match(/^\[([^\[\]]+)\]\(([^\s()]+)(?:\s+"[^"\n]*")?\)$/);
36
+ if (parsed && isSafeMarkdownHref(parsed[2])) {
37
+ tokens.push({ type: 'link', value: parsed[1], href: parsed[2] });
38
+ }
39
+ else {
40
+ tokens.push({ type: 'text', value: raw });
41
+ }
42
+ }
43
+ else if (match[6]) {
44
+ tokens.push({ type: 'link', value: raw, href: raw });
45
+ }
46
+ cursor = INLINE_PATTERN.lastIndex;
47
+ }
48
+ if (cursor < value.length)
49
+ tokens.push({ type: 'text', value: value.slice(cursor) });
50
+ const merged = [];
51
+ for (const token of tokens) {
52
+ const previous = merged.at(-1);
53
+ if (token.type === 'text' && previous?.type === 'text') {
54
+ merged[merged.length - 1] = { type: 'text', value: previous.value + token.value };
55
+ }
56
+ else {
57
+ merged.push(token);
58
+ }
59
+ }
60
+ return merged.length > 0 ? merged : [{ type: 'text', value }];
61
+ }
62
+ function splitTableRow(line) {
63
+ return line
64
+ .trim()
65
+ .replace(/^\|/, '')
66
+ .replace(/\|$/, '')
67
+ .split(/(?<!\\)\|/)
68
+ .map((cell) => cell.trim().replace(/\\\|/g, '|'));
69
+ }
70
+ function startsBlock(lines, index) {
71
+ const line = lines[index] ?? '';
72
+ return /^(?:```|~~~|#{1,6}\s+|>\s?|\s*(?:[-+*]|\d+[.)])\s+|\s*(?:-{3,}|\*{3,}|_{3,})\s*$)/.test(line)
73
+ || (line.includes('|') && TABLE_DIVIDER.test(lines[index + 1] ?? ''));
74
+ }
75
+ export function parseMarkdown(value) {
76
+ const lines = value.replace(/\r\n?/g, '\n').split('\n');
77
+ const blocks = [];
78
+ let index = 0;
79
+ while (index < lines.length) {
80
+ const line = lines[index];
81
+ if (!line.trim()) {
82
+ index += 1;
83
+ continue;
84
+ }
85
+ const fence = line.match(/^\s*(```|~~~)\s*([^\s`]*)?.*$/);
86
+ if (fence) {
87
+ const marker = fence[1];
88
+ const language = (fence[2] ?? '').toLowerCase();
89
+ const code = [];
90
+ let closed = false;
91
+ index += 1;
92
+ while (index < lines.length) {
93
+ if (lines[index].trim() === marker) {
94
+ closed = true;
95
+ index += 1;
96
+ break;
97
+ }
98
+ code.push(lines[index]);
99
+ index += 1;
100
+ }
101
+ blocks.push({ type: 'code', language, value: code.join('\n'), closed });
102
+ continue;
103
+ }
104
+ const heading = line.match(/^(#{1,6})\s+(.+)$/);
105
+ if (heading) {
106
+ blocks.push({ type: 'heading', level: heading[1].length, content: parseMarkdownInline(heading[2]) });
107
+ index += 1;
108
+ continue;
109
+ }
110
+ if (/^\s*(?:-{3,}|\*{3,}|_{3,})\s*$/.test(line)) {
111
+ blocks.push({ type: 'rule' });
112
+ index += 1;
113
+ continue;
114
+ }
115
+ if (/^>\s?/.test(line)) {
116
+ const quoted = [];
117
+ while (index < lines.length && /^>\s?/.test(lines[index])) {
118
+ quoted.push(lines[index].replace(/^>\s?/, ''));
119
+ index += 1;
120
+ }
121
+ blocks.push({ type: 'quote', content: parseMarkdownInline(quoted.join('\n')) });
122
+ continue;
123
+ }
124
+ const listMatch = line.match(/^\s*([-+*]|\d+[.)])\s+(.+)$/);
125
+ if (listMatch) {
126
+ const ordered = /^\d/.test(listMatch[1]);
127
+ const items = [];
128
+ while (index < lines.length) {
129
+ const item = lines[index].match(/^\s*([-+*]|\d+[.)])\s+(.+)$/);
130
+ if (!item || /^\d/.test(item[1]) !== ordered)
131
+ break;
132
+ const task = item[2].match(/^\[([ xX])\]\s+(.+)$/);
133
+ items.push({
134
+ content: parseMarkdownInline(task ? task[2] : item[2]),
135
+ ...(task ? { checked: task[1].toLowerCase() === 'x' } : {}),
136
+ });
137
+ index += 1;
138
+ }
139
+ blocks.push({ type: 'list', ordered, items });
140
+ continue;
141
+ }
142
+ if (line.includes('|') && TABLE_DIVIDER.test(lines[index + 1] ?? '')) {
143
+ const header = splitTableRow(line).map(parseMarkdownInline);
144
+ const rows = [];
145
+ index += 2;
146
+ while (index < lines.length && lines[index].includes('|') && lines[index].trim()) {
147
+ rows.push(splitTableRow(lines[index]).map(parseMarkdownInline));
148
+ index += 1;
149
+ }
150
+ blocks.push({ type: 'table', header, rows });
151
+ continue;
152
+ }
153
+ const paragraph = [line];
154
+ index += 1;
155
+ while (index < lines.length && lines[index].trim() && !startsBlock(lines, index)) {
156
+ paragraph.push(lines[index]);
157
+ index += 1;
158
+ }
159
+ blocks.push({ type: 'paragraph', content: parseMarkdownInline(paragraph.join('\n')) });
160
+ }
161
+ return blocks;
162
+ }
163
+ const KEYWORDS = {
164
+ javascript: new Set(['async', 'await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'default', 'delete', 'do', 'else', 'export', 'extends', 'finally', 'for', 'from', 'function', 'if', 'import', 'in', 'instanceof', 'let', 'new', 'of', 'return', 'static', 'switch', 'throw', 'try', 'typeof', 'var', 'void', 'while', 'yield']),
165
+ typescript: new Set(['abstract', 'any', 'as', 'asserts', 'async', 'await', 'boolean', 'break', 'case', 'catch', 'class', 'const', 'continue', 'declare', 'default', 'delete', 'do', 'else', 'enum', 'export', 'extends', 'finally', 'for', 'from', 'function', 'if', 'implements', 'import', 'in', 'infer', 'instanceof', 'interface', 'keyof', 'let', 'namespace', 'never', 'new', 'number', 'object', 'of', 'readonly', 'return', 'satisfies', 'static', 'string', 'switch', 'symbol', 'throw', 'try', 'type', 'typeof', 'undefined', 'unknown', 'var', 'void', 'while', 'yield']),
166
+ python: new Set(['and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']),
167
+ shell: new Set(['case', 'do', 'done', 'elif', 'else', 'esac', 'export', 'fi', 'for', 'function', 'if', 'in', 'local', 'then', 'while']),
168
+ css: new Set(['@import', '@media', '@supports', 'and', 'important', 'not', 'only']),
169
+ };
170
+ const LANGUAGE_ALIASES = {
171
+ js: 'javascript', jsx: 'javascript', mjs: 'javascript', cjs: 'javascript',
172
+ ts: 'typescript', tsx: 'typescript', mts: 'typescript', cts: 'typescript',
173
+ py: 'python', bash: 'shell', sh: 'shell', zsh: 'shell', jsonc: 'json',
174
+ };
175
+ export function highlightCodeLine(line, language = '') {
176
+ const normalized = LANGUAGE_ALIASES[language] ?? language;
177
+ const keywords = KEYWORDS[normalized] ?? KEYWORDS.javascript;
178
+ const tokens = [];
179
+ let index = 0;
180
+ const push = (kind, value) => {
181
+ if (value)
182
+ tokens.push({ kind, value });
183
+ };
184
+ while (index < line.length) {
185
+ const rest = line.slice(index);
186
+ const comment = normalized === 'python' || normalized === 'shell'
187
+ ? rest.match(/^#.*/)
188
+ : rest.match(/^\/\/.*|^\/\*.*?\*\//);
189
+ if (comment) {
190
+ push('comment', comment[0]);
191
+ index += comment[0].length;
192
+ continue;
193
+ }
194
+ const string = rest.match(/^(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`)/);
195
+ if (string) {
196
+ push('string', string[0]);
197
+ index += string[0].length;
198
+ continue;
199
+ }
200
+ const number = rest.match(/^(?:0x[\da-f]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i);
201
+ if (number) {
202
+ push('number', number[0]);
203
+ index += number[0].length;
204
+ continue;
205
+ }
206
+ const word = rest.match(/^[A-Za-z_$@][\w$-]*/);
207
+ if (word) {
208
+ const literal = /^(?:true|false|null|undefined|None|True|False)$/.test(word[0]);
209
+ push(literal ? 'literal' : keywords.has(word[0]) ? 'keyword' : 'plain', word[0]);
210
+ index += word[0].length;
211
+ continue;
212
+ }
213
+ const plain = rest.match(/^[^A-Za-z_$@'"`\d/#]+/) ?? rest.match(/^./);
214
+ push('plain', plain?.[0] ?? '');
215
+ index += plain?.[0].length ?? 1;
216
+ }
217
+ return tokens;
218
+ }
219
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../client/message-content/markdown.ts"],"names":[],"mappings":"AAoBA,yEAAyE;AACzE,uEAAuE;AACvE,MAAM,cAAc,GAAG,wJAAwJ,CAAC;AAChL,MAAM,aAAa,GAAG,qDAAqD,CAAC;AAE5E,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC1B,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,OAAO,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,KAA6B,CAAC;IAClC,cAAc,CAAC,SAAS,GAAG,CAAC,CAAC;IAE7B,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACrD,IAAI,KAAK,CAAC,KAAK,GAAG,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjG,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3D,CAAC;aAAM,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3D,CAAC;aAAM,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7D,CAAC;aAAM,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;YAC5E,IAAI,MAAM,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnE,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC;IACpC,CAAC;IAED,IAAI,MAAM,GAAG,KAAK,CAAC,MAAM;QAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACrF,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,QAAQ,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;YACvD,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;QACpF,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI;SACR,IAAI,EAAE;SACN,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;SAClB,KAAK,CAAC,WAAW,CAAC;SAClB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,WAAW,CAAC,KAAwB,EAAE,KAAa;IAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAChC,OAAO,mFAAmF,CAAC,IAAI,CAAC,IAAI,CAAC;WAChG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACxD,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACjB,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC1D,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YAChD,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,IAAI,MAAM,GAAG,KAAK,CAAC;YACnB,KAAK,IAAI,CAAC,CAAC;YACX,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;oBACnC,MAAM,GAAG,IAAI,CAAC;oBACd,KAAK,IAAI,CAAC,CAAC;oBACX,MAAM;gBACR,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;gBACxB,KAAK,IAAI,CAAC,CAAC;YACb,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;YACxE,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAChD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACrG,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QAED,IAAI,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9B,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC1D,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;gBAC/C,KAAK,IAAI,CAAC,CAAC;YACb,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;YAChF,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAC5D,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,KAAK,GAA4D,EAAE,CAAC;YAC1E,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;gBAC/D,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO;oBAAE,MAAM;gBACpD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;gBACnD,KAAK,CAAC,IAAI,CAAC;oBACT,OAAO,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBACtD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC5D,CAAC,CAAC;gBACH,KAAK,IAAI,CAAC,CAAC;YACb,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAC9C,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YACrE,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;YAC5D,MAAM,IAAI,GAAyB,EAAE,CAAC;YACtC,KAAK,IAAI,CAAC,CAAC;YACX,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;gBACjF,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBAChE,KAAK,IAAI,CAAC,CAAC;YACb,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,CAAC;QACzB,KAAK,IAAI,CAAC,CAAC;QACX,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;YACjF,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YAC7B,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;IACzF,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,QAAQ,GAAwC;IACpD,UAAU,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9U,UAAU,EAAE,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACpjB,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/R,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACvI,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;CACpF,CAAC;AAEF,MAAM,gBAAgB,GAA2B;IAC/C,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY;IACzE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY;IACzE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;CACtE,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,QAAQ,GAAG,EAAE;IAC3D,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC;IAC1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC;IAC7D,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,MAAM,IAAI,GAAG,CAAC,IAAmB,EAAE,KAAa,EAAE,EAAE;QAClD,IAAI,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEF,OAAO,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,OAAO;YAC/D,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;YACpB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACvC,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5B,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;QACxF,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1B,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAC1B,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC1E,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1B,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAC1B,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC/C,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,OAAO,GAAG,iDAAiD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAChF,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACjF,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACxB,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAChC,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -11,5 +11,8 @@ export declare function idbListInbox(adapter: string, endpoint_id: string, kind:
11
11
  export declare function applyConsoleEvent(event: {
12
12
  type: string;
13
13
  data?: unknown;
14
+ runtimeId?: string;
15
+ eventId?: number;
16
+ timestamp?: number;
14
17
  }): Promise<void>;
15
18
  //# sourceMappingURL=idb-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"idb-store.d.ts","sourceRoot":"","sources":["../../client/persistence/idb-store.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAmBF,wBAAsB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CASpE;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,GACxB,OAAO,CAAC,WAAW,EAAE,CAAC,CAgBxB;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAa9F"}
1
+ {"version":3,"file":"idb-store.d.ts","sourceRoot":"","sources":["../../client/persistence/idb-store.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAmBF,wBAAsB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CASpE;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,GACxB,OAAO,CAAC,WAAW,EAAE,CAAC,CAgBxB;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBhB"}
@@ -48,10 +48,20 @@ export async function applyConsoleEvent(event) {
48
48
  const parsed = parseConsoleInboxEvent(event);
49
49
  if (!parsed)
50
50
  return;
51
- const updatedAt = Date.now();
51
+ const updatedAt = typeof event.timestamp === 'number' && Number.isFinite(event.timestamp)
52
+ ? event.timestamp
53
+ : Date.now();
54
+ const resumableId = typeof event.runtimeId === 'string'
55
+ && event.runtimeId
56
+ && Number.isSafeInteger(event.eventId)
57
+ && (event.eventId ?? 0) > 0
58
+ ? `${event.runtimeId}:${event.eventId}`
59
+ : null;
52
60
  await idbPutInbox({
53
- // 追加自增+随机后缀:同毫秒同会话的两条事件不会因主键相同而互相覆盖
54
- id: `${parsed.adapter}:${parsed.endpointKey}:${parsed.type}:${updatedAt}:${inboxEventSeq++}:${Math.random().toString(36).slice(2, 8)}`,
61
+ // Resumable Host events are idempotent across history/live redelivery.
62
+ // Legacy/unsequenced sources retain collision-safe append ids.
63
+ id: resumableId
64
+ ?? `${parsed.adapter}:${parsed.endpointKey}:${parsed.type}:${updatedAt}:${inboxEventSeq++}:${Math.random().toString(36).slice(2, 8)}`,
55
65
  adapter: parsed.adapter,
56
66
  endpoint_id: parsed.endpointKey,
57
67
  kind: parsed.kind,