@geminixiang/mikan 1.0.0-beta.28 → 1.0.0-beta.29

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 (185) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/adapter.d.ts +1 -1
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/adapter.js.map +1 -1
  5. package/dist/adapters/buffered-responder.d.ts +7 -1
  6. package/dist/adapters/buffered-responder.d.ts.map +1 -1
  7. package/dist/adapters/buffered-responder.js +6 -0
  8. package/dist/adapters/buffered-responder.js.map +1 -1
  9. package/dist/adapters/slack/blocks.d.ts.map +1 -1
  10. package/dist/adapters/slack/blocks.js +108 -152
  11. package/dist/adapters/slack/blocks.js.map +1 -1
  12. package/dist/adapters/slack/bot.d.ts +1 -0
  13. package/dist/adapters/slack/bot.d.ts.map +1 -1
  14. package/dist/adapters/slack/bot.js +44 -6
  15. package/dist/adapters/slack/bot.js.map +1 -1
  16. package/dist/adapters/slack/progressive-render.d.ts +66 -0
  17. package/dist/adapters/slack/progressive-render.d.ts.map +1 -0
  18. package/dist/adapters/slack/progressive-render.js +171 -0
  19. package/dist/adapters/slack/progressive-render.js.map +1 -0
  20. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  21. package/dist/adapters/slack/response-lifecycle.js +41 -139
  22. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  23. package/dist/adapters/slack/tool-pack.d.ts +27 -0
  24. package/dist/adapters/slack/tool-pack.d.ts.map +1 -0
  25. package/dist/adapters/slack/tool-pack.js +24 -0
  26. package/dist/adapters/slack/tool-pack.js.map +1 -0
  27. package/dist/adapters/slack/tools/blockkit.d.ts +28 -0
  28. package/dist/adapters/slack/tools/blockkit.d.ts.map +1 -0
  29. package/dist/adapters/slack/tools/blockkit.js +106 -0
  30. package/dist/adapters/slack/tools/blockkit.js.map +1 -0
  31. package/dist/adapters/telegram/context.d.ts.map +1 -1
  32. package/dist/adapters/telegram/context.js +14 -0
  33. package/dist/adapters/telegram/context.js.map +1 -1
  34. package/dist/agent.d.ts +2 -1
  35. package/dist/agent.d.ts.map +1 -1
  36. package/dist/agent.js +227 -40
  37. package/dist/agent.js.map +1 -1
  38. package/dist/cli/ext-dev.d.ts +2 -0
  39. package/dist/cli/ext-dev.d.ts.map +1 -0
  40. package/dist/cli/ext-dev.js +177 -0
  41. package/dist/cli/ext-dev.js.map +1 -0
  42. package/dist/cli/ext.d.ts.map +1 -1
  43. package/dist/cli/ext.js +7 -0
  44. package/dist/cli/ext.js.map +1 -1
  45. package/dist/config.d.ts.map +1 -1
  46. package/dist/config.js +31 -0
  47. package/dist/config.js.map +1 -1
  48. package/dist/execution-resolver.d.ts.map +1 -1
  49. package/dist/execution-resolver.js +16 -3
  50. package/dist/execution-resolver.js.map +1 -1
  51. package/dist/harness/auth.d.ts +2 -1
  52. package/dist/harness/auth.d.ts.map +1 -1
  53. package/dist/harness/auth.js +6 -0
  54. package/dist/harness/auth.js.map +1 -1
  55. package/dist/harness/extensions/blockkit.d.ts +19 -0
  56. package/dist/harness/extensions/blockkit.d.ts.map +1 -0
  57. package/dist/harness/extensions/blockkit.js +42 -0
  58. package/dist/harness/extensions/blockkit.js.map +1 -0
  59. package/dist/harness/extensions/loader.d.ts +13 -1
  60. package/dist/harness/extensions/loader.d.ts.map +1 -1
  61. package/dist/harness/extensions/loader.js +112 -41
  62. package/dist/harness/extensions/loader.js.map +1 -1
  63. package/dist/harness/extensions/registry.d.ts +15 -1
  64. package/dist/harness/extensions/registry.d.ts.map +1 -1
  65. package/dist/harness/extensions/registry.js +34 -0
  66. package/dist/harness/extensions/registry.js.map +1 -1
  67. package/dist/harness/extensions/types.d.ts +64 -0
  68. package/dist/harness/extensions/types.d.ts.map +1 -1
  69. package/dist/harness/extensions/types.js.map +1 -1
  70. package/dist/harness/index.d.ts +4 -2
  71. package/dist/harness/index.d.ts.map +1 -1
  72. package/dist/harness/index.js +2 -0
  73. package/dist/harness/index.js.map +1 -1
  74. package/dist/harness/runner.d.ts +6 -1
  75. package/dist/harness/runner.d.ts.map +1 -1
  76. package/dist/harness/runner.js +37 -8
  77. package/dist/harness/runner.js.map +1 -1
  78. package/dist/harness/subagent-profiles.d.ts +16 -0
  79. package/dist/harness/subagent-profiles.d.ts.map +1 -0
  80. package/dist/harness/subagent-profiles.js +211 -0
  81. package/dist/harness/subagent-profiles.js.map +1 -0
  82. package/dist/harness/subagent-runner.d.ts +9 -5
  83. package/dist/harness/subagent-runner.d.ts.map +1 -1
  84. package/dist/harness/subagent-runner.js +276 -103
  85. package/dist/harness/subagent-runner.js.map +1 -1
  86. package/dist/harness/types.d.ts +38 -1
  87. package/dist/harness/types.d.ts.map +1 -1
  88. package/dist/harness/types.js.map +1 -1
  89. package/dist/main.js +51 -14
  90. package/dist/main.js.map +1 -1
  91. package/dist/packages/admin.d.ts +29 -0
  92. package/dist/packages/admin.d.ts.map +1 -0
  93. package/dist/packages/admin.js +96 -0
  94. package/dist/packages/admin.js.map +1 -0
  95. package/dist/packages/index.d.ts +6 -0
  96. package/dist/packages/index.d.ts.map +1 -0
  97. package/dist/packages/index.js +6 -0
  98. package/dist/packages/index.js.map +1 -0
  99. package/dist/packages/inspect.d.ts +36 -0
  100. package/dist/packages/inspect.d.ts.map +1 -0
  101. package/dist/packages/inspect.js +100 -0
  102. package/dist/packages/inspect.js.map +1 -0
  103. package/dist/packages/materialize.d.ts +41 -0
  104. package/dist/packages/materialize.d.ts.map +1 -0
  105. package/dist/packages/materialize.js +190 -0
  106. package/dist/packages/materialize.js.map +1 -0
  107. package/dist/packages/resolve.d.ts +60 -0
  108. package/dist/packages/resolve.d.ts.map +1 -0
  109. package/dist/packages/resolve.js +212 -0
  110. package/dist/packages/resolve.js.map +1 -0
  111. package/dist/packages/source.d.ts +33 -0
  112. package/dist/packages/source.d.ts.map +1 -0
  113. package/dist/packages/source.js +177 -0
  114. package/dist/packages/source.js.map +1 -0
  115. package/dist/packages/types.d.ts +58 -0
  116. package/dist/packages/types.d.ts.map +1 -0
  117. package/dist/packages/types.js +2 -0
  118. package/dist/packages/types.js.map +1 -0
  119. package/dist/provisioner.d.ts.map +1 -1
  120. package/dist/provisioner.js +4 -1
  121. package/dist/provisioner.js.map +1 -1
  122. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  123. package/dist/runtime/conversation-runtime.js +90 -21
  124. package/dist/runtime/conversation-runtime.js.map +1 -1
  125. package/dist/runtime/types.d.ts +3 -1
  126. package/dist/runtime/types.d.ts.map +1 -1
  127. package/dist/runtime/types.js.map +1 -1
  128. package/dist/sandbox/gondolin.d.ts +39 -9
  129. package/dist/sandbox/gondolin.d.ts.map +1 -1
  130. package/dist/sandbox/gondolin.js +335 -43
  131. package/dist/sandbox/gondolin.js.map +1 -1
  132. package/dist/sandbox/index.d.ts +1 -1
  133. package/dist/sandbox/index.d.ts.map +1 -1
  134. package/dist/sandbox/index.js +1 -1
  135. package/dist/sandbox/index.js.map +1 -1
  136. package/dist/sandbox/types.d.ts +1 -0
  137. package/dist/sandbox/types.d.ts.map +1 -1
  138. package/dist/sandbox/types.js.map +1 -1
  139. package/dist/subagent-progress.d.ts +43 -0
  140. package/dist/subagent-progress.d.ts.map +1 -0
  141. package/dist/subagent-progress.js +220 -0
  142. package/dist/subagent-progress.js.map +1 -0
  143. package/dist/tools/read.d.ts +1 -0
  144. package/dist/tools/read.d.ts.map +1 -1
  145. package/dist/tools/read.js +30 -5
  146. package/dist/tools/read.js.map +1 -1
  147. package/dist/tools/subagent.d.ts +12 -9
  148. package/dist/tools/subagent.d.ts.map +1 -1
  149. package/dist/tools/subagent.js +141 -76
  150. package/dist/tools/subagent.js.map +1 -1
  151. package/dist/types.d.ts +90 -2
  152. package/dist/types.d.ts.map +1 -1
  153. package/dist/types.js.map +1 -1
  154. package/dist/web/admin/portal.d.ts.map +1 -1
  155. package/dist/web/admin/portal.js +268 -1
  156. package/dist/web/admin/portal.js.map +1 -1
  157. package/package.json +6 -6
  158. package/dist/sandbox/gondolin-bootstrap.d.ts +0 -12
  159. package/dist/sandbox/gondolin-bootstrap.d.ts.map +0 -1
  160. package/dist/sandbox/gondolin-bootstrap.js +0 -9
  161. package/dist/sandbox/gondolin-bootstrap.js.map +0 -1
  162. package/dist/sandbox/gondolin-contract.d.ts +0 -58
  163. package/dist/sandbox/gondolin-contract.d.ts.map +0 -1
  164. package/dist/sandbox/gondolin-contract.js +0 -71
  165. package/dist/sandbox/gondolin-contract.js.map +0 -1
  166. package/dist/sandbox/gondolin-inventory.d.ts +0 -75
  167. package/dist/sandbox/gondolin-inventory.d.ts.map +0 -1
  168. package/dist/sandbox/gondolin-inventory.js +0 -257
  169. package/dist/sandbox/gondolin-inventory.js.map +0 -1
  170. package/dist/sandbox/gondolin-recovery.d.ts +0 -20
  171. package/dist/sandbox/gondolin-recovery.d.ts.map +0 -1
  172. package/dist/sandbox/gondolin-recovery.js +0 -24
  173. package/dist/sandbox/gondolin-recovery.js.map +0 -1
  174. package/dist/sandbox/gondolin-worker-client.d.ts +0 -110
  175. package/dist/sandbox/gondolin-worker-client.d.ts.map +0 -1
  176. package/dist/sandbox/gondolin-worker-client.js +0 -322
  177. package/dist/sandbox/gondolin-worker-client.js.map +0 -1
  178. package/dist/sandbox/gondolin-worker-main.d.ts +0 -2
  179. package/dist/sandbox/gondolin-worker-main.d.ts.map +0 -1
  180. package/dist/sandbox/gondolin-worker-main.js +0 -22
  181. package/dist/sandbox/gondolin-worker-main.js.map +0 -1
  182. package/dist/sandbox/gondolin-worker.d.ts +0 -17
  183. package/dist/sandbox/gondolin-worker.d.ts.map +0 -1
  184. package/dist/sandbox/gondolin-worker.js +0 -201
  185. package/dist/sandbox/gondolin-worker.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -9,6 +9,34 @@ any release.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [1.0.0-beta.29]
