@moltzap/client 2026.511.1 → 2026.519.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 (218) hide show
  1. package/dist/auth.d.ts +12 -6
  2. package/dist/auth.d.ts.map +1 -1
  3. package/dist/auth.js +67 -29
  4. package/dist/auth.js.map +1 -1
  5. package/dist/auth.test.js +113 -76
  6. package/dist/auth.test.js.map +1 -1
  7. package/dist/channel-base/format-cross-conv.d.ts +43 -0
  8. package/dist/channel-base/format-cross-conv.d.ts.map +1 -0
  9. package/dist/channel-base/format-cross-conv.js +69 -0
  10. package/dist/channel-base/format-cross-conv.js.map +1 -0
  11. package/dist/channel-base/format-group-block.d.ts +43 -0
  12. package/dist/channel-base/format-group-block.d.ts.map +1 -0
  13. package/dist/channel-base/format-group-block.js +59 -0
  14. package/dist/channel-base/format-group-block.js.map +1 -0
  15. package/dist/channel-base/index.d.ts +21 -0
  16. package/dist/channel-base/index.d.ts.map +1 -0
  17. package/dist/channel-base/index.js +24 -0
  18. package/dist/channel-base/index.js.map +1 -0
  19. package/dist/channel-base/lease-guard.d.ts +30 -0
  20. package/dist/channel-base/lease-guard.d.ts.map +1 -0
  21. package/dist/channel-base/lease-guard.js +40 -0
  22. package/dist/channel-base/lease-guard.js.map +1 -0
  23. package/dist/channel-base/lease-store.d.ts +30 -0
  24. package/dist/channel-base/lease-store.d.ts.map +1 -0
  25. package/dist/channel-base/lease-store.js +58 -0
  26. package/dist/channel-base/lease-store.js.map +1 -0
  27. package/dist/channel-base/lease.d.ts +94 -0
  28. package/dist/channel-base/lease.d.ts.map +1 -0
  29. package/dist/channel-base/lease.js +110 -0
  30. package/dist/channel-base/lease.js.map +1 -0
  31. package/dist/channel-core-context.test.d.ts +2 -0
  32. package/dist/channel-core-context.test.d.ts.map +1 -0
  33. package/dist/channel-core-context.test.js +334 -0
  34. package/dist/channel-core-context.test.js.map +1 -0
  35. package/dist/channel-core-dispatch.test.d.ts +2 -0
  36. package/dist/channel-core-dispatch.test.d.ts.map +1 -0
  37. package/dist/channel-core-dispatch.test.js +550 -0
  38. package/dist/channel-core-dispatch.test.js.map +1 -0
  39. package/dist/channel-core-enrichment.d.ts +8 -0
  40. package/dist/channel-core-enrichment.d.ts.map +1 -0
  41. package/dist/channel-core-enrichment.js +134 -0
  42. package/dist/channel-core-enrichment.js.map +1 -0
  43. package/dist/channel-core-errors.d.ts +20 -0
  44. package/dist/channel-core-errors.d.ts.map +1 -0
  45. package/dist/channel-core-errors.js +12 -0
  46. package/dist/channel-core-errors.js.map +1 -0
  47. package/dist/channel-core-test-support.d.ts +48 -0
  48. package/dist/channel-core-test-support.d.ts.map +1 -0
  49. package/dist/channel-core-test-support.js +111 -0
  50. package/dist/channel-core-test-support.js.map +1 -0
  51. package/dist/channel-core.d.ts +30 -7
  52. package/dist/channel-core.d.ts.map +1 -1
  53. package/dist/channel-core.js +214 -237
  54. package/dist/channel-core.js.map +1 -1
  55. package/dist/channel-core.test.js +216 -1082
  56. package/dist/channel-core.test.js.map +1 -1
  57. package/dist/cli/__tests__/cli-multi-agent.int.test.js +129 -23
  58. package/dist/cli/__tests__/cli-multi-agent.int.test.js.map +1 -1
  59. package/dist/cli/commands/conversations-v2.test.js +64 -54
  60. package/dist/cli/commands/conversations-v2.test.js.map +1 -1
  61. package/dist/cli/commands/conversations.d.ts +5 -5
  62. package/dist/cli/commands/conversations.d.ts.map +1 -1
  63. package/dist/cli/commands/conversations.js +43 -36
  64. package/dist/cli/commands/conversations.js.map +1 -1
  65. package/dist/cli/commands/messages.d.ts +4 -4
  66. package/dist/cli/commands/messages.d.ts.map +1 -1
  67. package/dist/cli/commands/messages.js +4 -4
  68. package/dist/cli/commands/messages.js.map +1 -1
  69. package/dist/cli/commands/messages.test.js +61 -49
  70. package/dist/cli/commands/messages.test.js.map +1 -1
  71. package/dist/cli/commands/ping.d.ts +0 -9
  72. package/dist/cli/commands/ping.d.ts.map +1 -1
  73. package/dist/cli/commands/ping.js +1 -1
  74. package/dist/cli/commands/ping.js.map +1 -1
  75. package/dist/cli/commands/presence.d.ts +1 -1
  76. package/dist/cli/commands/presence.js +1 -1
  77. package/dist/cli/commands/register.d.ts +2 -2
  78. package/dist/cli/commands/register.d.ts.map +1 -1
  79. package/dist/cli/commands/register.js +98 -77
  80. package/dist/cli/commands/register.js.map +1 -1
  81. package/dist/cli/commands/register.test.js +63 -39
  82. package/dist/cli/commands/register.test.js.map +1 -1
  83. package/dist/cli/commands/send.d.ts +6 -6
  84. package/dist/cli/commands/send.js +6 -6
  85. package/dist/cli/commands/send.test.js +32 -28
  86. package/dist/cli/commands/send.test.js.map +1 -1
  87. package/dist/cli/commands/status.d.ts.map +1 -1
  88. package/dist/cli/commands/status.js +3 -4
  89. package/dist/cli/commands/status.js.map +1 -1
  90. package/dist/cli/config.d.ts +0 -2
  91. package/dist/cli/config.d.ts.map +1 -1
  92. package/dist/cli/config.js +86 -76
  93. package/dist/cli/config.js.map +1 -1
  94. package/dist/cli/config.test.js +80 -42
  95. package/dist/cli/config.test.js.map +1 -1
  96. package/dist/cli/index.d.ts +1 -16
  97. package/dist/cli/index.d.ts.map +1 -1
  98. package/dist/cli/index.js +50 -113
  99. package/dist/cli/index.js.map +1 -1
  100. package/dist/cli/process-argv.d.ts +2 -0
  101. package/dist/cli/process-argv.d.ts.map +1 -0
  102. package/dist/cli/process-argv.js +2 -0
  103. package/dist/cli/process-argv.js.map +1 -0
  104. package/dist/cli/profile.d.ts +3 -10
  105. package/dist/cli/profile.d.ts.map +1 -1
  106. package/dist/cli/profile.js +105 -104
  107. package/dist/cli/profile.js.map +1 -1
  108. package/dist/cli/profile.test.js +338 -232
  109. package/dist/cli/profile.test.js.map +1 -1
  110. package/dist/cli/runtime.d.ts +5 -17
  111. package/dist/cli/runtime.d.ts.map +1 -1
  112. package/dist/cli/runtime.js +6 -59
  113. package/dist/cli/runtime.js.map +1 -1
  114. package/dist/cli/socket-client.d.ts +10 -15
  115. package/dist/cli/socket-client.d.ts.map +1 -1
  116. package/dist/cli/socket-client.js +74 -89
  117. package/dist/cli/socket-client.js.map +1 -1
  118. package/dist/cli/transport.d.ts +9 -5
  119. package/dist/cli/transport.d.ts.map +1 -1
  120. package/dist/cli/transport.js +45 -42
  121. package/dist/cli/transport.js.map +1 -1
  122. package/dist/cli/transport.test.js +227 -133
  123. package/dist/cli/transport.test.js.map +1 -1
  124. package/dist/index.d.ts +4 -1
  125. package/dist/index.d.ts.map +1 -1
  126. package/dist/index.js +3 -0
  127. package/dist/index.js.map +1 -1
  128. package/dist/local-daemon-rpc.d.ts +13 -0
  129. package/dist/local-daemon-rpc.d.ts.map +1 -0
  130. package/dist/local-daemon-rpc.js +17 -0
  131. package/dist/local-daemon-rpc.js.map +1 -0
  132. package/dist/local-paths.d.ts +7 -0
  133. package/dist/local-paths.d.ts.map +1 -0
  134. package/dist/local-paths.js +20 -0
  135. package/dist/local-paths.js.map +1 -0
  136. package/dist/runtime/close-info.d.ts +3 -12
  137. package/dist/runtime/close-info.d.ts.map +1 -1
  138. package/dist/runtime/close-info.js +28 -39
  139. package/dist/runtime/close-info.js.map +1 -1
  140. package/dist/runtime/close-info.test.js +77 -70
  141. package/dist/runtime/close-info.test.js.map +1 -1
  142. package/dist/runtime/errors.test.js +42 -28
  143. package/dist/runtime/errors.test.js.map +1 -1
  144. package/dist/runtime/frame.d.ts +4 -31
  145. package/dist/runtime/frame.d.ts.map +1 -1
  146. package/dist/runtime/frame.js +7 -116
  147. package/dist/runtime/frame.js.map +1 -1
  148. package/dist/runtime/frame.test.js +41 -54
  149. package/dist/runtime/frame.test.js.map +1 -1
  150. package/dist/runtime/index.d.ts +7 -0
  151. package/dist/runtime/index.d.ts.map +1 -1
  152. package/dist/runtime/index.js +7 -11
  153. package/dist/runtime/index.js.map +1 -1
  154. package/dist/runtime/local-history.d.ts +67 -0
  155. package/dist/runtime/local-history.d.ts.map +1 -0
  156. package/dist/runtime/local-history.js +77 -0
  157. package/dist/runtime/local-history.js.map +1 -0
  158. package/dist/runtime/local-service-commands.d.ts +19 -0
  159. package/dist/runtime/local-service-commands.d.ts.map +1 -1
  160. package/dist/runtime/local-service-commands.js +23 -0
  161. package/dist/runtime/local-service-commands.js.map +1 -1
  162. package/dist/runtime/local-socket-server.d.ts +20 -0
  163. package/dist/runtime/local-socket-server.d.ts.map +1 -0
  164. package/dist/runtime/local-socket-server.js +94 -0
  165. package/dist/runtime/local-socket-server.js.map +1 -0
  166. package/dist/runtime/refs.d.ts +1 -1
  167. package/dist/runtime/refs.js +1 -1
  168. package/dist/runtime/runtime.test.js +29 -21
  169. package/dist/runtime/runtime.test.js.map +1 -1
  170. package/dist/runtime/service-helpers.d.ts +32 -0
  171. package/dist/runtime/service-helpers.d.ts.map +1 -0
  172. package/dist/runtime/service-helpers.js +85 -0
  173. package/dist/runtime/service-helpers.js.map +1 -0
  174. package/dist/runtime/subscribers.d.ts +13 -17
  175. package/dist/runtime/subscribers.d.ts.map +1 -1
  176. package/dist/runtime/subscribers.js +37 -32
  177. package/dist/runtime/subscribers.js.map +1 -1
  178. package/dist/runtime/subscribers.test.js +139 -131
  179. package/dist/runtime/subscribers.test.js.map +1 -1
  180. package/dist/service-socket-path.test.d.ts +2 -0
  181. package/dist/service-socket-path.test.d.ts.map +1 -0
  182. package/dist/service-socket-path.test.js +87 -0
  183. package/dist/service-socket-path.test.js.map +1 -0
  184. package/dist/service.d.ts +23 -20
  185. package/dist/service.d.ts.map +1 -1
  186. package/dist/service.js +192 -340
  187. package/dist/service.js.map +1 -1
  188. package/dist/service.test.js +652 -653
  189. package/dist/service.test.js.map +1 -1
  190. package/dist/test/index.d.ts +30 -14
  191. package/dist/test/index.d.ts.map +1 -1
  192. package/dist/test/index.js +25 -21
  193. package/dist/test/index.js.map +1 -1
  194. package/dist/test-utils/channel-service-fixture.d.ts +1 -0
  195. package/dist/test-utils/channel-service-fixture.d.ts.map +1 -1
  196. package/dist/test-utils/channel-service-fixture.js +139 -98
  197. package/dist/test-utils/channel-service-fixture.js.map +1 -1
  198. package/dist/test-utils/conformance-adapter.d.ts.map +1 -1
  199. package/dist/test-utils/conformance-adapter.js +145 -124
  200. package/dist/test-utils/conformance-adapter.js.map +1 -1
  201. package/dist/test-utils/fake-service.d.ts.map +1 -1
  202. package/dist/test-utils/fake-service.js +3 -3
  203. package/dist/test-utils/fake-service.js.map +1 -1
  204. package/dist/test-utils/index.d.ts +25 -0
  205. package/dist/test-utils/index.d.ts.map +1 -1
  206. package/dist/test-utils/index.js +25 -8
  207. package/dist/test-utils/index.js.map +1 -1
  208. package/dist/ws-client-test-support.d.ts +180 -0
  209. package/dist/ws-client-test-support.d.ts.map +1 -0
  210. package/dist/ws-client-test-support.js +399 -0
  211. package/dist/ws-client-test-support.js.map +1 -0
  212. package/dist/ws-client.d.ts +59 -32
  213. package/dist/ws-client.d.ts.map +1 -1
  214. package/dist/ws-client.js +272 -321
  215. package/dist/ws-client.js.map +1 -1
  216. package/dist/ws-client.test.js +388 -800
  217. package/dist/ws-client.test.js.map +1 -1
  218. package/package.json +18 -10
