@skaile/workspaces 1.14.1 → 1.15.0

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 (190) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/NOTICE +13 -0
  3. package/dist/app-sdk/index.js +1 -1
  4. package/dist/{asset-feeds-ZQLJ2DCP.js → asset-feeds-MWEMXMZA.js} +5 -5
  5. package/dist/{asset-feeds-ZQLJ2DCP.js.map → asset-feeds-MWEMXMZA.js.map} +1 -1
  6. package/dist/asset-manager/index.js +5 -5
  7. package/dist/asset-manager/installer.js +1 -1
  8. package/dist/bridge/drivers/claude-sdk.js +1 -1
  9. package/dist/bridge/drivers/codex.js +1 -1
  10. package/dist/bridge/drivers/continue.js +2 -2
  11. package/dist/bridge/drivers/echo.js +1 -1
  12. package/dist/bridge/drivers/gemini.js +3 -3
  13. package/dist/bridge/drivers/goose.js +2 -2
  14. package/dist/bridge/drivers/omp.js +1 -1
  15. package/dist/bridge/drivers/opencode.js +2 -2
  16. package/dist/bridge/drivers/qwen.js +3 -3
  17. package/dist/bridge/index.js +2 -2
  18. package/dist/channels/adapters/msteams/activity.d.ts +70 -0
  19. package/dist/channels/adapters/msteams/activity.d.ts.map +1 -0
  20. package/dist/channels/adapters/msteams/client.d.ts +46 -0
  21. package/dist/channels/adapters/msteams/client.d.ts.map +1 -0
  22. package/dist/channels/adapters/msteams/index.d.ts +81 -0
  23. package/dist/channels/adapters/msteams/index.d.ts.map +1 -0
  24. package/dist/channels/adapters/msteams/jwt.d.ts +27 -0
  25. package/dist/channels/adapters/msteams/jwt.d.ts.map +1 -0
  26. package/dist/channels/adapters/msteams.d.ts +2 -0
  27. package/dist/channels/adapters/msteams.js +595 -0
  28. package/dist/channels/adapters/msteams.js.map +1 -0
  29. package/dist/channels/index.d.ts +2 -0
  30. package/dist/channels/index.js +1069 -0
  31. package/dist/channels/index.js.map +1 -0
  32. package/dist/channels/src/adapter.d.ts +54 -0
  33. package/dist/channels/src/adapter.d.ts.map +1 -0
  34. package/dist/channels/src/dedupe.d.ts +67 -0
  35. package/dist/channels/src/dedupe.d.ts.map +1 -0
  36. package/dist/channels/src/egress/output-mirror.d.ts +63 -0
  37. package/dist/channels/src/egress/output-mirror.d.ts.map +1 -0
  38. package/dist/channels/src/egress/vendor/auto-close-streaming.d.ts +26 -0
  39. package/dist/channels/src/egress/vendor/auto-close-streaming.d.ts.map +1 -0
  40. package/dist/channels/src/egress/vendor/chunked-message-stream.d.ts +79 -0
  41. package/dist/channels/src/egress/vendor/chunked-message-stream.d.ts.map +1 -0
  42. package/dist/channels/src/egress/vendor/markdown-to-mrkdwn.d.ts +21 -0
  43. package/dist/channels/src/egress/vendor/markdown-to-mrkdwn.d.ts.map +1 -0
  44. package/dist/channels/src/egress/vendor/message-stream.d.ts +57 -0
  45. package/dist/channels/src/egress/vendor/message-stream.d.ts.map +1 -0
  46. package/dist/channels/src/engine.d.ts +125 -0
  47. package/dist/channels/src/engine.d.ts.map +1 -0
  48. package/dist/channels/src/format/adaptive-card.d.ts +17 -0
  49. package/dist/channels/src/format/adaptive-card.d.ts.map +1 -0
  50. package/dist/channels/src/format/mrkdwn.d.ts +4 -0
  51. package/dist/channels/src/format/mrkdwn.d.ts.map +1 -0
  52. package/dist/channels/src/format/types.d.ts +9 -0
  53. package/dist/channels/src/format/types.d.ts.map +1 -0
  54. package/dist/channels/src/index.d.ts +17 -0
  55. package/dist/channels/src/index.d.ts.map +1 -0
  56. package/dist/channels/src/mention/lookup-tool.d.ts +23 -0
  57. package/dist/channels/src/mention/lookup-tool.d.ts.map +1 -0
  58. package/dist/channels/src/mention/normalize.d.ts +27 -0
  59. package/dist/channels/src/mention/normalize.d.ts.map +1 -0
  60. package/dist/channels/src/mention/render.d.ts +10 -0
  61. package/dist/channels/src/mention/render.d.ts.map +1 -0
  62. package/dist/channels/src/ports.d.ts +71 -0
  63. package/dist/channels/src/ports.d.ts.map +1 -0
  64. package/dist/channels/src/types.d.ts +169 -0
  65. package/dist/channels/src/types.d.ts.map +1 -0
  66. package/dist/{chunk-A7GDV5BV.js → chunk-2BQBWWFX.js} +2 -2
  67. package/dist/{chunk-A7GDV5BV.js.map → chunk-2BQBWWFX.js.map} +1 -1
  68. package/dist/{chunk-MWE7DEGC.js → chunk-344DEXZS.js} +3 -3
  69. package/dist/{chunk-MWE7DEGC.js.map → chunk-344DEXZS.js.map} +1 -1
  70. package/dist/{chunk-CC6LFFTI.js → chunk-6ZLMG5GR.js} +4 -4
  71. package/dist/{chunk-CC6LFFTI.js.map → chunk-6ZLMG5GR.js.map} +1 -1
  72. package/dist/{chunk-T2H2ZCU4.js → chunk-73HV7RV3.js} +3 -3
  73. package/dist/{chunk-T2H2ZCU4.js.map → chunk-73HV7RV3.js.map} +1 -1
  74. package/dist/{chunk-P5VLR3L7.js → chunk-BI2NKPA4.js} +8 -4
  75. package/dist/chunk-BI2NKPA4.js.map +1 -0
  76. package/dist/{chunk-IIGWJE5T.js → chunk-DPUZJI45.js} +3 -3
  77. package/dist/{chunk-IIGWJE5T.js.map → chunk-DPUZJI45.js.map} +1 -1
  78. package/dist/chunk-F2IBDVBP.js +72 -0
  79. package/dist/chunk-F2IBDVBP.js.map +1 -0
  80. package/dist/{chunk-G73FOLLO.js → chunk-F3ET4UGP.js} +3 -3
  81. package/dist/{chunk-G73FOLLO.js.map → chunk-F3ET4UGP.js.map} +1 -1
  82. package/dist/{chunk-ZWPXSHMW.js → chunk-HA53HVIS.js} +336 -100
  83. package/dist/chunk-HA53HVIS.js.map +1 -0
  84. package/dist/{chunk-HLIN4HRK.js → chunk-LTQOZIJO.js} +2 -2
  85. package/dist/{chunk-HLIN4HRK.js.map → chunk-LTQOZIJO.js.map} +1 -1
  86. package/dist/{chunk-CS6NFRNQ.js → chunk-MJEUK6VJ.js} +2 -2
  87. package/dist/{chunk-CS6NFRNQ.js.map → chunk-MJEUK6VJ.js.map} +1 -1
  88. package/dist/{chunk-AF2NTM4B.js → chunk-NRXVS7E4.js} +6 -6
  89. package/dist/{chunk-AF2NTM4B.js.map → chunk-NRXVS7E4.js.map} +1 -1
  90. package/dist/{chunk-UDUFMVJD.js → chunk-RADBQ5XJ.js} +7 -7
  91. package/dist/{chunk-UDUFMVJD.js.map → chunk-RADBQ5XJ.js.map} +1 -1
  92. package/dist/{chunk-TSB46BHR.js → chunk-RDE43ORT.js} +4 -4
  93. package/dist/{chunk-TSB46BHR.js.map → chunk-RDE43ORT.js.map} +1 -1
  94. package/dist/{chunk-4RI4TNMO.js → chunk-SELNYOEO.js} +2 -2
  95. package/dist/{chunk-4RI4TNMO.js.map → chunk-SELNYOEO.js.map} +1 -1
  96. package/dist/{chunk-KECY74AL.js → chunk-SRWIVMJI.js} +4 -4
  97. package/dist/{chunk-KECY74AL.js.map → chunk-SRWIVMJI.js.map} +1 -1
  98. package/dist/{chunk-VK24PIAB.js → chunk-TFIFNDT2.js} +3 -3
  99. package/dist/{chunk-VK24PIAB.js.map → chunk-TFIFNDT2.js.map} +1 -1
  100. package/dist/{chunk-NIZNN42B.js → chunk-XW3SWH7C.js} +3 -3
  101. package/dist/{chunk-NIZNN42B.js.map → chunk-XW3SWH7C.js.map} +1 -1
  102. package/dist/{chunk-BIAA3N2A.js → chunk-Z6NGK5YC.js} +3 -3
  103. package/dist/{chunk-BIAA3N2A.js.map → chunk-Z6NGK5YC.js.map} +1 -1
  104. package/dist/cli/index.js +41 -41
  105. package/dist/connectors/config.js +1 -1
  106. package/dist/connectors/index.js +1 -1
  107. package/dist/core/index.js +1 -1
  108. package/dist/deploy/index.js +1 -1
  109. package/dist/{ensure-sources-O7X3LYLG.js → ensure-sources-QGL44IRI.js} +8 -8
  110. package/dist/{ensure-sources-O7X3LYLG.js.map → ensure-sources-QGL44IRI.js.map} +1 -1
  111. package/dist/factory-assets/connectors/box.js +1 -1
  112. package/dist/factory-assets/connectors/deploy.js +1 -1
  113. package/dist/factory-assets/connectors/devserver.js +1 -1
  114. package/dist/factory-assets/connectors/flow/adapter.js +1 -1
  115. package/dist/factory-assets/connectors/flow/engine.js +1 -1
  116. package/dist/factory-assets/connectors/flow/run-flow.js +2 -2
  117. package/dist/factory-assets/connectors/flow.js +1 -1
  118. package/dist/factory-assets/connectors/git.js +1 -1
  119. package/dist/factory-assets/connectors/gmail.js +1 -1
  120. package/dist/factory-assets/connectors/googledrive.js +1 -1
  121. package/dist/factory-assets/connectors/local.js +1 -1
  122. package/dist/factory-assets/connectors/mattermost.js +1 -1
  123. package/dist/factory-assets/connectors/memory.js +1 -1
  124. package/dist/factory-assets/connectors/minio.js +1 -1
  125. package/dist/factory-assets/connectors/postgres.js +1 -1
  126. package/dist/factory-assets/connectors/s3.js +1 -1
  127. package/dist/factory-assets/connectors/sharepoint.js +1 -1
  128. package/dist/factory-assets/connectors/sqlite.js +1 -1
  129. package/dist/factory-assets/connectors/static-server.js +1 -1
  130. package/dist/factory-assets/connectors/tunnel.js +1 -1
  131. package/dist/factory-assets/connectors/webdav.js +1 -1
  132. package/dist/factory-assets/connectors/xstate-store.js +1 -1
  133. package/dist/factory-assets/connectors/xstate.js +1 -1
  134. package/dist/{flows-TIUWM7SZ.js → flows-FHWBCLXF.js} +3 -3
  135. package/dist/{flows-TIUWM7SZ.js.map → flows-FHWBCLXF.js.map} +1 -1
  136. package/dist/{helpers-DNTGJSA5.js → helpers-FMWODXTW.js} +8 -8
  137. package/dist/{helpers-DNTGJSA5.js.map → helpers-FMWODXTW.js.map} +1 -1
  138. package/dist/library/index.js +4 -4
  139. package/dist/library/install.js +1 -1
  140. package/dist/{library-publish-XKQN6RTR.js → library-publish-7YDHQGBN.js} +10 -10
  141. package/dist/{library-publish-XKQN6RTR.js.map → library-publish-7YDHQGBN.js.map} +1 -1
  142. package/dist/{open-library-2BWIUK4F.js → open-library-O6T3ELPK.js} +9 -9
  143. package/dist/{open-library-2BWIUK4F.js.map → open-library-O6T3ELPK.js.map} +1 -1
  144. package/dist/{paths-KOKCMBL5.js → paths-5QJJBAND.js} +7 -7
  145. package/dist/{paths-KOKCMBL5.js.map → paths-5QJJBAND.js.map} +1 -1
  146. package/dist/{plugin-store-QMJ2B3VM.js → plugin-store-ZBJZ7F6D.js} +3 -3
  147. package/dist/{plugin-store-QMJ2B3VM.js.map → plugin-store-ZBJZ7F6D.js.map} +1 -1
  148. package/dist/{project-4NPDM7R3.js → project-HAMLHLD5.js} +9 -9
  149. package/dist/{project-4NPDM7R3.js.map → project-HAMLHLD5.js.map} +1 -1
  150. package/dist/runner/index.js +8 -8
  151. package/dist/runner/src/serve.d.ts +138 -1
  152. package/dist/runner/src/serve.d.ts.map +1 -1
  153. package/dist/sdk/asset-manager.js +5 -5
  154. package/dist/sdk/bridge.js +2 -2
  155. package/dist/sdk/core.js +1 -1
  156. package/dist/sdk/flow.js +1 -1
  157. package/dist/sdk/index.js +8 -8
  158. package/dist/sdk/runner.js +8 -8
  159. package/dist/sdk/session.js +2 -2
  160. package/dist/sdk/transport/ws.js +1 -1
  161. package/dist/sdk/transport.js +1 -1
  162. package/dist/sdk/types.js +1 -1
  163. package/dist/session/index.js +2 -2
  164. package/dist/session/src/dispatcher.d.ts.map +1 -1
  165. package/dist/{setup-TNHKXCBL.js → setup-OJC74Q2Q.js} +5 -5
  166. package/dist/{setup-TNHKXCBL.js.map → setup-OJC74Q2Q.js.map} +1 -1
  167. package/dist/{source-HVMQJZU7.js → source-ITDH4367.js} +10 -10
  168. package/dist/{source-HVMQJZU7.js.map → source-ITDH4367.js.map} +1 -1
  169. package/dist/{source-manifest-publish-JN62UMZD.js → source-manifest-publish-RMHC7R6M.js} +11 -11
  170. package/dist/{source-manifest-publish-JN62UMZD.js.map → source-manifest-publish-RMHC7R6M.js.map} +1 -1
  171. package/dist/transport/index.js +1 -1
  172. package/dist/transport/ws.js +1 -1
  173. package/dist/tui/index.js +8 -8
  174. package/dist/types/index.js +1 -1
  175. package/dist/types/src/events.d.ts +74 -1
  176. package/dist/types/src/events.d.ts.map +1 -1
  177. package/dist/types/src/flow.d.ts +34 -0
  178. package/dist/types/src/flow.d.ts.map +1 -1
  179. package/dist/types/src/index.d.ts +2 -2
  180. package/dist/types/src/index.d.ts.map +1 -1
  181. package/dist/types/src/protocol.d.ts +6 -0
  182. package/dist/types/src/protocol.d.ts.map +1 -1
  183. package/dist/types/src/version.d.ts +23 -1
  184. package/dist/types/src/version.d.ts.map +1 -1
  185. package/dist/workspace-plugin/adapters/mcp.js +1 -1
  186. package/dist/workspace-plugin/adapters/omp.js +3 -3
  187. package/dist/workspace-plugin/index.js +1 -1
  188. package/package.json +15 -2
  189. package/dist/chunk-P5VLR3L7.js.map +0 -1
  190. package/dist/chunk-ZWPXSHMW.js.map +0 -1
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Options for {@link SerializedMessageStream}.
3
+ */
4
+ export interface SerializedMessageStreamOptions {
5
+ /** Writes `content` to the platform message (e.g. an edit/update call). */
6
+ apply: (content: string) => Promise<void>;
7
+ /** Minimum gap between consecutive applies, in ms. `flush()` bypasses it. */
8
+ throttleMs: number;
9
+ /**
10
+ * Sink for a failed `apply`; defaults to `console.error`. The failure is
11
+ * swallowed after reporting: a failed FINAL apply leaves the platform
12
+ * message stale, and nothing retries it unless newer content arrives.
13
+ */
14
+ onApplyError?: (err: unknown) => void;
15
+ /** Clock override for tests; defaults to `Date.now`. */
16
+ now?: () => number;
17
+ }
18
+ /**
19
+ * Per-message streaming text state machine.
20
+ *
21
+ * Wraps a single posted platform message and lets callers feed it the growing
22
+ * text buffer of a streaming reply. Edits are throttled (chat platforms
23
+ * rate-limit message updates) and *serialised* through a per-message promise
24
+ * queue so concurrent updates can't race — a hazard the upstream project hit,
25
+ * where an end-triggered flush of "ALPHA" could be overtaken by an in-flight
26
+ * flush of "AL" and the final state read "AL".
27
+ *
28
+ * Guarantees: at most one `apply` in flight; applies happen in enqueue order;
29
+ * a newer `enqueue` supersedes older un-applied content (no stale flush); no
30
+ * `apply` more often than `throttleMs` except on `flush()`.
31
+ */
32
+ export declare class SerializedMessageStream {
33
+ private buffer;
34
+ private applied;
35
+ private queue;
36
+ private lastApplyAt;
37
+ private flushTimer;
38
+ private readonly throttleMs;
39
+ private readonly apply;
40
+ private readonly onApplyError;
41
+ private readonly now;
42
+ constructor(opts: SerializedMessageStreamOptions);
43
+ /** Replace the in-flight buffer (callers pass the accumulated text). */
44
+ enqueue(content: string): void;
45
+ /**
46
+ * Mark the stream done. Cancels any pending throttled flush, enqueues a
47
+ * final flush, and resolves once the entire queue (including the final
48
+ * flush and anything previously in flight) has drained.
49
+ *
50
+ * After this resolves, the platform message reflects the final buffer state.
51
+ */
52
+ flush(): Promise<void>;
53
+ private scheduleFlush;
54
+ private enqueueFlush;
55
+ private flushNow;
56
+ }
57
+ //# sourceMappingURL=message-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-stream.d.ts","sourceRoot":"","sources":["../../../../../channels/src/egress/vendor/message-stream.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C,2EAA2E;IAC3E,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,OAAO,CAAM;IACrB,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,UAAU,CAA4C;IAC9D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAC3D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyB;IACtD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,IAAI,EAAE,8BAA8B;IAQhD,wEAAwE;IACxE,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAM9B;;;;;;OAMG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,YAAY;YAIN,QAAQ;CAiBvB"}
@@ -0,0 +1,125 @@
1
+ import type { ChannelAdapter, ChannelLogger, IngressSink } from "./adapter.js";
2
+ import type { DedupeStore } from "./dedupe.js";
3
+ import type { BindingStore, CredentialPort, IdentityPort, IngressHost, SessionPort } from "./ports.js";
4
+ import type { Binding, ChannelPlatform, ConversationKey } from "./types.js";
5
+ /**
6
+ * Notice posted when `unmappedActorPolicy === "reject"` turns an inbound
7
+ * message away — ephemeral where the surface supports it, a threaded regular
8
+ * reply otherwise.
9
+ */
10
+ export declare const REJECT_NOTICE: string;
11
+ /** The five host-owned ports the engine consumes (spec §4.2). */
12
+ export type ChannelEnginePorts = {
13
+ session: SessionPort;
14
+ identity: IdentityPort;
15
+ bindings: BindingStore;
16
+ credentials: CredentialPort;
17
+ ingress: IngressHost;
18
+ };
19
+ /** Options for {@link ChannelEngine}. */
20
+ export type ChannelEngineOptions = {
21
+ adapters: ChannelAdapter[];
22
+ ports: ChannelEnginePorts;
23
+ /** Inbound eventId dedupe store. Default a 10-min {@link TtlDedupeStore}. */
24
+ dedupe?: DedupeStore;
25
+ /** Post a "Thinking…" status if no agent text within this after deliver. Default 5000. */
26
+ placeholderAfterMs?: number;
27
+ /** Policy for actors IdentityPort cannot map. Default "reject" (ephemeral notice). */
28
+ unmappedActorPolicy?: "reject" | "external-framed";
29
+ logger?: ChannelLogger;
30
+ /** Clock override for tests. Default `Date.now`. */
31
+ now?: () => number;
32
+ /**
33
+ * Bindings the host restored from its store on boot. `start()` runs the
34
+ * conversation preflight per binding — logging (not throwing) failures with
35
+ * their actionable messages — and starts mirroring the enabled ones.
36
+ */
37
+ initialBindings?: Binding[];
38
+ };
39
+ /**
40
+ * Runs the channels data flow for a set of adapters against one host's ports.
41
+ *
42
+ * Ingress (spec §7.1): `sinkFor(platform)` hands each adapter an engine-owned
43
+ * {@link IngressSink} whose `onMessage` fast-acks — loop-guard and dedupe
44
+ * checks are synchronous, everything else detaches. Reactions and
45
+ * conversation events are logged and dropped this milestone.
46
+ *
47
+ * Egress (spec §7.2): one {@link OutputMirror} + SessionPort subscription per
48
+ * active binding, created by `bind()` / `initialBindings` / lazy bot-mention
49
+ * bind — and self-healing on delivery to a bound conversation whose mirror is
50
+ * not yet up. Every posted MessageRef lands in the egress-ref registry so its
51
+ * echo can never re-ingest.
52
+ */
53
+ export declare class ChannelEngine {
54
+ private readonly opts;
55
+ private readonly logger;
56
+ private readonly dedupe;
57
+ private readonly now;
58
+ private readonly unmappedActorPolicy;
59
+ private readonly adaptersByPlatform;
60
+ private readonly sinks;
61
+ /** Canonical `${platform}:${messageId}` keys of every message this engine posted (TTL-bounded). */
62
+ private readonly egressRefs;
63
+ private readonly states;
64
+ /** Per-conversation serial chains — ingress, bind() and unbind() all queue here (self-removing). */
65
+ private readonly conversationChains;
66
+ private readonly placeholderAfterMs;
67
+ private placeholderSeq;
68
+ constructor(opts: ChannelEngineOptions);
69
+ /**
70
+ * Starts every adapter with an engine-owned IngressSink, then restores
71
+ * `initialBindings`: preflight each (logging failures) and start mirroring
72
+ * the enabled ones (spec §7.3 "on engine start").
73
+ */
74
+ start(): Promise<void>;
75
+ /** Disposes all mirrors, unsubscribes, and stops all adapters. */
76
+ stop(): Promise<void>;
77
+ /**
78
+ * Verifies the conversation (adapter.verifyConversation), persists the
79
+ * binding, and starts mirroring. Throws with the health problems on failure.
80
+ * Rebinding an already-bound key replaces its mirror. The state mutation is
81
+ * serialized on the conversation's chain, so a concurrent inbound lazy bind
82
+ * either happens-before (and is replaced) or happens-after (and sees this
83
+ * binding); the preflight stays outside the chain.
84
+ */
85
+ bind(binding: Binding): Promise<void>;
86
+ /** Stops mirroring and removes the binding from the store (serialized per key). */
87
+ unbind(key: ConversationKey): Promise<void>;
88
+ /** The engine's sink for a given platform's adapter. Throws on an unknown platform. */
89
+ sinkFor(platform: ChannelPlatform): IngressSink;
90
+ private adapterFor;
91
+ /** Fast-ack intake (spec §7.1.3): synchronous checks only, then detach. */
92
+ private onMessage;
93
+ /**
94
+ * Appends `task` to the conversation's serial chain and returns its result.
95
+ * Every state mutation for one key — detached ingress, `bind()`, `unbind()`
96
+ * — runs through here, so an inbound lazy bind can never interleave with a
97
+ * host-initiated rebind. The chain entry removes itself once drained.
98
+ */
99
+ private enqueueOnKey;
100
+ /**
101
+ * Detaches ingress work onto the per-conversation chain: concurrent
102
+ * messages for the same key run in arrival order, so the lazy-bind window
103
+ * (bindings.get → createSession → bindings.put) can never race itself.
104
+ */
105
+ private enqueueIngress;
106
+ /** Detached ingress work: identity, routing, lazy bind, attributed delivery. */
107
+ private process;
108
+ /** "Teams: <snippet>" — title for a lazily-created thread session. */
109
+ private sessionTitle;
110
+ /** Reject notice: ephemeral where supported; threaded regular reply otherwise. */
111
+ private postRejectNotice;
112
+ private stateFor;
113
+ /** Idempotent: one OutputMirror + session subscription per bound conversation. */
114
+ private ensureMirror;
115
+ /** Engine-side filtering in front of the mirror: placeholder, loop guard, turn origin. */
116
+ private onAgentEvent;
117
+ /** One-shot "_Thinking…_" status if the agent stays silent after a delivery (spec §7.1.7). */
118
+ private armPlaceholder;
119
+ private disarmPlaceholder;
120
+ /** Bind-time preflight in log-only form, for engine-start restoration. */
121
+ private verifyOrLog;
122
+ /** Disarm, unsubscribe, and flush/dispose the mirror of one binding. */
123
+ private teardownState;
124
+ }
125
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../channels/src/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Teams-facing formatting: text normalization for the markdown subset Teams
3
+ * renders, plus Adaptive Card construction for question posts with options.
4
+ */
5
+ import type { FormatConverter } from "./types.js";
6
+ /**
7
+ * Teams' supported markdown subset pass-through: normalizes constructs Teams
8
+ * cannot render (~~strike~~ → plain, heading # → bold line); everything else
9
+ * verbatim. Line-based on purpose — no markdown parser; fenced code passes
10
+ * through untouched.
11
+ */
12
+ export declare function markdownToTeamsText(markdown: string): string;
13
+ /** Adaptive Card 1.4 JSON for a question with option buttons (Action.Submit, data: { option }). */
14
+ export declare function makeQuestionCard(markdown: string, options: string[]): Record<string, unknown>;
15
+ /** {@link FormatConverter} for adapters whose `textFormat` is `"adaptive-card"` (Teams). */
16
+ export declare const teamsFormatConverter: FormatConverter;
17
+ //# sourceMappingURL=adaptive-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adaptive-card.d.ts","sourceRoot":"","sources":["../../../../channels/src/format/adaptive-card.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAe5D;AAED,mGAAmG;AACnG,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAY7F;AAED,4FAA4F;AAC5F,eAAO,MAAM,oBAAoB,EAAE,eAAyD,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { FormatConverter } from "./types.js";
2
+ /** {@link FormatConverter} for adapters whose `textFormat` is `"mrkdwn"` (Slack). */
3
+ export declare const mrkdwnFormatConverter: FormatConverter;
4
+ //# sourceMappingURL=mrkdwn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mrkdwn.d.ts","sourceRoot":"","sources":["../../../../channels/src/format/mrkdwn.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,qFAAqF;AACrF,eAAO,MAAM,qBAAqB,EAAE,eAAsD,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Format-layer contract: outbound engine-markdown → platform text dialect.
3
+ * One converter exists per `SurfaceCapabilities.textFormat` value.
4
+ */
5
+ /** Converts engine-markdown to a platform text dialect. One per SurfaceCapabilities.textFormat. */
6
+ export interface FormatConverter {
7
+ toPlatformText(markdown: string): string;
8
+ }
9
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../channels/src/format/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,mGAAmG;AACnG,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1C"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Public surface of `@skaile/workspaces/channels` — the chat-platform bridge
3
+ * layer: core types, the per-platform adapter contract, and host-owned ports.
4
+ */
5
+ export * from "./adapter.js";
6
+ export * from "./dedupe.js";
7
+ export * from "./egress/output-mirror.js";
8
+ export * from "./engine.js";
9
+ export * from "./format/adaptive-card.js";
10
+ export * from "./format/mrkdwn.js";
11
+ export * from "./format/types.js";
12
+ export * from "./mention/lookup-tool.js";
13
+ export * from "./mention/normalize.js";
14
+ export * from "./mention/render.js";
15
+ export * from "./ports.js";
16
+ export * from "./types.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../channels/src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The `lookup_user` helper behind outbound mentions-as-a-tool (spec §6.1).
3
+ * Ships as a plain builder this milestone — later rollout steps register it
4
+ * as a capability/tool-face (plan Decision 16).
5
+ */
6
+ import type { ChannelAdapter } from "../adapter.js";
7
+ import type { ActorQuery } from "../types.js";
8
+ import type { MentionRenderer } from "./render.js";
9
+ /** The `lookup_user` tool shape: query a platform user, get a mention token to paste. */
10
+ export type LookupUserTool = {
11
+ name: "lookup_user";
12
+ description: string;
13
+ run(query: ActorQuery): Promise<{
14
+ found: boolean;
15
+ mentionToken?: string;
16
+ displayName?: string;
17
+ }>;
18
+ };
19
+ /** Builds the lookup tool over an adapter; later rollout steps register it as a capability/tool-face. */
20
+ export declare function buildLookupUserTool(adapter: ChannelAdapter, renderer: MentionRenderer): LookupUserTool;
21
+ /** Prompt fragment instructing the model to call lookup_user and paste the token verbatim. */
22
+ export declare const LOOKUP_USER_PROMPT_FRAGMENT: string;
23
+ //# sourceMappingURL=lookup-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lookup-tool.d.ts","sourceRoot":"","sources":["../../../../channels/src/mention/lookup-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,yFAAyF;AACzF,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClG,CAAC;AAEF,yGAAyG;AACzG,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,eAAe,GACxB,cAAc,CAehB;AAED,8FAA8F;AAC9F,eAAO,MAAM,2BAA2B,QAGoD,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Inbound mention normalization (spec §6.1): adapter-parsed platform mention
3
+ * entities → the existing `Mention` union. This touches INBOUND platform
4
+ * entities only — the platform's session-member mention grammar is untouched
5
+ * (spec §12).
6
+ */
7
+ import type { Mention } from "@skaile/workspaces/types";
8
+ import type { IdentityPort } from "../ports.js";
9
+ import type { ChannelActor } from "../types.js";
10
+ /** A platform mention entity as the adapter parsed it, pre-identity-resolution. */
11
+ export type ChannelMentionEntity = {
12
+ externalId: string;
13
+ displayName: string;
14
+ /** True when the entity is the bot itself (adapter compares against its own id). */
15
+ isBot: boolean;
16
+ offset: number;
17
+ length: number;
18
+ };
19
+ /**
20
+ * Normalizes adapter-parsed mention entities into the existing Mention union
21
+ * (spec §6.1): bot → { type:"group", group:"agent" }; mapped user → user;
22
+ * unmapped → { type:"custom", kind:"external", data:{ platform, externalUserId } }.
23
+ */
24
+ export declare function normalizeMentions(entities: ChannelMentionEntity[], actorOf: (e: ChannelMentionEntity) => ChannelActor, identity: IdentityPort): Promise<Mention[]>;
25
+ /** True when any normalized mention addresses the agent (bot-mention gate, spec §7.1.6). */
26
+ export declare function mentionsAgent(mentions: Mention[]): boolean;
27
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../channels/src/mention/normalize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,mFAAmF;AACnF,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,oBAAoB,EAAE,EAChC,OAAO,EAAE,CAAC,CAAC,EAAE,oBAAoB,KAAK,YAAY,EAClD,QAAQ,EAAE,YAAY,GACrB,OAAO,CAAC,OAAO,EAAE,CAAC,CAiBpB;AAED,4FAA4F;AAC5F,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAE1D"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Outbound mention rendering seam. Each adapter supplies a renderer producing
3
+ * its platform-native token (`<at>…</at>` entity text, `<@U…>`, `@username`).
4
+ */
5
+ import type { ChannelActor } from "../types.js";
6
+ /** Per-platform outbound mention token rendering (CopilotKit mentions-as-a-tool: token pasted verbatim). */
7
+ export interface MentionRenderer {
8
+ renderUserMention(actor: ChannelActor): string;
9
+ }
10
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../../channels/src/mention/render.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,4GAA4G;AAC5G,MAAM,WAAW,eAAe;IAC9B,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAAC;CAChD"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Host-side ports the channels engine consumes. The framework never enforces
3
+ * authority — hosts do; the engine treats IdentityPort/BindingStore answers as
4
+ * authoritative and adds no permission model of its own (spec §6).
5
+ */
6
+ import type { AgentEvent } from "@skaile/workspaces/types";
7
+ import type { Binding, ChannelActor, ChannelMessage, ChannelPlatform, ConversationKey } from "./types.js";
8
+ /** Detaches a subscription created by {@link SessionPort.subscribe}. */
9
+ export type Unsubscribe = () => void;
10
+ /** A platform actor resolved to a host account by {@link IdentityPort}. */
11
+ export type HostUser = {
12
+ /** Host-side user id — becomes the attributed senderId on delivery. */
13
+ id: string;
14
+ displayName: string;
15
+ };
16
+ /** Handle to a host session returned by {@link SessionPort.createSession}. */
17
+ export type SessionRef = {
18
+ sessionId: string;
19
+ };
20
+ /** Spec for lazy thread-session creation on bot-mention (spec §7.1.6). */
21
+ export type NewSessionSpec = {
22
+ /** Human-readable title, e.g. "Teams: <thread snippet>". */
23
+ title: string;
24
+ platform: ChannelPlatform;
25
+ conversationKey: ConversationKey;
26
+ tenantId?: string;
27
+ /** Resolved host user requesting creation, when identity mapped. */
28
+ createdByUserId?: string;
29
+ };
30
+ /** Host's session boundary — deliver inbound messages, subscribe to agent output. */
31
+ export interface SessionPort {
32
+ /** Wakes if hibernated; persists attributed; prompts the agent (spec §7.1.7). */
33
+ deliver(binding: Binding, msg: ChannelMessage): Promise<void>;
34
+ /** One live subscription per active binding; consumes raw AgentEvents. */
35
+ subscribe(binding: Binding, sink: (e: AgentEvent) => void): Unsubscribe;
36
+ createSession?(spec: NewSessionSpec): Promise<SessionRef>;
37
+ }
38
+ /** Host's identity boundary — maps platform actors to host users. */
39
+ export interface IdentityPort {
40
+ /** null ⇒ host policy applies (reject / framed-external — spec §7.1.5). */
41
+ resolveActor(actor: ChannelActor): Promise<HostUser | null>;
42
+ }
43
+ /** Host-persisted conversationKey ↔ session join (spec §5.1); answers are authoritative. */
44
+ export interface BindingStore {
45
+ get(key: ConversationKey): Promise<Binding | null>;
46
+ put(binding: Binding): Promise<void>;
47
+ listForSession(sessionId: string): Promise<Binding[]>;
48
+ remove(key: ConversationKey): Promise<void>;
49
+ }
50
+ /** Per-platform credentials. Adapters never persist these (spec §8). */
51
+ export type ChannelCredential = {
52
+ kind: "msteams";
53
+ appId: string;
54
+ clientSecret: string;
55
+ } | {
56
+ kind: "token";
57
+ token: string;
58
+ baseUrl?: string;
59
+ };
60
+ /** Host's secret boundary — resolves per-tenant platform credentials on demand. */
61
+ export interface CredentialPort {
62
+ forTenant(platform: ChannelPlatform, tenantId: string): Promise<ChannelCredential>;
63
+ }
64
+ /** Web-standard handler so hosts adapt it to Fastify raw child or Bun.serve alike. */
65
+ export type RawHttpHandler = (req: Request) => Promise<Response>;
66
+ /** Host's HTTP surface for webhook-style adapters. */
67
+ export interface IngressHost {
68
+ /** Webhook-style adapters (Teams) register here; outbound-socket adapters need nothing. */
69
+ registerHttpRoute?(path: string, handler: RawHttpHandler): void;
70
+ }
71
+ //# sourceMappingURL=ports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../../../channels/src/ports.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,cAAc,EACd,eAAe,EACf,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,wEAAwE;AACxE,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC,2EAA2E;AAC3E,MAAM,MAAM,QAAQ,GAAG;IACrB,uEAAuE;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,8EAA8E;AAC9E,MAAM,MAAM,UAAU,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/C,0EAA0E;AAC1E,MAAM,MAAM,cAAc,GAAG;IAC3B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,eAAe,CAAC;IAC1B,eAAe,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,qFAAqF;AACrF,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,0EAA0E;IAC1E,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,GAAG,WAAW,CAAC;IACxE,aAAa,CAAC,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC3D;AAED,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;CAC7D;AAED,4FAA4F;AAC5F,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACnD,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,MAAM,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED,wEAAwE;AACxE,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,mFAAmF;AACnF,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACpF;AAED,sFAAsF;AACtF,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEjE,sDAAsD;AACtD,MAAM,WAAW,WAAW;IAC1B,2FAA2F;IAC3F,iBAAiB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;CACjE"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Core value and message types for the channels layer — the bridge between
3
+ * external chat platforms (Teams, Mattermost, Slack) and workspace sessions.
4
+ *
5
+ * Everything here is transport-neutral: no platform SDK types leak in, and
6
+ * platform-native payloads only appear as opaque `raw`/`messageRef` slots.
7
+ */
8
+ import type { MessageV2 } from "@skaile/workspaces/types";
9
+ /** Chat platforms the channels layer can bridge. */
10
+ export declare const CHANNEL_PLATFORMS: readonly ["msteams", "mattermost", "slack"];
11
+ /** One of the supported chat platforms (`"msteams" | "mattermost" | "slack"`). */
12
+ export type ChannelPlatform = (typeof CHANNEL_PLATFORMS)[number];
13
+ /**
14
+ * Canonical identifier of a place in a chat app: `"<platform>:<conversationId>"`,
15
+ * optionally `"…/<threadRootId>"`. Never a session id — the Binding is the only
16
+ * join between the two (spec §5.1).
17
+ */
18
+ export type ConversationKey = string;
19
+ /**
20
+ * Builds a {@link ConversationKey} from its parts.
21
+ *
22
+ * Invariant: `parseConversationKey(makeConversationKey(p, c, t))` round-trips
23
+ * exactly, provided `threadRootId` itself contains no `/`.
24
+ */
25
+ export declare function makeConversationKey(platform: ChannelPlatform, conversationId: string, threadRootId?: string): ConversationKey;
26
+ /**
27
+ * Splits a {@link ConversationKey} into platform, conversation id, and optional
28
+ * thread root. Throws on an unknown platform prefix.
29
+ *
30
+ * Gotcha: the thread separator is the LAST `/` — conversation ids may
31
+ * themselves contain slashes (e.g. Mattermost `team/channel`).
32
+ */
33
+ export declare function parseConversationKey(key: ConversationKey): {
34
+ platform: ChannelPlatform;
35
+ conversationId: string;
36
+ threadRootId?: string;
37
+ };
38
+ /** A person (or bot) as the chat platform sees them — pre-IdentityPort resolution. */
39
+ export type ChannelActor = {
40
+ platform: ChannelPlatform;
41
+ /** Platform-native user id (Teams AAD object id, Slack user id, MM user id). */
42
+ externalId: string;
43
+ displayName: string;
44
+ /** Teams tenant / MM team / Slack workspace, when known. */
45
+ tenantId?: string;
46
+ /** Identity hint for IdentityPort mapping, when the platform exposes it. */
47
+ email?: string;
48
+ isBot?: boolean;
49
+ };
50
+ /** Reference to a posted platform message. `raw` carries platform-native extras (e.g. Teams serviceUrl). */
51
+ export type MessageRef = {
52
+ platform: ChannelPlatform;
53
+ conversationKey: ConversationKey;
54
+ /** Platform-native message id (Teams activity id, Slack ts, MM post id). */
55
+ messageId: string;
56
+ raw?: unknown;
57
+ };
58
+ /** Where to post: a conversation, optionally threaded under an existing message. */
59
+ export type ReplyTarget = {
60
+ conversationKey: ConversationKey;
61
+ /** Platform-native thread anchor; adapters thread under it where supported. */
62
+ threadRef?: MessageRef;
63
+ };
64
+ /**
65
+ * Declarative surface description consumed by the engine + egress pipeline.
66
+ * Finalized per spec §13.1 by this plan — the conformance kit asserts adapters
67
+ * honor `maxMessageLength` and `ackDeadlineMs`.
68
+ */
69
+ export type SurfaceCapabilities = {
70
+ canEditMessages: boolean;
71
+ canDeleteMessages: boolean;
72
+ supportsThreads: boolean;
73
+ supportsCards: boolean;
74
+ supportsTyping: boolean;
75
+ supportsEphemeral: boolean;
76
+ supportsReactions: boolean;
77
+ /** Hard cap on a single posted message's text length; egress chunks at this. */
78
+ maxMessageLength: number;
79
+ /** IngressSink.onMessage must resolve within this (Slack ~3000, Teams 15000). */
80
+ ackDeadlineMs: number;
81
+ /** Minimum interval between successive edits of one message (egress throttle). */
82
+ editThrottleMs: number;
83
+ /** Outbound text dialect the adapter expects from the format layer. */
84
+ textFormat: "markdown" | "mrkdwn" | "adaptive-card";
85
+ };
86
+ /** Per-binding egress policy (spec §7.2.4). */
87
+ export type MirrorMode = "agent-only" | "full" | "chat-initiated";
88
+ /**
89
+ * The conversationKey ↔ sessionId join, persisted by the host's BindingStore.
90
+ * Deliberately not 1:1 (spec §5.1). Session ids never leak into chat payloads.
91
+ */
92
+ export type Binding = {
93
+ conversationKey: ConversationKey;
94
+ sessionId: string;
95
+ platform: ChannelPlatform;
96
+ tenantId?: string;
97
+ mirrorMode: MirrorMode;
98
+ enabled: boolean;
99
+ /** Host user id that created the binding (audit; authority stays with the host). */
100
+ createdBy: string;
101
+ /** ISO 8601. */
102
+ createdAt: string;
103
+ };
104
+ /**
105
+ * The one genuinely new meta type (spec §5) — rides on MessageMeta's extension
106
+ * slot; hosts persist it untouched via the round-trip preservation contract.
107
+ */
108
+ export type ChannelMetaExtensions = {
109
+ channel?: {
110
+ platform: ChannelPlatform;
111
+ conversationKey: ConversationKey;
112
+ /** Platform event id — the inbound dedupe key. */
113
+ eventId: string;
114
+ tenantId?: string;
115
+ /** Pre-IdentityPort resolution attribution. */
116
+ actor?: {
117
+ externalId: string;
118
+ displayName: string;
119
+ };
120
+ /** Opaque platform-native ref of the source message. */
121
+ messageRef?: unknown;
122
+ };
123
+ };
124
+ /** A workspace message envelope whose meta block carries {@link ChannelMetaExtensions}. */
125
+ export type ChannelMessage = MessageV2<ChannelMetaExtensions>;
126
+ /** What the engine hands an adapter to post. Format conversion is the adapter's job. */
127
+ export type OutboundMessage = {
128
+ /** Markdown source; adapters convert via the format layer per their textFormat. */
129
+ markdown: string;
130
+ /** Rendering intent. Default "text". */
131
+ kind?: "text" | "question" | "status" | "error";
132
+ /** Options rendered as buttons where supportsCards; appended as a list otherwise. */
133
+ options?: string[];
134
+ };
135
+ /** Fast-ack result of IngressSink.onMessage (spec §7.1.3). */
136
+ export type IngressAck = {
137
+ status: "accepted" | "duplicate" | "ignored" | "rejected";
138
+ reason?: string;
139
+ };
140
+ /** Inbound reaction event. Engine behavior deferred this milestone (Decision 7). */
141
+ export type InboundReaction = {
142
+ conversationKey: ConversationKey;
143
+ messageRef: MessageRef;
144
+ emoji: string;
145
+ actor: ChannelActor;
146
+ action: "added" | "removed";
147
+ eventId: string;
148
+ };
149
+ /** Non-message conversation lifecycle signals adapters may surface. */
150
+ export type ConversationEvent = {
151
+ conversationKey: ConversationKey;
152
+ kind: "member_joined" | "member_left" | "conversation_renamed" | "conversation_deleted";
153
+ eventId: string;
154
+ raw?: unknown;
155
+ };
156
+ /** Query for ChannelAdapter.lookupActor — backs the mentions-as-a-tool helper. */
157
+ export type ActorQuery = {
158
+ externalId?: string;
159
+ email?: string;
160
+ /** Display-name substring match, platform semantics. */
161
+ name?: string;
162
+ };
163
+ /** Result of verifyConversation — actionable problems, forge-tui preflight pattern. */
164
+ export type ConversationHealth = {
165
+ ok: boolean;
166
+ /** Human-actionable problem descriptions ("bot is not a member of #x — invite it"). */
167
+ problems: string[];
168
+ };
169
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../channels/src/types.ts"],"names":[],"mappings":"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"}
@@ -68,5 +68,5 @@ async function flowFindFlowForSession(projectDir, runId) {
68
68
  }
69
69
 
70
70
  export { flowFindFlowForSession, flowGetSession, flowList, flowListSessions, flowShow };
71
- //# sourceMappingURL=chunk-A7GDV5BV.js.map
72
- //# sourceMappingURL=chunk-A7GDV5BV.js.map
71
+ //# sourceMappingURL=chunk-2BQBWWFX.js.map
72
+ //# sourceMappingURL=chunk-2BQBWWFX.js.map