13
+
14
+ ### Added
15
+
16
+ - Add Git-sourced extension packages with global and conversation scopes, package mount resolution, CLI inspection, and admin portal management.
17
+ - Add native Slack markdown-block responses and the `slack_blockkit` tool for interactive Block Kit messages.
18
+ - Add interactive Block Kit APIs for extensions, with a poll extension example.
19
+ - Add named subagent profiles, built-in workflow specialists, per-profile tool grants, and a bounded Slack progress dashboard.
20
+ - Preserve durable memory with Session Dream before biweekly shared-channel session rotation, using the same conversation-scoped maintenance path as `/new`.
21
+
22
+ ### Changed
23
+
24
+ - Run Gondolin runtimes inside the mikan process instead of detached workers. Restarts now boot fresh VMs on demand, and shutdown closes every VM so projected files sync back first.
25
+ - Remove Gondolin runtime inventories, worker heartbeats, and the `stateDir` argument from `configureGondolinRuntime`.
26
+ - Render standard GFM response prose as native Slack markdown blocks while keeping progressive response updates behind a single lifecycle.
27
+
28
+ ### Fixed
29
+
30
+ - Keep the current session active and preserve saved memory when Session Dream cannot finish.
31
+ - Bound subagent cancellation, invocation modes, profile labels, and Block Kit payloads; clamp long labels with an ellipsis instead of rejecting calls.
32
+ - Show the selected subagent profile and its tool grant consistently in progress output.
33
+ - Render the Slack subagent dashboard as a response source rather than escaped mrkdwn.
34
+ - Isolate Git test fixtures from an ambient `GIT_DIR`.
35
+
36
+ ### Tests
37
+
38
+ - Add coverage for extension packages, extension Block Kit APIs, native Slack rendering, subagent profiles and progress, Session Dream rotation, and in-process Gondolin lifecycle behavior.
39
+
12
40
  ## [1.0.0-beta.28]
13
41
 
14
42
  ### Removed
package/dist/adapter.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export type { MessagingBot, ConversationContext, ConversationEvent, MessagingEventHandler, ChatAdapter, ConversationMessage, ConversationResponder, ChatToolResult, ConversationKind, MessagingInfo, PlatformName, PlatformNotifier, PlatformReactor, PlatformUploader, RunningSession, } from "./types.js";
1
+ export type { MessagingBot, ConversationContext, ConversationEvent, MessagingEventHandler, ChatAdapter, ConversationMessage, ConversationResponder, ChatToolResult, ConversationKind, MessagingInfo, PlatformBlockKit, PlatformName, PlatformNotifier, PlatformReactor, PlatformUploader, RunningSession, SubagentProgressSnapshot, } from "./types.js";
2
2
  //# sourceMappingURL=adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,cAAc,GACf,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,wBAAwB,GACzB,MAAM,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"","sourcesContent":["export type {\n MessagingBot,\n ConversationContext,\n ConversationEvent,\n MessagingEventHandler,\n ChatAdapter,\n ConversationMessage,\n ConversationResponder,\n ChatToolResult,\n ConversationKind,\n MessagingInfo,\n PlatformName,\n PlatformNotifier,\n PlatformReactor,\n PlatformUploader,\n RunningSession,\n} from \"./types.js\";\n"]}
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"","sourcesContent":["export type {\n MessagingBot,\n ConversationContext,\n ConversationEvent,\n MessagingEventHandler,\n ChatAdapter,\n ConversationMessage,\n ConversationResponder,\n ChatToolResult,\n ConversationKind,\n MessagingInfo,\n PlatformBlockKit,\n PlatformName,\n PlatformNotifier,\n PlatformReactor,\n PlatformUploader,\n RunningSession,\n SubagentProgressSnapshot,\n} from \"./types.js\";\n"]}
@@ -1,4 +1,4 @@
1
- import type { ChatToolResult, ConversationResponder } from "../adapter.js";
1
+ import type { ChatToolResult, ConversationResponder, SubagentProgressSnapshot } from "../adapter.js";
2
2
  import { type ChatResponseErrorOperation } from "./shared.js";
3
3
  /**
4
4
  * The per-platform verbs and policy behind one buffered responder. Everything
@@ -26,6 +26,12 @@ export interface BufferedResponderPlatform {
26
26
  workingIndicator?: string;
27
27
  /** Enable appendResponseDelta/finishResponse over a buffered stream. */
28
28
  streaming: boolean;
29
+ /**
30
+ * Convert the subagent dashboard for a pipeline that is not response-source
31
+ * Markdown (Telegram HTML). Markdown platforms omit this: the harness
32
+ * composes the Markdown dashboard through replaceResponse.
33
+ */
34
+ formatSubagentProgress?: (progress: SubagentProgressSnapshot) => string;
29
35
  typing?: {
30
36
  send: () => Promise<unknown>;
31
37
  intervalMs: number;
@@ -1 +1 @@
1
- {"version":3,"file":"buffered-responder.d.ts","sourceRoot":"","sources":["../../src/adapters/buffered-responder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE3E,OAAO,EAA6B,KAAK,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAGzF;;;;;;;;GAQG;AACH,MAAM,WAAW,yBAAyB;IACxC,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IAChD,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7B,UAAU,EAAE,MAAM,CAAC;QACnB,+DAA+D;QAC/D,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,gBAAgB,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,MAAM,CAAC;IACrD,WAAW,EAAE,CACX,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,0BAA0B,EACrC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC3B,IAAI,CAAC;IACV,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,gEAAgE;IAChE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,0CAA0C;IAC1C,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,gEAAgE;IAChE,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzE,mCAAmC;IACnC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,mEAAmE;IACnE,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,uEAAuE;IACvE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9C,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,oFAAoF;AACpF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CASvE;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,yBAAyB,GAAG;IAC5E,SAAS,EAAE,qBAAqB,CAAC;CAClC,CAoPA"}
1
+ {"version":3,"file":"buffered-responder.d.ts","sourceRoot":"","sources":["../../src/adapters/buffered-responder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACzB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAA6B,KAAK,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAGzF;;;;;;;;GAQG;AACH,MAAM,WAAW,yBAAyB;IACxC,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IAChD,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,SAAS,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,CAAC,QAAQ,EAAE,wBAAwB,KAAK,MAAM,CAAC;IACxE,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7B,UAAU,EAAE,MAAM,CAAC;QACnB,+DAA+D;QAC/D,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,gBAAgB,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,MAAM,CAAC;IACrD,WAAW,EAAE,CACX,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,0BAA0B,EACrC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC3B,IAAI,CAAC;IACV,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,gEAAgE;IAChE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,0CAA0C;IAC1C,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,gEAAgE;IAChE,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzE,mCAAmC;IACnC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,mEAAmE;IACnE,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,uEAAuE;IACvE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9C,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,oFAAoF;AACpF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CASvE;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,yBAAyB,GAAG;IAC5E,SAAS,EAAE,qBAAqB,CAAC;CAClC,CA2PA"}
@@ -123,6 +123,12 @@ export function createBufferedResponder(platform) {
123
123
  hadExistingResponse: Boolean(responseId),
124
124
  }));
125
125
  },