package/dist/auth.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { Effect } from "effect";
2
- /** HTTP response from the agent registration endpoints
3
- * (`/api/v1/auth/register` and `/api/v1/admin/register-agent`). */
2
+ /**
3
+ * HTTP response from the agent registration endpoints
4
+ * (`/api/v1/auth/register` and `/api/v1/admin/register-agent`).
5
+ */
4
6
  export interface RegisterResponse {
5
7
  agentId: string;
6
8
  apiKey: string;
@@ -11,8 +13,10 @@ export interface RegisterResponse {
11
13
  export interface RegisterAgentOptions {
12
14
  description?: string;
13
15
  inviteCode?: string;
14
- /** When set, registers via the secret-gated admin endpoint and pre-claims
15
- * the agent for this user. See {@link registerAgent}. */
16
+ /**
17
+ * When set, registers via the secret-gated admin endpoint and pre-claims
18
+ * the agent for this user. See {@link registerAgent}.
19
+ */
16
20
  ownerUserId?: string;
17
21
  }
18
22
  declare const RegisterAgentError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
@@ -23,13 +27,15 @@ export declare class RegisterAgentError extends RegisterAgentError_base<{
23
27
  readonly cause?: unknown;
24
28
  }> {
25
29
  }
26
- /** Register a new agent via HTTP. Thin wrapper around the agent-registration
30
+ /**
31
+ * Register a new agent via HTTP. Thin wrapper around the agent-registration
27
32
  * endpoints — the WebSocket dance is `MoltZapWsClient`'s job; this just
28
33
  * returns the credentials the caller feeds it as `agentKey` at construction.
29
34
  *
30
35
  * Routes to `/api/v1/admin/register-agent` when `ownerUserId` is provided
31
36
  * (admin path pre-claims the agent for the given owner); otherwise routes
32
- * to the public `/api/v1/auth/register` endpoint. */
37
+ * to the public `/api/v1/auth/register` endpoint.
38
+ */
33
39
  export declare const registerAgent: (baseUrl: string, name: string, opts?: RegisterAgentOptions) => Effect.Effect<RegisterResponse, RegisterAgentError>;
34
40
  export {};
35
41
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEtC;mEACmE;AACnE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;6DACyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;;;;AAKD,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC7E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;CAAG;AAOL;;;;;;qDAMqD;AACrD,eAAO,MAAM,aAAa,GACxB,SAAS,MAAM,EACf,MAAM,MAAM,EACZ,OAAO,oBAAoB,KAC1B,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,kBAAkB,CAmClD,CAAC"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAMA,OAAO,EAAQ,MAAM,EAAU,MAAM,QAAQ,CAAC;AAE9C;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;;;;AAOD,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC7E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;CAAG;AAOL;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,GACxB,SAAS,MAAM,EACf,MAAM,MAAM,EACZ,OAAM,oBAAyB,KAC9B,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,kBAAkB,CAgBlD,CAAC"}
package/dist/auth.js CHANGED
@@ -1,40 +1,78 @@
1
- import { Data, Effect } from "effect";
1
+ import { HttpClient, HttpClientRequest, HttpClientResponse, } from "@effect/platform";
2
+ import { NodeHttpClient } from "@effect/platform-node";
3
+ import { Data, Effect, Either } from "effect";
2
4
  const PUBLIC_PATH = "/api/v1/auth/register";
3
5
  const ADMIN_PATH = "/api/v1/admin/register-agent";
6
+ const HTTP_SUCCESS_STATUS_MIN = 200;
7
+ const HTTP_REDIRECT_STATUS_MIN = 300;
4
8
  export class RegisterAgentError extends Data.TaggedError("RegisterAgentError") {
5
9
  }
6
10
  const registerAgentError = (message, cause) => new RegisterAgentError({ message, cause });
7
- /** Register a new agent via HTTP. Thin wrapper around the agent-registration
11
+ /**
12
+ * Register a new agent via HTTP. Thin wrapper around the agent-registration
8
13
  * endpoints — the WebSocket dance is `MoltZapWsClient`'s job; this just
9
14
  * returns the credentials the caller feeds it as `agentKey` at construction.
10
15
  *
11
16
  * Routes to `/api/v1/admin/register-agent` when `ownerUserId` is provided
12
17
  * (admin path pre-claims the agent for the given owner); otherwise routes
13
- * to the public `/api/v1/auth/register` endpoint. */
14
- export const registerAgent = (baseUrl, name, opts) => Effect.tryPromise({
15
- try: () => {
16
- const body = { name };
17
- if (opts?.description)
18
- body.description = opts.description;
19
- if (opts?.inviteCode)
20
- body.inviteCode = opts.inviteCode;
21
- if (opts?.ownerUserId)
22
- body.ownerUserId = opts.ownerUserId;
23
- const path = opts?.ownerUserId ? ADMIN_PATH : PUBLIC_PATH;
24
- return fetch(`${baseUrl}${path}`, {
25
- method: "POST",
26
- headers: { "Content-Type": "application/json" },
27
- body: JSON.stringify(body),
28
- });
29
- },
30
- catch: (err) => registerAgentError("Register request failed", err),
31
- }).pipe(Effect.flatMap((res) => res.ok
32
- ? Effect.tryPromise({
33
- try: () => res.json(),
34
- catch: (err) => registerAgentError("Register response decode failed", err),
35
- })
36
- : Effect.tryPromise({
37
- try: () => res.text(),
38
- catch: (err) => registerAgentError("Register error response read failed", err),
39
- }).pipe(Effect.flatMap((text) => Effect.fail(registerAgentError(`Register failed: ${res.status} ${text}`))))));
18
+ * to the public `/api/v1/auth/register` endpoint.
19
+ */
20
+ export const registerAgent = (baseUrl, name, opts = {}) => registerAgentRequest(baseUrl, name, opts).pipe(Effect.provide(NodeHttpClient.layer), Effect.either, Effect.flatMap(Either.match({
21
+ onLeft: (cause) => Effect.fail(cause instanceof RegisterAgentError
22
+ ? cause
23
+ : registerAgentError("Register request failed", cause)),
24
+ onRight: (value) => Effect.succeed(value),
25
+ })), Effect.withSpan("registerAgent"));
26
+ function registerAgentRequest(baseUrl, name, opts) {
27
+ return Effect.gen(function* () {
28
+ const client = yield* HttpClient.HttpClient;
29
+ const body = registerAgentBody(name, opts);
30
+ const request = registerHttpRequest(baseUrl, registerPath(opts), body);
31
+ const response = yield* client
32
+ .execute(request)
33
+ .pipe(Effect.mapError((cause) => registerAgentError("Register request failed", cause)));
34
+ return yield* isSuccessStatus(response.status)
35
+ ? decodeRegisterResponse(response)
36
+ : failRegisterStatus(response);
37
+ });
38
+ }
39
+ function registerAgentBody(name, opts) {
40
+ return {
41
+ name,
42
+ ...(opts?.description !== undefined
43
+ ? { description: opts.description }
44
+ : {}),
45
+ ...(opts?.inviteCode !== undefined ? { inviteCode: opts.inviteCode } : {}),
46
+ ...(opts?.ownerUserId !== undefined
47
+ ? { ownerUserId: opts.ownerUserId }
48
+ : {}),
49
+ };
50
+ }
51
+ function registerPath(opts) {
52
+ return opts?.ownerUserId ? ADMIN_PATH : PUBLIC_PATH;
53
+ }
54
+ function registerHttpRequest(baseUrl, path, body) {
55
+ return HttpClientRequest.post(`${baseUrl}${path}`).pipe(HttpClientRequest.setHeader("Content-Type", "application/json"), HttpClientRequest.bodyUnsafeJson(body));
56
+ }
57
+ function isSuccessStatus(status) {
58
+ return status >= HTTP_SUCCESS_STATUS_MIN && status < HTTP_REDIRECT_STATUS_MIN;
59
+ }
60
+ function failRegisterStatus(response) {
61
+ return Effect.gen(function* () {
62
+ const text = yield* decodeResponseText(response);
63
+ return yield* Effect.fail(registerAgentError(`Register failed: ${response.status} ${text}`));
64
+ });
65
+ }
66
+ function decodeResponseText(response) {
67
+ return response.text.pipe(Effect.either, Effect.flatMap(Either.match({
68
+ onLeft: (cause) => Effect.fail(registerAgentError("Register error response read failed", cause)),
69
+ onRight: Effect.succeed,
70
+ })));
71
+ }
72
+ function decodeRegisterResponse(response) {
73
+ return response.json.pipe(Effect.either, Effect.flatMap(Either.match({
74
+ onLeft: (cause) => Effect.fail(registerAgentError("Register response decode failed", cause)),
75
+ onRight: (value) => Effect.succeed(value),
76
+ })));
77
+ }
40
78
  //# sourceMappingURL=auth.js.map
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAoBtC,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAC5C,MAAM,UAAU,GAAG,8BAA8B,CAAC;AAElD,MAAM,OAAO,kBAAmB,SAAQ,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAG3E;CAAG;AAEL,MAAM,kBAAkB,GAAG,CACzB,OAAe,EACf,KAAe,EACK,EAAE,CAAC,IAAI,kBAAkB,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AAEpE;;;;;;qDAMqD;AACrD,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,OAAe,EACf,IAAY,EACZ,IAA2B,EAC0B,EAAE,CACvD,MAAM,CAAC,UAAU,CAAC;IAChB,GAAG,EAAE,GAAG,EAAE;QACR,MAAM,IAAI,GAA2B,EAAE,IAAI,EAAE,CAAC;QAC9C,IAAI,IAAI,EAAE,WAAW;YAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QAC3D,IAAI,IAAI,EAAE,UAAU;YAAE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACxD,IAAI,IAAI,EAAE,WAAW;YAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QAC3D,MAAM,IAAI,GAAG,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;QAC1D,OAAO,KAAK,CAAC,GAAG,OAAO,GAAG,IAAI,EAAE,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;IACL,CAAC;IACD,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAkB,CAAC,yBAAyB,EAAE,GAAG,CAAC;CACnE,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CACrB,GAAG,CAAC,EAAE;IACJ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QAChB,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAA+B;QAClD,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CACb,kBAAkB,CAAC,iCAAiC,EAAE,GAAG,CAAC;KAC7D,CAAC;IACJ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QAChB,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE;QACrB,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CACb,kBAAkB,CAAC,qCAAqC,EAAE,GAAG,CAAC;KACjE,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACtB,MAAM,CAAC,IAAI,CACT,kBAAkB,CAAC,oBAAoB,GAAG,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAC7D,CACF,CACF,CACN,CACF,CAAC"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
package/dist/auth.test.js CHANGED
@@ -1,84 +1,121 @@
1
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
2
- import { Effect } from "effect";
1
+ import { HttpRouter, HttpServer, HttpServerRequest, HttpServerResponse, } from "@effect/platform";
2
+ import { NodeHttpServer } from "@effect/platform-node";
3
+ import { it as effectIt } from "@effect/vitest";
4
+ import { Effect, Exit, Ref } from "effect";
5
+ import { describe, expect } from "vitest";
3
6
  import { registerAgent } from "./auth.js";
4
- /** Run an Effect to a Promise for vitest assertions. */
5
- const run = (e) => Effect.runPromise(e);
6
- /** Build a fake `fetch` that captures the request and returns a canned
7
- * `RegisterResponse` payload. The capture is the assertion target — we
8
- * verify URL and body shape without standing up the real server. The
9
- * fake matches `typeof globalThis.fetch` so it can replace the real
10
- * binding without a cast. */
11
- function makeFakeFetch(responder) {
12
- const calls = [];
13
- const fakeFetch = async (input, init) => {
14
- const url = typeof input === "string"
15
- ? input
16
- : input instanceof URL
17
- ? input.toString()
18
- : input.url;
19
- const bodyText = typeof init?.body === "string" ? init.body : "";
20
- calls.push({
21
- url,
22
- method: init?.method,
23
- body: bodyText ? JSON.parse(bodyText) : undefined,
7
+ const it = effectIt.scoped;
8
+ const ADMIN_REGISTER_PATH = "/api/v1/admin/register-agent";
9
+ const PUBLIC_REGISTER_PATH = "/api/v1/auth/register";
10
+ const POST_METHOD = "POST";
11
+ const CREATED_STATUS = 201;
12
+ const FORBIDDEN_STATUS = 403;
13
+ const SINGLE_CALL_COUNT = 1;
14
+ const LOCALHOST = "127.0.0.1";
15
+ const LOCAL_HTTP_SCHEME = "http";
16
+ const JSON_CONTENT_TYPE = "application/json";
17
+ const TEXT_CONTENT_TYPE = "text/plain";
18
+ const TEST_AGENT_NAME = "test";
19
+ const INVITE_CODE = "secret";
20
+ const OWNER_USER_ID = "00000000-0000-4000-8000-000000000001";
21
+ const AGENT_ID = "agent-id";
22
+ const API_KEY = "api-key";
23
+ const CLAIM_URL = "https://example.test/claim";
24
+ const CLAIM_TOKEN = "claim-token";
25
+ const INVITE_REQUIRED_BODY = "invite required";
26
+ const defaultRegisterResponse = () => ({
27
+ status: CREATED_STATUS,
28
+ contentType: JSON_CONTENT_TYPE,
29
+ body: JSON.stringify({
30
+ agentId: AGENT_ID,
31
+ apiKey: API_KEY,
32
+ claimUrl: CLAIM_URL,
33
+ claimToken: CLAIM_TOKEN,
34
+ }),
35
+ });
36
+ const forbiddenResponse = () => ({
37
+ status: FORBIDDEN_STATUS,
38
+ contentType: TEXT_CONTENT_TYPE,
39
+ body: INVITE_REQUIRED_BODY,
40
+ });
41
+ const localBaseUrl = (port) => `${LOCAL_HTTP_SCHEME}://${LOCALHOST}:${port}`;
42
+ const requestBody = (request) => request.json.pipe(Effect.catchAll(() => Effect.succeed(undefined)));
43
+ const appendCapturedCall = (calls, call) => Ref.update(calls, (current) => [...current, call]);
44
+ const responseFromStub = (response) => HttpServerResponse.text(response.body, {
45
+ status: response.status,
46
+ contentType: response.contentType,
47
+ });
48
+ const routeHandler = (path, calls, responder) => Effect.gen(function* () {
49
+ const request = yield* HttpServerRequest.HttpServerRequest;
50
+ const body = yield* requestBody(request);
51
+ yield* appendCapturedCall(calls, {
52
+ path,
53
+ method: request.method,
54
+ body,
55
+ });
56
+ return responseFromStub(responder(path));
57
+ });
58
+ const makeRegisterServer = (responder = defaultRegisterResponse) => Effect.gen(function* () {
59
+ const calls = yield* Ref.make([]);
60
+ const adminRoute = HttpRouter.post(ADMIN_REGISTER_PATH, routeHandler(ADMIN_REGISTER_PATH, calls, responder));
61
+ const publicRoute = HttpRouter.post(PUBLIC_REGISTER_PATH, routeHandler(PUBLIC_REGISTER_PATH, calls, responder));
62
+ yield* HttpServer.serveEffect(HttpRouter.empty.pipe(adminRoute, publicRoute));
63
+ const address = yield* HttpServer.addressWith((serverAddress) => Effect.succeed(serverAddress));
64
+ if (address._tag !== "TcpAddress") {
65
+ return yield* Effect.dieMessage(`expected TCP address: ${address._tag}`);
66
+ }
67
+ return { baseUrl: localBaseUrl(address.port), calls };
68
+ });
69
+ const expectSingleCall = (calls) => {
70
+ expect(calls).toHaveLength(SINGLE_CALL_COUNT);
71
+ const [call] = calls;
72
+ expect(call).toBeDefined();
73
+ return call ?? { path: "", method: "", body: undefined };
74
+ };
75
+ function postsOwnerUserIdToAdminEndpoint() {
76
+ return Effect.gen(function* () {
77
+ const server = yield* makeRegisterServer();
78
+ const result = yield* registerAgent(server.baseUrl, TEST_AGENT_NAME, {
79
+ inviteCode: INVITE_CODE,
80
+ ownerUserId: OWNER_USER_ID,
81
+ });
82
+ const call = expectSingleCall(yield* Ref.get(server.calls));
83
+ expect(call.path).toBe(ADMIN_REGISTER_PATH);
84
+ expect(call.method).toBe(POST_METHOD);
85
+ expect(call.body).toEqual({
86
+ name: TEST_AGENT_NAME,
87
+ inviteCode: INVITE_CODE,
88
+ ownerUserId: OWNER_USER_ID,
24
89
  });
25
- if (responder)
26
- return responder(url);
27
- return new Response(JSON.stringify({
28
- agentId: "agent-id",
29
- apiKey: "api-key",
30
- claimUrl: "http://example/claim",
31
- claimToken: "claim-token",
32
- }), { status: 201, headers: { "Content-Type": "application/json" } });
33
- };
34
- return { fakeFetch, calls };
90
+ expect(result.agentId).toBe(AGENT_ID);
91
+ }).pipe(Effect.provide(NodeHttpServer.layerTest), Effect.orDie);
35
92
  }
36
- describe("registerAgent", () => {
37
- const baseUrl = "http://test.local";
38
- let originalFetch;
39
- beforeEach(() => {
40
- originalFetch = globalThis.fetch;
41
- });
42
- afterEach(() => {
43
- globalThis.fetch = originalFetch;
44
- });
45
- it("posts ownerUserId in the body to the admin endpoint", async () => {
46
- const { fakeFetch, calls } = makeFakeFetch();
47
- globalThis.fetch = fakeFetch;
48
- const result = await run(registerAgent(baseUrl, "test", {
49
- inviteCode: "secret",
50
- ownerUserId: "00000000-0000-4000-8000-000000000001",
51
- }));
52
- expect(calls).toHaveLength(1);
53
- const [call] = calls;
54
- expect(call.url).toBe(`${baseUrl}/api/v1/admin/register-agent`);
55
- expect(call.method).toBe("POST");
93
+ function postsToPublicEndpointWithoutOwnerUserId() {
94
+ return Effect.gen(function* () {
95
+ const server = yield* makeRegisterServer();
96
+ yield* registerAgent(server.baseUrl, TEST_AGENT_NAME, {
97
+ inviteCode: INVITE_CODE,
98
+ });
99
+ const call = expectSingleCall(yield* Ref.get(server.calls));
100
+ expect(call.path).toBe(PUBLIC_REGISTER_PATH);
56
101
  expect(call.body).toEqual({
57
- name: "test",
58
- inviteCode: "secret",
59
- ownerUserId: "00000000-0000-4000-8000-000000000001",
102
+ name: TEST_AGENT_NAME,
103
+ inviteCode: INVITE_CODE,
60
104
  });
61
- expect(result.agentId).toBe("agent-id");
62
- });
63
- it("posts to the public endpoint without ownerUserId when absent", async () => {
64
- const { fakeFetch, calls } = makeFakeFetch();
65
- globalThis.fetch = fakeFetch;
66
- await run(registerAgent(baseUrl, "test", { inviteCode: "secret" }));
67
- expect(calls[0].url).toBe(`${baseUrl}/api/v1/auth/register`);
68
- // toEqual with `additionalProperties` rejects extra keys, so this also
69
- // proves ownerUserId is not on the body.
70
- expect(calls[0].body).toEqual({ name: "test", inviteCode: "secret" });
71
- });
72
- it("fails when the server returns a non-2xx response", async () => {
73
- const { fakeFetch } = makeFakeFetch(() => new Response("invite required", {
74
- status: 403,
75
- headers: { "Content-Type": "text/plain" },
76
- }));
77
- globalThis.fetch = fakeFetch;
78
- const exit = await Effect.runPromiseExit(registerAgent(baseUrl, "test", {
79
- ownerUserId: "00000000-0000-4000-8000-000000000001",
105
+ }).pipe(Effect.provide(NodeHttpServer.layerTest), Effect.orDie);
106
+ }
107
+ function nonSuccessResponseFails() {
108
+ return Effect.gen(function* () {
109
+ const server = yield* makeRegisterServer(() => forbiddenResponse());
110
+ const exit = yield* Effect.exit(registerAgent(server.baseUrl, TEST_AGENT_NAME, {
111
+ ownerUserId: OWNER_USER_ID,
80
112
  }));
81
- expect(exit._tag).toBe("Failure");
82
- });
113
+ expect(Exit.isFailure(exit)).toBe(true);
114
+ }).pipe(Effect.provide(NodeHttpServer.layerTest), Effect.orDie);
115
+ }
116
+ describe("registerAgent", () => {
117
+ it("posts ownerUserId in the body to the admin endpoint", postsOwnerUserIdToAdminEndpoint);
118
+ it("posts to the public endpoint without ownerUserId when absent", postsToPublicEndpointWithoutOwnerUserId);
119
+ it("fails when the server returns a non-2xx response", nonSuccessResponseFails);
83
120
  });
84
121
  //# sourceMappingURL=auth.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.test.js","sourceRoot":"","sources":["../src/auth.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.test.js","sourceRoot":"","sources":["../src/auth.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Channel-base `formatCrossConv` — shared cross-conversation message
3
+ * formatter parameterized by markup variant or per-channel formatter
4
+ * callback.
5
+ *
6
+ * Replaces:
7
+ * - `packages/openclaw-channel/src/format-cross-conv.ts → formatCrossConvOpenClaw`
8
+ * (markup variant: `"json-header"`)
9
+ * - `packages/nanoclaw-channel/src/channels/moltzap.ts → formatCrossConvNanoclaw`
10
+ * (markup variant: `"xml-system-reminder"`)
11
+ *
12
+ * Behavioral parity is locked via the golden-snapshot fixtures captured
13
+ * pre-refactor — see arch sub-issue #605 §3.5 and §4.6.
14
+ */
15
+ import { type CrossConvMessage } from "../service.js";
16
+ export type { CrossConvMessage };
17
+ export type CrossConvMarkup = "json-header" | "xml-system-reminder";
18
+ export type CrossConvFormatter = (messages: readonly CrossConvMessage[], opts: {
19
+ readonly ownAgentId: string;
20
+ }) => string;
21
+ /**
22
+ * Returns the formatted block, or `null` when `messages` is empty.
23
+ *
24
+ * Markup variants:
25
+ * - `"json-header"`: byte-identical to the pre-refactor openclaw output.
26
+ * Header is `"Messages (untrusted metadata):"` followed by a ` ```json `
27
+ * fenced JSON array.
28
+ * - `"xml-system-reminder"`: byte-identical to the pre-refactor nanoclaw
29
+ * output. `&lt;messages&gt;` wrapper around `&lt;message&gt;` entries with
30
+ * `sender`/`conversation`/`time` attributes; sender/conv/time/text all
31
+ * run through `sanitizeForSystemReminder`.
32
+ *
33
+ * Or pass a custom `formatter` callback — channel-base owns the empty-check
34
+ * + ownAgentId disambiguation; the callback owns the markup.
35
+ */
36
+ export declare function formatCrossConv(messages: readonly CrossConvMessage[], opts: {
37
+ readonly ownAgentId: string;
38
+ readonly markup: CrossConvMarkup;
39
+ } | {
40
+ readonly ownAgentId: string;
41
+ readonly formatter: CrossConvFormatter;
42
+ }): string | null;
43
+ //# sourceMappingURL=format-cross-conv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-cross-conv.d.ts","sourceRoot":"","sources":["../../src/channel-base/format-cross-conv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,KAAK,gBAAgB,EAEtB,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,qBAAqB,CAAC;AAEpE,MAAM,MAAM,kBAAkB,GAAG,CAC/B,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EACrC,IAAI,EAAE;IAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,KAClC,MAAM,CAAC;AAmDZ;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EACrC,IAAI,EACA;IAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GACjE;IAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAA;CAAE,GAC1E,MAAM,GAAG,IAAI,CAWf"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Channel-base `formatCrossConv` — shared cross-conversation message
3
+ * formatter parameterized by markup variant or per-channel formatter
4
+ * callback.
5
+ *
6
+ * Replaces:
7
+ * - `packages/openclaw-channel/src/format-cross-conv.ts → formatCrossConvOpenClaw`
8
+ * (markup variant: `"json-header"`)
9
+ * - `packages/nanoclaw-channel/src/channels/moltzap.ts → formatCrossConvNanoclaw`
10
+ * (markup variant: `"xml-system-reminder"`)
11
+ *
12
+ * Behavioral parity is locked via the golden-snapshot fixtures captured
13
+ * pre-refactor — see arch sub-issue #605 §3.5 and §4.6.
14
+ */
15
+ import { sanitizeForSystemReminder, } from "../service.js";
16
+ const CROSS_CONV_HEADER_JSON = "Messages (untrusted metadata):";
17
+ const JSON_INDENT_SPACES = 2;
18
+ function normalizeMessage(message, opts) {
19
+ return {
20
+ conversation: message.conversationName ?? `DM with @${message.senderName}`,
21
+ sender: message.senderId === opts.ownAgentId ? "You" : message.senderName,
22
+ text: message.text,
23
+ timestamp: message.timestamp,
24
+ };
25
+ }
26
+ function formatJsonHeader(messages, opts) {
27
+ const items = messages.map((m) => normalizeMessage(m, opts));
28
+ return `${CROSS_CONV_HEADER_JSON}\n\`\`\`json\n${JSON.stringify(items, null, JSON_INDENT_SPACES)}\n\`\`\``;
29
+ }
30
+ function formatXmlSystemReminder(messages, opts) {
31
+ const lines = messages.map((m) => {
32
+ const item = normalizeMessage(m, opts);
33
+ const sender = sanitizeForSystemReminder(item.sender);
34
+ const conv = sanitizeForSystemReminder(item.conversation);
35
+ const text = sanitizeForSystemReminder(item.text);
36
+ const time = sanitizeForSystemReminder(item.timestamp);
37
+ return `<message sender="${sender}" conversation="${conv}" time="${time}">${text}</message>`;
38
+ });
39
+ return ["<messages>", ...lines, "</messages>"].join("\n");
40
+ }
41
+ /**
42
+ * Returns the formatted block, or `null` when `messages` is empty.
43
+ *
44
+ * Markup variants:
45
+ * - `"json-header"`: byte-identical to the pre-refactor openclaw output.
46
+ * Header is `"Messages (untrusted metadata):"` followed by a ` ```json `
47
+ * fenced JSON array.
48
+ * - `"xml-system-reminder"`: byte-identical to the pre-refactor nanoclaw
49
+ * output. `&lt;messages&gt;` wrapper around `&lt;message&gt;` entries with
50
+ * `sender`/`conversation`/`time` attributes; sender/conv/time/text all
51
+ * run through `sanitizeForSystemReminder`.
52
+ *
53
+ * Or pass a custom `formatter` callback — channel-base owns the empty-check
54
+ * + ownAgentId disambiguation; the callback owns the markup.
55
+ */
56
+ export function formatCrossConv(messages, opts) {
57
+ if (messages.length === 0)
58
+ return null;
59
+ if ("formatter" in opts) {
60
+ return opts.formatter(messages, { ownAgentId: opts.ownAgentId });
61
+ }
62
+ switch (opts.markup) {
63
+ case "json-header":
64
+ return formatJsonHeader(messages, { ownAgentId: opts.ownAgentId });
65
+ case "xml-system-reminder":
66
+ return formatXmlSystemReminder(messages, { ownAgentId: opts.ownAgentId });
67
+ }
68
+ }
69
+ //# sourceMappingURL=format-cross-conv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-cross-conv.js","sourceRoot":"","sources":["../../src/channel-base/format-cross-conv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAEL,yBAAyB,GAC1B,MAAM,eAAe,CAAC;AAWvB,MAAM,sBAAsB,GAAG,gCAAgC,CAAC;AAChE,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAS7B,SAAS,gBAAgB,CACvB,OAAyB,EACzB,IAAqC;IAErC,OAAO;QACL,YAAY,EAAE,OAAO,CAAC,gBAAgB,IAAI,YAAY,OAAO,CAAC,UAAU,EAAE;QAC1E,MAAM,EAAE,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU;QACzE,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CACvB,QAAqC,EACrC,IAAqC;IAErC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7D,OAAO,GAAG,sBAAsB,iBAAiB,IAAI,CAAC,SAAS,CAC7D,KAAK,EACL,IAAI,EACJ,kBAAkB,CACnB,UAAU,CAAC;AACd,CAAC;AAED,SAAS,uBAAuB,CAC9B,QAAqC,EACrC,IAAqC;IAErC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,gBAAgB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,yBAAyB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,yBAAyB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvD,OAAO,oBAAoB,MAAM,mBAAmB,IAAI,WAAW,IAAI,KAAK,IAAI,YAAY,CAAC;IAC/F,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,YAAY,EAAE,GAAG,KAAK,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAqC,EACrC,IAE2E;IAE3E,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;QACpB,KAAK,aAAa;YAChB,OAAO,gBAAgB,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACrE,KAAK,qBAAqB;YACxB,OAAO,uBAAuB,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Channel-base group-block helpers.
3
+ *
4
+ * Replaces nanoclaw's inline `formatGroupBlock` at
5
+ * `packages/nanoclaw-channel/src/channels/moltzap.ts → formatGroupBlock`. Also
6
+ * extracts the shared type-narrowing predicate (`getGroupFields`) consumed by
7
+ * openclaw (deriving `groupSubject` / `groupMembers` for the OpenClaw context)
8
+ * and nanoclaw (gating the inline group-block render).
9
+ */
10
+ import type { EnrichedConversationMeta } from "../channel-core.js";
11
+ import type { CrossConvMarkup } from "./format-cross-conv.js";
12
+ export interface GroupFields {
13
+ readonly name: string | undefined;
14
+ readonly participants: readonly string[];
15
+ }
16
+ export type GroupFormatter = (fields: GroupFields) => string;
17
+ /**
18
+ * Returns `{ name, participants }` when `meta?.type === "group"`; else `null`.
19
+ * Pure narrowing helper — callers use the non-null return to drive
20
+ * `formatGroupBlock` or per-channel field extraction (openclaw's
21
+ * `groupSubject` + `groupMembers`).
22
+ */
23
+ export declare function getGroupFields(meta: EnrichedConversationMeta | undefined): GroupFields | null;
24
+ /**
25
+ * Returns the formatted group block.
26
+ *
27
+ * Markup variants:
28
+ * - `"xml-system-reminder"`: byte-identical to the pre-refactor nanoclaw
29
+ * output (a `&lt;system-reminder&gt;` block with group name + participants).
30
+ * - `"json-header"`: empty string. Openclaw does not render a group block;
31
+ * it consumes `getGroupFields` directly to derive its OpenClaw-side
32
+ * `groupSubject` / `groupMembers` fields. The empty-string return locks
33
+ * the "openclaw renders no group block" behavior as an explicit,
34
+ * fixtured output (see arch sub-issue #605 §3.5).
35
+ *
36
+ * Or pass a custom `formatter` callback.
37
+ */
38
+ export declare function formatGroupBlock(fields: GroupFields, opts: {
39
+ readonly markup: CrossConvMarkup;
40
+ } | {
41
+ readonly formatter: GroupFormatter;
42
+ }): string;
43
+ //# sourceMappingURL=format-group-block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-group-block.d.ts","sourceRoot":"","sources":["../../src/channel-base/format-group-block.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,MAAM,CAAC;AAK7D;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,wBAAwB,GAAG,SAAS,GACzC,WAAW,GAAG,IAAI,CAGpB;AAgBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,WAAW,EACnB,IAAI,EACA;IAAE,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GACpC;IAAE,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GACzC,MAAM,CAQR"}