126
+ replaceSubagentProgress: platform.formatSubagentProgress
127
+ ? async (progress, finalText) => {
128
+ const dashboard = platform.formatSubagentProgress(progress);
129
+ await responder.replaceResponse(finalText ? `${dashboard}\n\n${finalText}` : dashboard);
130
+ }
131
+ : undefined,
126
132
  respondDiagnostic: async (text, options) => {
127
133
  await run("respondDiagnostic", "respond_diagnostic", async () => {
128
134
  const prefix = options?.style === "error" ? platform.errorPrefix : "";
@@ -1 +1 @@
1
- {"version":3,"file":"buffered-responder.js","sourceRoot":"","sources":["../../src/adapters/buffered-responder.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ChatToolResult, ConversationResponder } from \"../adapter.js\";\nimport * as log from \"../log.js\";\nimport { formatToolArgs, splitText, type ChatResponseErrorOperation } from \"./shared.js\";\nimport { BufferedResponseStream, OrderedResponseOperations } from \"./streaming.js\";\n\n/**\n * The per-platform verbs and policy behind one buffered responder. Everything\n * else — the accumulated-text state machine, split-first-then-continuations\n * posting, response-id capture, ordered-queue error choreography, typing\n * interval, working indicator, delete semantics — is owned by\n * {@link createBufferedResponder} and identical on every buffered platform.\n * (Slack keeps its own streaming lifecycle; this covers the platforms that\n * edit one response message in place.)\n */\nexport interface BufferedResponderPlatform {\n /** Log label, e.g. \"Discord\". */\n label: string;\n /** Hard message length; longer responses continue in extra messages. */\n maxLength: number;\n formatContinuation: (partNum: number) => string;\n /** Prefix for respondDiagnostic({style:\"error\"}). */\n errorPrefix: string;\n /** Platform text normalization applied before accumulation (e.g. HTML). */\n sanitize?: (text: string) => string;\n /**\n * Suffix rendered while the run is working (and re-rendered away by\n * setWorking(false)). Platforms without one leave setWorking to typing.\n */\n workingIndicator?: string;\n /** Enable appendResponseDelta/finishResponse over a buffered stream. */\n streaming: boolean;\n typing?: {\n send: () => Promise<unknown>;\n intervalMs: number;\n /** Also stop the indicator when a message is actually sent. */\n stopOnSend?: boolean;\n };\n formatToolResult: (result: ChatToolResult) => string;\n reportError: (\n err: unknown,\n operation: ChatResponseErrorOperation,\n extra: Record<string, unknown>,\n ) => void;\n /** Posted into the conversation after a send fails (e.g. Telegram's ⚠️). */\n notifySendFailure?: (errorMessage: string) => Promise<void>;\n /** Post the first response message; returns its platform id. */\n post: (text: string) => Promise<string>;\n /** Edit the existing response message. */\n update: (id: string, text: string) => Promise<void>;\n /** Post an out-of-band message (continuations, diagnostics). */\n postExtra: (text: string, responseId: string | null) => Promise<unknown>;\n /** Delete the response message. */\n delete?: (id: string) => Promise<void>;\n /** Record a bot response chunk against the response message id. */\n logBotResponse?: (text: string, id: string) => void;\n /** Direct upload; absent platforms fall back to uploadFallbackNote. */\n uploadFile?: (filePath: string, title?: string) => Promise<void>;\n /** Posted (queued) instead of uploading when uploadFile is absent. */\n uploadFallbackNote?: (name: string) => string;\n react?: (emoji: string) => Promise<void>;\n}\n\n/** The tool-result rendering shared by the Markdown platforms (Discord, GitHub). */\nexport function formatMarkdownToolResult(result: ChatToolResult): string {\n const argsFormatted = formatToolArgs(result.args);\n const duration = (result.durationMs / 1000).toFixed(1);\n let text = `**${result.isError ? \"Error\" : \"Done\"} ${result.toolName}**`;\n if (result.label) text += `: ${result.label}`;\n text += ` (${duration}s)\\n`;\n if (argsFormatted) text += `\\`\\`\\`\\n${argsFormatted}\\n\\`\\`\\`\\n`;\n text += `**Result:**\\n\\`\\`\\`\\n${result.result}\\n\\`\\`\\``;\n return text;\n}\n\nexport function createBufferedResponder(platform: BufferedResponderPlatform): {\n responder: ConversationResponder;\n} {\n let responseId: string | null = null;\n let accumulatedText = \"\";\n let isWorking = true;\n const queue = new OrderedResponseOperations();\n let typingInterval: ReturnType<typeof setInterval> | null = null;\n let typingFailureWarned = false;\n\n const sanitize = platform.sanitize ?? ((text: string) => text);\n\n function stopTyping(): void {\n if (typingInterval !== null) {\n clearInterval(typingInterval);\n typingInterval = null;\n }\n }\n\n /** The response text as currently displayed (working indicator applied). */\n function render(text: string): string {\n return platform.workingIndicator && isWorking ? text + platform.workingIndicator : text;\n }\n\n async function postOrUpdate(displayText: string): Promise<void> {\n if (responseId !== null) {\n await platform.update(responseId, displayText);\n return;\n }\n if (platform.typing?.stopOnSend) stopTyping();\n responseId = await platform.post(displayText);\n }\n\n async function postExtra(text: string): Promise<void> {\n if (platform.typing?.stopOnSend) stopTyping();\n await platform.postExtra(text, responseId);\n }\n\n async function postSplit(text: string): Promise<void> {\n const [head, ...tail] = splitText(text, platform.maxLength, platform.formatContinuation);\n await postOrUpdate(head);\n for (const part of tail) {\n await postExtra(part);\n }\n }\n\n const stream = new BufferedResponseStream({\n flush: async (text) => {\n await postSplit(render(text));\n },\n finish: async (text) => {\n isWorking = false;\n stopTyping();\n await postSplit(text);\n },\n });\n\n function run(\n label: string,\n operation: ChatResponseErrorOperation,\n work: () => Promise<void>,\n extra: (err: unknown) => Record<string, unknown>,\n ): Promise<void> {\n return queue.run(work, async (err) => {\n const message = err instanceof Error ? err.message : String(err);\n log.logWarning(`${platform.label} ${label} error`, message);\n platform.reportError(err, operation, extra(err));\n if (platform.notifySendFailure) {\n try {\n await platform.notifySendFailure(message);\n } catch {\n // ignore secondary failure\n }\n }\n });\n }\n\n const responder: ConversationResponder = {\n respond: async (text: string) => {\n await run(\n \"respond\",\n \"respond\",\n async () => {\n const sanitized = sanitize(text);\n accumulatedText = accumulatedText ? `${accumulatedText}\\n${sanitized}` : sanitized;\n stream.setText(accumulatedText);\n await postSplit(render(accumulatedText));\n if (responseId !== null) {\n platform.logBotResponse?.(text, responseId);\n }\n },\n () => ({\n phase: responseId ? \"update\" : \"initial_post\",\n textLength: text.length,\n accumulatedLength: accumulatedText.length,\n }),\n );\n },\n\n ...(platform.streaming\n ? {\n appendResponseDelta: async (delta: string) => {\n await run(\n \"appendResponseDelta\",\n \"respond\",\n async () => {\n await stream.append(sanitize(delta));\n accumulatedText = stream.getText();\n if (responseId !== null) {\n platform.logBotResponse?.(delta, responseId);\n }\n },\n () => ({ textLength: delta.length, accumulatedLength: stream.getText().length }),\n );\n },\n\n finishResponse: async (finalText?: string) => {\n await run(\n \"finishResponse\",\n \"set_working\",\n async () => {\n await stream.finish(finalText === undefined ? undefined : sanitize(finalText));\n accumulatedText = stream.getText();\n },\n () => ({ finalTextLength: finalText?.length }),\n );\n },\n }\n : {}),\n\n replaceResponse: async (text: string) => {\n await run(\n \"replaceResponse\",\n \"replace_response\",\n async () => {\n accumulatedText = sanitize(text);\n stream.setText(accumulatedText);\n await postSplit(accumulatedText);\n },\n () => ({\n textLength: text.length,\n hadExistingResponse: Boolean(responseId),\n }),\n );\n },\n\n respondDiagnostic: async (text: string, options?: { style?: \"muted\" | \"error\" }) => {\n await run(\n \"respondDiagnostic\",\n \"respond_diagnostic\",\n async () => {\n const prefix = options?.style === \"error\" ? platform.errorPrefix : \"\";\n for (const part of splitText(\n sanitize(`${prefix}${text}`),\n platform.maxLength,\n platform.formatContinuation,\n )) {\n await postExtra(part);\n }\n },\n () => ({ textLength: text.length, style: options?.style }),\n );\n },\n\n respondToolResult: async (result: ChatToolResult) => {\n await responder.respondDiagnostic(platform.formatToolResult(result));\n },\n\n setTyping: async (isTyping: boolean) => {\n const typing = platform.typing;\n if (!typing) return;\n const onTypingError = (err: unknown): void => {\n if (typingFailureWarned) return;\n typingFailureWarned = true;\n log.logWarning(\n `${platform.label} sendTyping failed (further occurrences suppressed for this session)`,\n err instanceof Error ? err.message : String(err),\n );\n };\n if (isTyping && typingInterval === null) {\n typing.send().catch(onTypingError);\n typingInterval = setInterval(() => {\n typing.send().catch(onTypingError);\n }, typing.intervalMs);\n } else if (!isTyping) {\n stopTyping();\n }\n },\n\n setWorking: async (working: boolean) => {\n if (!platform.workingIndicator) {\n if (!working) stopTyping();\n return;\n }\n await run(\n \"setWorking\",\n \"set_working\",\n async () => {\n isWorking = working;\n if (!working) stopTyping();\n if (responseId !== null) {\n const [head] = splitText(\n render(accumulatedText),\n platform.maxLength,\n platform.formatContinuation,\n );\n await platform.update(responseId, head);\n }\n },\n () => ({ working }),\n );\n },\n\n uploadFile: async (filePath: string, title?: string) => {\n if (platform.uploadFile) {\n await platform.uploadFile(filePath, title);\n return;\n }\n const note = platform.uploadFallbackNote?.(title ?? filePath);\n if (note === undefined) return;\n await run(\n \"uploadFile\",\n \"respond_diagnostic\",\n () => postExtra(note),\n () => ({ filePath }),\n );\n },\n\n ...(platform.react ? { react: platform.react } : {}),\n\n deleteResponse: async () => {\n await queue.run(async () => {\n stopTyping();\n if (responseId !== null) {\n try {\n await platform.delete?.(responseId);\n } catch {\n // Ignore errors\n }\n responseId = null;\n }\n });\n },\n };\n\n return { responder };\n}\n"]}
1
+ {"version":3,"file":"buffered-responder.js","sourceRoot":"","sources":["../../src/adapters/buffered-responder.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ChatToolResult,\n ConversationResponder,\n SubagentProgressSnapshot,\n} from \"../adapter.js\";\nimport * as log from \"../log.js\";\nimport { formatToolArgs, splitText, type ChatResponseErrorOperation } from \"./shared.js\";\nimport { BufferedResponseStream, OrderedResponseOperations } from \"./streaming.js\";\n\n/**\n * The per-platform verbs and policy behind one buffered responder. Everything\n * else — the accumulated-text state machine, split-first-then-continuations\n * posting, response-id capture, ordered-queue error choreography, typing\n * interval, working indicator, delete semantics — is owned by\n * {@link createBufferedResponder} and identical on every buffered platform.\n * (Slack keeps its own streaming lifecycle; this covers the platforms that\n * edit one response message in place.)\n */\nexport interface BufferedResponderPlatform {\n /** Log label, e.g. \"Discord\". */\n label: string;\n /** Hard message length; longer responses continue in extra messages. */\n maxLength: number;\n formatContinuation: (partNum: number) => string;\n /** Prefix for respondDiagnostic({style:\"error\"}). */\n errorPrefix: string;\n /** Platform text normalization applied before accumulation (e.g. HTML). */\n sanitize?: (text: string) => string;\n /**\n * Suffix rendered while the run is working (and re-rendered away by\n * setWorking(false)). Platforms without one leave setWorking to typing.\n */\n workingIndicator?: string;\n /** Enable appendResponseDelta/finishResponse over a buffered stream. */\n streaming: boolean;\n /**\n * Convert the subagent dashboard for a pipeline that is not response-source\n * Markdown (Telegram HTML). Markdown platforms omit this: the harness\n * composes the Markdown dashboard through replaceResponse.\n */\n formatSubagentProgress?: (progress: SubagentProgressSnapshot) => string;\n typing?: {\n send: () => Promise<unknown>;\n intervalMs: number;\n /** Also stop the indicator when a message is actually sent. */\n stopOnSend?: boolean;\n };\n formatToolResult: (result: ChatToolResult) => string;\n reportError: (\n err: unknown,\n operation: ChatResponseErrorOperation,\n extra: Record<string, unknown>,\n ) => void;\n /** Posted into the conversation after a send fails (e.g. Telegram's ⚠️). */\n notifySendFailure?: (errorMessage: string) => Promise<void>;\n /** Post the first response message; returns its platform id. */\n post: (text: string) => Promise<string>;\n /** Edit the existing response message. */\n update: (id: string, text: string) => Promise<void>;\n /** Post an out-of-band message (continuations, diagnostics). */\n postExtra: (text: string, responseId: string | null) => Promise<unknown>;\n /** Delete the response message. */\n delete?: (id: string) => Promise<void>;\n /** Record a bot response chunk against the response message id. */\n logBotResponse?: (text: string, id: string) => void;\n /** Direct upload; absent platforms fall back to uploadFallbackNote. */\n uploadFile?: (filePath: string, title?: string) => Promise<void>;\n /** Posted (queued) instead of uploading when uploadFile is absent. */\n uploadFallbackNote?: (name: string) => string;\n react?: (emoji: string) => Promise<void>;\n}\n\n/** The tool-result rendering shared by the Markdown platforms (Discord, GitHub). */\nexport function formatMarkdownToolResult(result: ChatToolResult): string {\n const argsFormatted = formatToolArgs(result.args);\n const duration = (result.durationMs / 1000).toFixed(1);\n let text = `**${result.isError ? \"Error\" : \"Done\"} ${result.toolName}**`;\n if (result.label) text += `: ${result.label}`;\n text += ` (${duration}s)\\n`;\n if (argsFormatted) text += `\\`\\`\\`\\n${argsFormatted}\\n\\`\\`\\`\\n`;\n text += `**Result:**\\n\\`\\`\\`\\n${result.result}\\n\\`\\`\\``;\n return text;\n}\n\nexport function createBufferedResponder(platform: BufferedResponderPlatform): {\n responder: ConversationResponder;\n} {\n let responseId: string | null = null;\n let accumulatedText = \"\";\n let isWorking = true;\n const queue = new OrderedResponseOperations();\n let typingInterval: ReturnType<typeof setInterval> | null = null;\n let typingFailureWarned = false;\n\n const sanitize = platform.sanitize ?? ((text: string) => text);\n\n function stopTyping(): void {\n if (typingInterval !== null) {\n clearInterval(typingInterval);\n typingInterval = null;\n }\n }\n\n /** The response text as currently displayed (working indicator applied). */\n function render(text: string): string {\n return platform.workingIndicator && isWorking ? text + platform.workingIndicator : text;\n }\n\n async function postOrUpdate(displayText: string): Promise<void> {\n if (responseId !== null) {\n await platform.update(responseId, displayText);\n return;\n }\n if (platform.typing?.stopOnSend) stopTyping();\n responseId = await platform.post(displayText);\n }\n\n async function postExtra(text: string): Promise<void> {\n if (platform.typing?.stopOnSend) stopTyping();\n await platform.postExtra(text, responseId);\n }\n\n async function postSplit(text: string): Promise<void> {\n const [head, ...tail] = splitText(text, platform.maxLength, platform.formatContinuation);\n await postOrUpdate(head);\n for (const part of tail) {\n await postExtra(part);\n }\n }\n\n const stream = new BufferedResponseStream({\n flush: async (text) => {\n await postSplit(render(text));\n },\n finish: async (text) => {\n isWorking = false;\n stopTyping();\n await postSplit(text);\n },\n });\n\n function run(\n label: string,\n operation: ChatResponseErrorOperation,\n work: () => Promise<void>,\n extra: (err: unknown) => Record<string, unknown>,\n ): Promise<void> {\n return queue.run(work, async (err) => {\n const message = err instanceof Error ? err.message : String(err);\n log.logWarning(`${platform.label} ${label} error`, message);\n platform.reportError(err, operation, extra(err));\n if (platform.notifySendFailure) {\n try {\n await platform.notifySendFailure(message);\n } catch {\n // ignore secondary failure\n }\n }\n });\n }\n\n const responder: ConversationResponder = {\n respond: async (text: string) => {\n await run(\n \"respond\",\n \"respond\",\n async () => {\n const sanitized = sanitize(text);\n accumulatedText = accumulatedText ? `${accumulatedText}\\n${sanitized}` : sanitized;\n stream.setText(accumulatedText);\n await postSplit(render(accumulatedText));\n if (responseId !== null) {\n platform.logBotResponse?.(text, responseId);\n }\n },\n () => ({\n phase: responseId ? \"update\" : \"initial_post\",\n textLength: text.length,\n accumulatedLength: accumulatedText.length,\n }),\n );\n },\n\n ...(platform.streaming\n ? {\n appendResponseDelta: async (delta: string) => {\n await run(\n \"appendResponseDelta\",\n \"respond\",\n async () => {\n await stream.append(sanitize(delta));\n accumulatedText = stream.getText();\n if (responseId !== null) {\n platform.logBotResponse?.(delta, responseId);\n }\n },\n () => ({ textLength: delta.length, accumulatedLength: stream.getText().length }),\n );\n },\n\n finishResponse: async (finalText?: string) => {\n await run(\n \"finishResponse\",\n \"set_working\",\n async () => {\n await stream.finish(finalText === undefined ? undefined : sanitize(finalText));\n accumulatedText = stream.getText();\n },\n () => ({ finalTextLength: finalText?.length }),\n );\n },\n }\n : {}),\n\n replaceResponse: async (text: string) => {\n await run(\n \"replaceResponse\",\n \"replace_response\",\n async () => {\n accumulatedText = sanitize(text);\n stream.setText(accumulatedText);\n await postSplit(accumulatedText);\n },\n () => ({\n textLength: text.length,\n hadExistingResponse: Boolean(responseId),\n }),\n );\n },\n\n replaceSubagentProgress: platform.formatSubagentProgress\n ? async (progress: SubagentProgressSnapshot, finalText?: string) => {\n const dashboard = platform.formatSubagentProgress!(progress);\n await responder.replaceResponse(finalText ? `${dashboard}\\n\\n${finalText}` : dashboard);\n }\n : undefined,\n\n respondDiagnostic: async (text: string, options?: { style?: \"muted\" | \"error\" }) => {\n await run(\n \"respondDiagnostic\",\n \"respond_diagnostic\",\n async () => {\n const prefix = options?.style === \"error\" ? platform.errorPrefix : \"\";\n for (const part of splitText(\n sanitize(`${prefix}${text}`),\n platform.maxLength,\n platform.formatContinuation,\n )) {\n await postExtra(part);\n }\n },\n () => ({ textLength: text.length, style: options?.style }),\n );\n },\n\n respondToolResult: async (result: ChatToolResult) => {\n await responder.respondDiagnostic(platform.formatToolResult(result));\n },\n\n setTyping: async (isTyping: boolean) => {\n const typing = platform.typing;\n if (!typing) return;\n const onTypingError = (err: unknown): void => {\n if (typingFailureWarned) return;\n typingFailureWarned = true;\n log.logWarning(\n `${platform.label} sendTyping failed (further occurrences suppressed for this session)`,\n err instanceof Error ? err.message : String(err),\n );\n };\n if (isTyping && typingInterval === null) {\n typing.send().catch(onTypingError);\n typingInterval = setInterval(() => {\n typing.send().catch(onTypingError);\n }, typing.intervalMs);\n } else if (!isTyping) {\n stopTyping();\n }\n },\n\n setWorking: async (working: boolean) => {\n if (!platform.workingIndicator) {\n if (!working) stopTyping();\n return;\n }\n await run(\n \"setWorking\",\n \"set_working\",\n async () => {\n isWorking = working;\n if (!working) stopTyping();\n if (responseId !== null) {\n const [head] = splitText(\n render(accumulatedText),\n platform.maxLength,\n platform.formatContinuation,\n );\n await platform.update(responseId, head);\n }\n },\n () => ({ working }),\n );\n },\n\n uploadFile: async (filePath: string, title?: string) => {\n if (platform.uploadFile) {\n await platform.uploadFile(filePath, title);\n return;\n }\n const note = platform.uploadFallbackNote?.(title ?? filePath);\n if (note === undefined) return;\n await run(\n \"uploadFile\",\n \"respond_diagnostic\",\n () => postExtra(note),\n () => ({ filePath }),\n );\n },\n\n ...(platform.react ? { react: platform.react } : {}),\n\n deleteResponse: async () => {\n await queue.run(async () => {\n stopTyping();\n if (responseId !== null) {\n try {\n await platform.delete?.(responseId);\n } catch {\n // Ignore errors\n }\n responseId = null;\n }\n });\n },\n };\n\n return { responder };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/blocks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAwK/C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,EAAE,CAAA;CAAE,CA+DxF"}
1
+ {"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/blocks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA+I/C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,EAAE,CAAA;CAAE,CAmCxF"}
@@ -1,80 +1,46 @@
1
1
  import MarkdownIt from "markdown-it";
2
- const markdown = new MarkdownIt({
3
- html: false,
4
- linkify: true,
5
- breaks: true,
6
- });
2
+ // Parser is used only to locate tables and derive plain-text fallback.
3
+ // Prose is never re-serialized from tokens: it is sliced verbatim from the
4
+ // source and handed to Slack as a native `markdown` block, so Slack owns
5
+ // all prose rendering (same renderer as the markdown_text streaming API).
6
+ const markdown = new MarkdownIt({ html: false });
7
7
  const MAX_BLOCKS = 50;
8
- const SECTION_TEXT_LIMIT = 3000;
8
+ // Slack rejects messages whose markdown block text exceeds 12k (msg_too_long).
9
+ const MARKDOWN_TEXT_LIMIT = 12000;
9
10
  const FIELD_TEXT_LIMIT = 2000;
10
- function pushSection(blocks, text) {
11
- const trimmed = text.trim();
12
- if (!trimmed)
13
- return;
14
- for (let i = 0; i < trimmed.length && blocks.length < MAX_BLOCKS; i += SECTION_TEXT_LIMIT) {
15
- blocks.push({
16
- type: "section",
17
- text: { type: "mrkdwn", text: trimmed.slice(i, i + SECTION_TEXT_LIMIT) },
18
- });
19
- }
11
+ // Legacy Slack-style links (<url|label>) predate the standard-GFM response
12
+ // source contract; system producers may still emit them.
13
+ const LEGACY_MRKDWN_LINK_PATTERN = /<(https?:\/\/[^<>|\s]+)\|([^<>\n]+)>/g;
14
+ function convertLegacyMrkdwnLinks(source) {
15
+ return source.replace(LEGACY_MRKDWN_LINK_PATTERN, "[$2]($1)");
16
+ }
17
+ function normalizeMarkdownTables(source) {
18
+ return source
19
+ .split("\n")
20
+ .map((line) => {
21
+ const trimmed = line.trim();
22
+ if (!trimmed.startsWith("|") || !trimmed.endsWith("|"))
23
+ return line;
24
+ if (!/^[|+\-:\s]+$/.test(trimmed) || !trimmed.includes("+"))
25
+ return line;
26
+ return line.replaceAll("+", "|");
27
+ })
28
+ .join("\n");
20
29
  }
21
- function renderInline(tokens) {
30
+ function inlinePlainText(tokens) {
22
31
  if (!tokens)
23
32
  return "";
24
33
  let text = "";
25
- for (let i = 0; i < tokens.length; i++) {
26
- const token = tokens[i];
27
- const linkText = tokens[i + 1];
28
- const linkClose = tokens[i + 2];
29
- if (token.type === "link_open" &&
30
- token.markup === "autolink" &&
31
- linkText?.type === "text" &&
32
- linkText.content.includes("|") &&
33
- linkClose?.type === "link_close") {
34
- text += `<${linkText.content}>`;
35
- i += 2;
36
- }
37
- else if (token.type === "text" || token.type === "code_inline")
34
+ for (const token of tokens) {
35
+ if (token.type === "text" || token.type === "code_inline")
38
36
  text += token.content;
39
37
  else if (token.type === "softbreak" || token.type === "hardbreak")
40
38
  text += "\n";
41
- else if (token.type === "strong_open")
42
- text += "*";
43
- else if (token.type === "strong_close")
44
- text += "*";
45
- else if (token.type === "em_open")
46
- text += "_";
47
- else if (token.type === "em_close")
48
- text += "_";
49
- else if (token.type === "link_open") {
50
- const href = token.attrGet("href");
51
- if (href)
52
- text += `<${href}|`;
53
- }
54
- else if (token.type === "link_close") {
55
- text += ">";
56
- }
57
- else if (token.children) {
58
- text += renderInline(token.children);
59
- }
39
+ else if (token.children)
40
+ text += inlinePlainText(token.children);
60
41
  }
61
42
  return text;
62
43
  }
63
- function collectInlineUntil(tokens, index, endType) {
64
- let text = "";
65
- let i = index;
66
- for (; i < tokens.length && tokens[i].type !== endType; i++) {
67
- const token = tokens[i];
68
- if (token.type === "inline")
69
- text += renderInline(token.children) || token.content;
70
- else if (token.type === "fence" || token.type === "code_block")
71
- text += `\n\`\`\`\n${token.content}\n\`\`\``;
72
- }
73
- return { text, next: i };
74
- }
75
- function isTableAt(tokens, index) {
76
- return tokens[index]?.type === "table_open";
77
- }
78
44
  function buildTableBlock(headers, rows) {
79
45
  const hasIndex = headers[0] === "#";
80
46
  const tableHeaders = hasIndex ? headers : ["#", ...headers];
@@ -88,7 +54,8 @@ function buildTableBlock(headers, rows) {
88
54
  };
89
55
  }
90
56
  function parseTable(tokens, index) {
91
- if (!isTableAt(tokens, index))
57
+ const open = tokens[index];
58
+ if (open?.type !== "table_open" || !open.map)
92
59
  return null;
93
60
  const headers = [];
94
61
  const rows = [];
@@ -111,110 +78,99 @@ function parseTable(tokens, index) {
111
78
  currentRow = null;
112
79
  }
113
80
  else if (token.type === "inline" && currentRow) {
114
- currentRow.push(renderInline(token.children) || token.content);
81
+ currentRow.push(inlinePlainText(token.children) || token.content);
115
82
  }
116
83
  }
117
84
  if (!headers.length || !rows.length)
118
85
  return null;
119
86
  const fallback = [headers.join(" | "), ...rows.map((row) => row.join(" | "))].join("\n");
120
- return { blocks: [buildTableBlock(headers, rows)], fallback, next: i };
121
- }
122
- function normalizeMarkdownTables(source) {
123
- return source
124
- .split("\n")
125
- .map((line) => {
126
- const trimmed = line.trim();
127
- if (!trimmed.startsWith("|") || !trimmed.endsWith("|"))
128
- return line;
129
- if (!/^[|+\-:\s]+$/.test(trimmed) || !trimmed.includes("+"))
130
- return line;
131
- return line.replaceAll("+", "|");
132
- })
133
- .join("\n");
134
- }
135
- const SLACK_MRKDWN_LINK_PATTERN = /<https?:\/\/[^<>|\s]+\|[^<>\n]+>/g;
136
- function protectSlackMrkdwnLinks(source) {
137
- const links = [];
138
- const protectedSource = source.replace(SLACK_MRKDWN_LINK_PATTERN, (link) => {
139
- const index = links.push(link) - 1;
140
- return `MIKANSLACKLINK${index}PLACEHOLDER`;
141
- });
142
- return { source: protectedSource, links };
87
+ const endLine = tokens[i]?.map?.[1] ?? open.map[1];
88
+ return {
89
+ table: {
90
+ block: buildTableBlock(headers, rows),
91
+ fallback,
92
+ startLine: open.map[0],
93
+ endLine,
94
+ },
95
+ next: i,
96
+ };
143
97
  }
144
- function restoreSlackMrkdwnLinks(text, links) {
145
- return text.replace(/MIKANSLACKLINK(\d+)PLACEHOLDER/g, (placeholder, indexText) => {
146
- return links[Number(indexText)] ?? placeholder;
147
- });
98
+ /** Split prose into chunks under the markdown block limit, preferring
99
+ * paragraph boundaries, then line boundaries, then a hard slice. */
100
+ function splitProse(text) {
101
+ if (text.length <= MARKDOWN_TEXT_LIMIT)
102
+ return [text];
103
+ const chunks = [];
104
+ let rest = text;
105
+ while (rest.length > MARKDOWN_TEXT_LIMIT) {
106
+ const window = rest.slice(0, MARKDOWN_TEXT_LIMIT);
107
+ let cut = window.lastIndexOf("\n\n");
108
+ if (cut <= 0)
109
+ cut = window.lastIndexOf("\n");
110
+ if (cut <= 0)
111
+ cut = MARKDOWN_TEXT_LIMIT;
112
+ chunks.push(rest.slice(0, cut));
113
+ rest = rest.slice(cut);
114
+ }
115
+ if (rest.trim())
116
+ chunks.push(rest);
117
+ return chunks;
148
118
  }
149
- function restoreBlockLinks(block, links) {
150
- if (block.type === "section" && block.text?.type === "mrkdwn") {
151
- block.text.text = restoreSlackMrkdwnLinks(block.text.text, links);
119
+ function pushMarkdown(blocks, prose) {
120
+ const trimmed = prose.trim();
121
+ if (!trimmed)
122
+ return;
123
+ for (const chunk of splitProse(trimmed)) {
124
+ if (blocks.length >= MAX_BLOCKS)
125
+ return;
126
+ const text = chunk.trim();
127
+ if (text)
128
+ blocks.push({ type: "markdown", text });
152
129
  }
153
- else if (block.type === "table") {
154
- for (const row of block.rows) {
155
- for (const cell of row) {
156
- if ("text" in cell && typeof cell.text === "string") {
157
- cell.text = restoreSlackMrkdwnLinks(cell.text, links);
158
- }
159
- }
160
- }
130
+ }
131
+ function plainTextFallback(tokens) {
132
+ const parts = [];
133
+ for (const token of tokens) {
134
+ if (token.type === "inline")
135
+ parts.push(inlinePlainText(token.children) || token.content);
136
+ else if (token.type === "fence" || token.type === "code_block")
137
+ parts.push(token.content.trimEnd());
161
138
  }
162
- return block;
139
+ return parts.filter(Boolean).join("\n");
163
140
  }
164
141
  export function renderSlackBlocks(source) {
165
- const protectedSource = protectSlackMrkdwnLinks(normalizeMarkdownTables(source));
166
- const tokens = markdown.parse(protectedSource.source, {});
142
+ const normalized = normalizeMarkdownTables(convertLegacyMrkdwnLinks(source));
143
+ const tokens = markdown.parse(normalized, {});
144
+ const lines = normalized.split("\n");
145
+ const tables = [];
146
+ for (let i = 0; i < tokens.length; i++) {
147
+ const parsed = parseTable(tokens, i);
148
+ if (parsed) {
149
+ tables.push(parsed.table);
150
+ i = parsed.next;
151
+ }
152
+ }
167
153
  const blocks = [];
168
154
  const fallback = [];
169
- for (let i = 0; i < tokens.length && blocks.length < MAX_BLOCKS; i++) {
170
- const token = tokens[i];
171
- const table = parseTable(tokens, i);
172
- if (table) {
173
- blocks.push(...table.blocks.slice(0, MAX_BLOCKS - blocks.length));
155
+ let cursor = 0;
156
+ for (const table of tables) {
157
+ const prose = lines.slice(cursor, table.startLine).join("\n");
158
+ pushMarkdown(blocks, prose);
159
+ if (prose.trim())
160
+ fallback.push(plainTextFallback(markdown.parse(prose, {})));
161
+ if (blocks.length < MAX_BLOCKS) {
162
+ blocks.push(table.block);
174
163
  fallback.push(table.fallback);
175
- i = table.next;
176
- continue;
177
- }
178
- if (token.type === "heading_open") {
179
- const collected = collectInlineUntil(tokens, i + 1, "heading_close");
180
- const text = `*${collected.text}*`;
181
- pushSection(blocks, text);
182
- fallback.push(collected.text);
183
- i = collected.next;
184
- continue;
185
- }
186
- if (token.type === "paragraph_open") {
187
- const collected = collectInlineUntil(tokens, i + 1, "paragraph_close");
188
- pushSection(blocks, collected.text);
189
- fallback.push(collected.text);
190
- i = collected.next;
191
- continue;
192
- }
193
- if (token.type === "bullet_list_open" || token.type === "ordered_list_open") {
194
- const lines = [];
195
- let item = 1;
196
- for (i += 1; i < tokens.length && !tokens[i].type.endsWith("list_close"); i++) {
197
- if (tokens[i].type !== "inline")
198
- continue;
199
- const marker = token.type === "ordered_list_open" ? `${item++}.` : "•";
200
- lines.push(`${marker} ${renderInline(tokens[i].children) || tokens[i].content}`);
201
- }
202
- const text = lines.join("\n");
203
- pushSection(blocks, text);
204
- fallback.push(text);
205
- continue;
206
- }
207
- if (token.type === "fence" || token.type === "code_block") {
208
- const text = `\`\`\`\n${token.content}\n\`\`\``;
209
- pushSection(blocks, text);
210
- fallback.push(token.content);
211
164
  }
165
+ cursor = table.endLine;
212
166
  }
213
- if (!blocks.length)
214
- pushSection(blocks, protectedSource.source);
167
+ const trailingProse = lines.slice(cursor).join("\n");
168
+ pushMarkdown(blocks, trailingProse);
169
+ if (trailingProse.trim())
170
+ fallback.push(plainTextFallback(markdown.parse(trailingProse, {})));
215
171
  return {
216
- text: restoreSlackMrkdwnLinks(fallback.join("\n\n") || protectedSource.source, protectedSource.links),
217
- blocks: blocks.map((block) => restoreBlockLinks(block, protectedSource.links)),
172
+ text: fallback.filter(Boolean).join("\n\n") || normalized,
173
+ blocks,
218
174
  };
219
175
  }
220
176
  //# sourceMappingURL=blocks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"blocks.js","sourceRoot":"","sources":["../../../src/adapters/slack/blocks.ts"],"names":[],"mappings":"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","sourcesContent":["import MarkdownIt from \"markdown-it\";\nimport type Token from \"markdown-it/lib/token.mjs\";\nimport type { KnownBlock } from \"@slack/types\";\n\nconst markdown = new MarkdownIt({\n html: false,\n linkify: true,\n breaks: true,\n});\n\nconst MAX_BLOCKS = 50;\nconst SECTION_TEXT_LIMIT = 3000;\nconst FIELD_TEXT_LIMIT = 2000;\n\nfunction pushSection(blocks: KnownBlock[], text: string): void {\n const trimmed = text.trim();\n if (!trimmed) return;\n for (let i = 0; i < trimmed.length && blocks.length < MAX_BLOCKS; i += SECTION_TEXT_LIMIT) {\n blocks.push({\n type: \"section\",\n text: { type: \"mrkdwn\", text: trimmed.slice(i, i + SECTION_TEXT_LIMIT) },\n } as KnownBlock);\n }\n}\n\nfunction renderInline(tokens: Token[] | null | undefined): string {\n if (!tokens) return \"\";\n let text = \"\";\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n const linkText = tokens[i + 1];\n const linkClose = tokens[i + 2];\n if (\n token.type === \"link_open\" &&\n token.markup === \"autolink\" &&\n linkText?.type === \"text\" &&\n linkText.content.includes(\"|\") &&\n linkClose?.type === \"link_close\"\n ) {\n text += `<${linkText.content}>`;\n i += 2;\n } else if (token.type === \"text\" || token.type === \"code_inline\") text += token.content;\n else if (token.type === \"softbreak\" || token.type === \"hardbreak\") text += \"\\n\";\n else if (token.type === \"strong_open\") text += \"*\";\n else if (token.type === \"strong_close\") text += \"*\";\n else if (token.type === \"em_open\") text += \"_\";\n else if (token.type === \"em_close\") text += \"_\";\n else if (token.type === \"link_open\") {\n const href = token.attrGet(\"href\");\n if (href) text += `<${href}|`;\n } else if (token.type === \"link_close\") {\n text += \">\";\n } else if (token.children) {\n text += renderInline(token.children);\n }\n }\n return text;\n}\n\nfunction collectInlineUntil(\n tokens: Token[],\n index: number,\n endType: string,\n): { text: string; next: number } {\n let text = \"\";\n let i = index;\n for (; i < tokens.length && tokens[i].type !== endType; i++) {\n const token = tokens[i];\n if (token.type === \"inline\") text += renderInline(token.children) || token.content;\n else if (token.type === \"fence\" || token.type === \"code_block\")\n text += `\\n\\`\\`\\`\\n${token.content}\\n\\`\\`\\``;\n }\n return { text, next: i };\n}\n\nfunction isTableAt(tokens: Token[], index: number): boolean {\n return tokens[index]?.type === \"table_open\";\n}\n\nfunction buildTableBlock(headers: string[], rows: string[][]): KnownBlock {\n const hasIndex = headers[0] === \"#\";\n const tableHeaders = hasIndex ? headers : [\"#\", ...headers];\n const tableRows = hasIndex\n ? rows\n : rows.map((row, rowNumber) => [String(rowNumber + 1)].concat(row));\n return {\n type: \"table\",\n rows: [tableHeaders, ...tableRows].map((row) =>\n row.map((cell) => ({ type: \"raw_text\", text: (cell || \" \").slice(0, FIELD_TEXT_LIMIT) })),\n ),\n column_settings: tableHeaders.map(() => ({ is_wrapped: true })),\n } as KnownBlock;\n}\n\nfunction parseTable(\n tokens: Token[],\n index: number,\n): { blocks: KnownBlock[]; fallback: string; next: number } | null {\n if (!isTableAt(tokens, index)) return null;\n\n const headers: string[] = [];\n const rows: string[][] = [];\n let currentRow: string[] | null = null;\n let inHead = false;\n let i = index + 1;\n\n for (; i < tokens.length && tokens[i].type !== \"table_close\"; i++) {\n const token = tokens[i];\n if (token.type === \"thead_open\") inHead = true;\n else if (token.type === \"thead_close\") inHead = false;\n else if (token.type === \"tr_open\") currentRow = [];\n else if (token.type === \"tr_close\" && currentRow) {\n if (inHead) headers.push(...currentRow);\n else rows.push(currentRow);\n currentRow = null;\n } else if (token.type === \"inline\" && currentRow) {\n currentRow.push(renderInline(token.children) || token.content);\n }\n }\n\n if (!headers.length || !rows.length) return null;\n\n const fallback = [headers.join(\" | \"), ...rows.map((row) => row.join(\" | \"))].join(\"\\n\");\n return { blocks: [buildTableBlock(headers, rows)], fallback, next: i };\n}\n\nfunction normalizeMarkdownTables(source: string): string {\n return source\n .split(\"\\n\")\n .map((line) => {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"|\") || !trimmed.endsWith(\"|\")) return line;\n if (!/^[|+\\-:\\s]+$/.test(trimmed) || !trimmed.includes(\"+\")) return line;\n return line.replaceAll(\"+\", \"|\");\n })\n .join(\"\\n\");\n}\n\nconst SLACK_MRKDWN_LINK_PATTERN = /<https?:\\/\\/[^<>|\\s]+\\|[^<>\\n]+>/g;\n\nfunction protectSlackMrkdwnLinks(source: string): { source: string; links: string[] } {\n const links: string[] = [];\n const protectedSource = source.replace(SLACK_MRKDWN_LINK_PATTERN, (link) => {\n const index = links.push(link) - 1;\n return `MIKANSLACKLINK${index}PLACEHOLDER`;\n });\n return { source: protectedSource, links };\n}\n\nfunction restoreSlackMrkdwnLinks(text: string, links: string[]): string {\n return text.replace(/MIKANSLACKLINK(\\d+)PLACEHOLDER/g, (placeholder, indexText: string) => {\n return links[Number(indexText)] ?? placeholder;\n });\n}\n\nfunction restoreBlockLinks(block: KnownBlock, links: string[]): KnownBlock {\n if (block.type === \"section\" && block.text?.type === \"mrkdwn\") {\n block.text.text = restoreSlackMrkdwnLinks(block.text.text, links);\n } else if (block.type === \"table\") {\n for (const row of block.rows) {\n for (const cell of row) {\n if (\"text\" in cell && typeof cell.text === \"string\") {\n cell.text = restoreSlackMrkdwnLinks(cell.text, links);\n }\n }\n }\n }\n return block;\n}\n\nexport function renderSlackBlocks(source: string): { text: string; blocks: KnownBlock[] } {\n const protectedSource = protectSlackMrkdwnLinks(normalizeMarkdownTables(source));\n const tokens = markdown.parse(protectedSource.source, {});\n const blocks: KnownBlock[] = [];\n const fallback: string[] = [];\n\n for (let i = 0; i < tokens.length && blocks.length < MAX_BLOCKS; i++) {\n const token = tokens[i];\n\n const table = parseTable(tokens, i);\n if (table) {\n blocks.push(...table.blocks.slice(0, MAX_BLOCKS - blocks.length));\n fallback.push(table.fallback);\n i = table.next;\n continue;\n }\n\n if (token.type === \"heading_open\") {\n const collected = collectInlineUntil(tokens, i + 1, \"heading_close\");\n const text = `*${collected.text}*`;\n pushSection(blocks, text);\n fallback.push(collected.text);\n i = collected.next;\n continue;\n }\n\n if (token.type === \"paragraph_open\") {\n const collected = collectInlineUntil(tokens, i + 1, \"paragraph_close\");\n pushSection(blocks, collected.text);\n fallback.push(collected.text);\n i = collected.next;\n continue;\n }\n\n if (token.type === \"bullet_list_open\" || token.type === \"ordered_list_open\") {\n const lines: string[] = [];\n let item = 1;\n for (i += 1; i < tokens.length && !tokens[i].type.endsWith(\"list_close\"); i++) {\n if (tokens[i].type !== \"inline\") continue;\n const marker = token.type === \"ordered_list_open\" ? `${item++}.` : \"•\";\n lines.push(`${marker} ${renderInline(tokens[i].children) || tokens[i].content}`);\n }\n const text = lines.join(\"\\n\");\n pushSection(blocks, text);\n fallback.push(text);\n continue;\n }\n\n if (token.type === \"fence\" || token.type === \"code_block\") {\n const text = `\\`\\`\\`\\n${token.content}\\n\\`\\`\\``;\n pushSection(blocks, text);\n fallback.push(token.content);\n }\n }\n\n if (!blocks.length) pushSection(blocks, protectedSource.source);\n return {\n text: restoreSlackMrkdwnLinks(\n fallback.join(\"\\n\\n\") || protectedSource.source,\n protectedSource.links,\n ),\n blocks: blocks.map((block) => restoreBlockLinks(block, protectedSource.links)),\n };\n}\n"]}
1
+ {"version":3,"file":"blocks.js","sourceRoot":"","sources":["../../../src/adapters/slack/blocks.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,aAAa,CAAC;AAIrC,uEAAuE;AACvE,2EAA2E;AAC3E,yEAAyE;AACzE,0EAA0E;AAC1E,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAEjD,MAAM,UAAU,GAAG,EAAE,CAAC;AACtB,+EAA+E;AAC/E,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAClC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B,2EAA2E;AAC3E,yDAAyD;AACzD,MAAM,0BAA0B,GAAG,uCAAuC,CAAC;AAE3E,SAAS,wBAAwB,CAAC,MAAc;IAC9C,OAAO,MAAM,CAAC,OAAO,CAAC,0BAA0B,EAAE,UAAU,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,uBAAuB,CAAC,MAAc;IAC7C,OAAO,MAAM;SACV,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACpE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACzE,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACnC,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,SAAS,eAAe,CAAC,MAAkC;IACzD,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa;YAAE,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC;aAC5E,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;YAAE,IAAI,IAAI,IAAI,CAAC;aAC3E,IAAI,KAAK,CAAC,QAAQ;YAAE,IAAI,IAAI,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,eAAe,CAAC,OAAiB,EAAE,IAAgB;IAC1D,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;IACpC,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC;IAC5D,MAAM,SAAS,GAAG,QAAQ;QACxB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACtE,OAAO;QACL,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,CAAC,YAAY,EAAE,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC7C,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAC1F;QACD,eAAe,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;KAClD,CAAC;AAClB,CAAC;AASD,SAAS,UAAU,CAAC,MAAe,EAAE,KAAa;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,IAAI,EAAE,IAAI,KAAK,YAAY,IAAI,CAAC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAE1D,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAe,EAAE,CAAC;IAC5B,IAAI,UAAU,GAAoB,IAAI,CAAC;IACvC,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IAElB,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;QAClE,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;YAAE,MAAM,GAAG,IAAI,CAAC;aAC1C,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa;YAAE,MAAM,GAAG,KAAK,CAAC;aACjD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;YAAE,UAAU,GAAG,EAAE,CAAC;aAC9C,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,UAAU,EAAE,CAAC;YACjD,IAAI,MAAM;gBAAE,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;;gBACnC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC3B,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,UAAU,EAAE,CAAC;YACjD,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEjD,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzF,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACnD,OAAO;QACL,KAAK,EAAE;YACL,KAAK,EAAE,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC;YACrC,QAAQ;YACR,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YACtB,OAAO;SACR;QACD,IAAI,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED;qEACqE;AACrE,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,IAAI,CAAC,MAAM,IAAI,mBAAmB;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,OAAO,IAAI,CAAC,MAAM,GAAG,mBAAmB,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;QAClD,IAAI,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,GAAG,IAAI,CAAC;YAAE,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,GAAG,IAAI,CAAC;YAAE,GAAG,GAAG,mBAAmB,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAChC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,EAAE;QAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,YAAY,CAAC,MAAoB,EAAE,KAAa;IACvD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,IAAI,MAAM,CAAC,MAAM,IAAI,UAAU;YAAE,OAAO;QACxC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC1B,IAAI,IAAI;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAgB,CAAC,CAAC;IAClE,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAe;IACxC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;aACrF,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;YAC5D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,UAAU,GAAG,uBAAuB,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7E,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAErC,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACrC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;QAClB,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9D,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,EAAE;YAAE,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9E,IAAI,MAAM,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACzB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;IACzB,CAAC;IACD,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrD,YAAY,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACpC,IAAI,aAAa,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAE9F,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,UAAU;QACzD,MAAM;KACP,CAAC;AACJ,CAAC","sourcesContent":["import MarkdownIt from \"markdown-it\";\nimport type Token from \"markdown-it/lib/token.mjs\";\nimport type { KnownBlock } from \"@slack/types\";\n\n// Parser is used only to locate tables and derive plain-text fallback.\n// Prose is never re-serialized from tokens: it is sliced verbatim from the\n// source and handed to Slack as a native `markdown` block, so Slack owns\n// all prose rendering (same renderer as the markdown_text streaming API).\nconst markdown = new MarkdownIt({ html: false });\n\nconst MAX_BLOCKS = 50;\n// Slack rejects messages whose markdown block text exceeds 12k (msg_too_long).\nconst MARKDOWN_TEXT_LIMIT = 12000;\nconst FIELD_TEXT_LIMIT = 2000;\n\n// Legacy Slack-style links (<url|label>) predate the standard-GFM response\n// source contract; system producers may still emit them.\nconst LEGACY_MRKDWN_LINK_PATTERN = /<(https?:\\/\\/[^<>|\\s]+)\\|([^<>\\n]+)>/g;\n\nfunction convertLegacyMrkdwnLinks(source: string): string {\n return source.replace(LEGACY_MRKDWN_LINK_PATTERN, \"[$2]($1)\");\n}\n\nfunction normalizeMarkdownTables(source: string): string {\n return source\n .split(\"\\n\")\n .map((line) => {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"|\") || !trimmed.endsWith(\"|\")) return line;\n if (!/^[|+\\-:\\s]+$/.test(trimmed) || !trimmed.includes(\"+\")) return line;\n return line.replaceAll(\"+\", \"|\");\n })\n .join(\"\\n\");\n}\n\nfunction inlinePlainText(tokens: Token[] | null | undefined): string {\n if (!tokens) return \"\";\n let text = \"\";\n for (const token of tokens) {\n if (token.type === \"text\" || token.type === \"code_inline\") text += token.content;\n else if (token.type === \"softbreak\" || token.type === \"hardbreak\") text += \"\\n\";\n else if (token.children) text += inlinePlainText(token.children);\n }\n return text;\n}\n\nfunction buildTableBlock(headers: string[], rows: string[][]): KnownBlock {\n const hasIndex = headers[0] === \"#\";\n const tableHeaders = hasIndex ? headers : [\"#\", ...headers];\n const tableRows = hasIndex\n ? rows\n : rows.map((row, rowNumber) => [String(rowNumber + 1)].concat(row));\n return {\n type: \"table\",\n rows: [tableHeaders, ...tableRows].map((row) =>\n row.map((cell) => ({ type: \"raw_text\", text: (cell || \" \").slice(0, FIELD_TEXT_LIMIT) })),\n ),\n column_settings: tableHeaders.map(() => ({ is_wrapped: true })),\n } as KnownBlock;\n}\n\ninterface ParsedTable {\n block: KnownBlock;\n fallback: string;\n startLine: number;\n endLine: number;\n}\n\nfunction parseTable(tokens: Token[], index: number): { table: ParsedTable; next: number } | null {\n const open = tokens[index];\n if (open?.type !== \"table_open\" || !open.map) return null;\n\n const headers: string[] = [];\n const rows: string[][] = [];\n let currentRow: string[] | null = null;\n let inHead = false;\n let i = index + 1;\n\n for (; i < tokens.length && tokens[i].type !== \"table_close\"; i++) {\n const token = tokens[i];\n if (token.type === \"thead_open\") inHead = true;\n else if (token.type === \"thead_close\") inHead = false;\n else if (token.type === \"tr_open\") currentRow = [];\n else if (token.type === \"tr_close\" && currentRow) {\n if (inHead) headers.push(...currentRow);\n else rows.push(currentRow);\n currentRow = null;\n } else if (token.type === \"inline\" && currentRow) {\n currentRow.push(inlinePlainText(token.children) || token.content);\n }\n }\n\n if (!headers.length || !rows.length) return null;\n\n const fallback = [headers.join(\" | \"), ...rows.map((row) => row.join(\" | \"))].join(\"\\n\");\n const endLine = tokens[i]?.map?.[1] ?? open.map[1];\n return {\n table: {\n block: buildTableBlock(headers, rows),\n fallback,\n startLine: open.map[0],\n endLine,\n },\n next: i,\n };\n}\n\n/** Split prose into chunks under the markdown block limit, preferring\n * paragraph boundaries, then line boundaries, then a hard slice. */\nfunction splitProse(text: string): string[] {\n if (text.length <= MARKDOWN_TEXT_LIMIT) return [text];\n const chunks: string[] = [];\n let rest = text;\n while (rest.length > MARKDOWN_TEXT_LIMIT) {\n const window = rest.slice(0, MARKDOWN_TEXT_LIMIT);\n let cut = window.lastIndexOf(\"\\n\\n\");\n if (cut <= 0) cut = window.lastIndexOf(\"\\n\");\n if (cut <= 0) cut = MARKDOWN_TEXT_LIMIT;\n chunks.push(rest.slice(0, cut));\n rest = rest.slice(cut);\n }\n if (rest.trim()) chunks.push(rest);\n return chunks;\n}\n\nfunction pushMarkdown(blocks: KnownBlock[], prose: string): void {\n const trimmed = prose.trim();\n if (!trimmed) return;\n for (const chunk of splitProse(trimmed)) {\n if (blocks.length >= MAX_BLOCKS) return;\n const text = chunk.trim();\n if (text) blocks.push({ type: \"markdown\", text } as KnownBlock);\n }\n}\n\nfunction plainTextFallback(tokens: Token[]): string {\n const parts: string[] = [];\n for (const token of tokens) {\n if (token.type === \"inline\") parts.push(inlinePlainText(token.children) || token.content);\n else if (token.type === \"fence\" || token.type === \"code_block\")\n parts.push(token.content.trimEnd());\n }\n return parts.filter(Boolean).join(\"\\n\");\n}\n\nexport function renderSlackBlocks(source: string): { text: string; blocks: KnownBlock[] } {\n const normalized = normalizeMarkdownTables(convertLegacyMrkdwnLinks(source));\n const tokens = markdown.parse(normalized, {});\n const lines = normalized.split(\"\\n\");\n\n const tables: ParsedTable[] = [];\n for (let i = 0; i < tokens.length; i++) {\n const parsed = parseTable(tokens, i);\n if (parsed) {\n tables.push(parsed.table);\n i = parsed.next;\n }\n }\n\n const blocks: KnownBlock[] = [];\n const fallback: string[] = [];\n let cursor = 0;\n for (const table of tables) {\n const prose = lines.slice(cursor, table.startLine).join(\"\\n\");\n pushMarkdown(blocks, prose);\n if (prose.trim()) fallback.push(plainTextFallback(markdown.parse(prose, {})));\n if (blocks.length < MAX_BLOCKS) {\n blocks.push(table.block);\n fallback.push(table.fallback);\n }\n cursor = table.endLine;\n }\n const trailingProse = lines.slice(cursor).join(\"\\n\");\n pushMarkdown(blocks, trailingProse);\n if (trailingProse.trim()) fallback.push(plainTextFallback(markdown.parse(trailingProse, {})));\n\n return {\n text: fallback.filter(Boolean).join(\"\\n\\n\") || normalized,\n blocks,\n };\n}\n"]}
@@ -42,6 +42,7 @@ export declare class SlackMessagingBot implements MessagingBot {
42
42
  postEphemeral(channel: string, user: string, text: string, threadTs?: string): Promise<void>;
43
43
  postEphemeralBlocks(channel: string, user: string, text: string, blocks: object[], threadTs?: string): Promise<void>;
44
44
  postMessageBlocks(channel: string, text: string, blocks: object[]): Promise<string>;
45
+ updateMessageBlocks(channel: string, ts: string, text: string, blocks: object[]): Promise<void>;
45
46
  postPrivate(conversationId: string, userId: string, text: string): Promise<void>;
46
47
  postPrivateDiagnostic(conversationId: string, userId: string, text: string, options?: {
47
48
  style?: "muted" | "error";
@@ -1 +1 @@
1
- {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/bot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/bot.ts"],"names":[],"mappings":"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"}