@openmarket/rooms-client 0.4.0 → 0.4.1

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.
@@ -96,7 +96,7 @@ export function buildMergeProposalBootstrap(opts) {
96
96
  /** The librarian bootstrap for `/brief refresh`: the agent rewrites the
97
97
  * room's brief doc itself, in the canonical structure renderBrief pins. */
98
98
  export function buildBriefRefreshBootstrap(opts) {
99
- return lines(opts.personaLine, `You are the LIBRARIAN for ${opts.label}. Maintain its brief: a concise, current snapshot.`, "1. Read the recent conversation with room_history for this room.", `2. Read the existing brief if any: doc_read spaceId ${opts.spaceId}, path ${opts.path}.`, `3. List the docs in play with doc_list (spaceId ${opts.spaceId}).`, `4. Write the brief with doc_write (spaceId ${opts.spaceId}, path ${opts.path}, a note describing what changed), following EXACTLY this structure:`, "", `# Brief: ${opts.label}`, "", `> Auto-generated by the room agent, read-only. Updated ${opts.nowLabel}.`, "", "## Summary", "<one or two short paragraphs on what this room is about and where it stands>", "", "## Open threads", "- <unresolved questions, or `None.`>", "", "## Decisions", "- <decisions reached, or `None yet.`>", "", "## Docs in play", "- `path` (rN, when) for each referenced doc, or `None referenced.`", "", "Keep it tight and factual. Do NOT output a DRAFT line. After writing, reply with one line naming the revision you wrote.");
99
+ return lines(opts.personaLine, `You are the LIBRARIAN for ${opts.label}. Maintain its brief: a concise, current snapshot.`, "1. Read the recent conversation with room_history for this room.", `2. Read the existing brief if any: doc_read spaceId ${opts.spaceId}, path ${opts.path}.`, `3. List the docs in play with doc_list (spaceId ${opts.spaceId}).`, `4. Write the brief with doc_write (spaceId ${opts.spaceId}, path ${opts.path}, a note describing what changed), following EXACTLY this structure:`, "", `# Brief: ${opts.label}`, "", `> Auto-generated by the room agent, read-only. Updated ${opts.nowLabel}.`, "", "## Summary", "<one or two short paragraphs on what this room is about and where it stands>", "", "## Open questions", "- <unresolved questions, or `None.`>", "", "## Decisions", "- <decisions reached, or `None yet.`>", "", "## Docs in play", "- `path` (rN, when) for each referenced doc, or `None referenced.`", "", "Keep it tight and factual. Do NOT output a DRAFT line. After writing, reply with one line naming the revision you wrote.");
100
100
  }
101
101
  /** The scoped-summarize turn message. It runs on the DEFAULT lane bootstrap
102
102
  * (context spine + citation teaching already present); the message carries
@@ -107,7 +107,14 @@ export interface BriefInput {
107
107
  openThreads: string[];
108
108
  decisions: string[];
109
109
  docs: BriefDocRef[];
110
+ /** Highest message seq this brief has incorporated. Rendered into the
111
+ * banner as the librarian's shared cursor; co-librarians read it before
112
+ * spending anything. */
113
+ coveredSeq?: number;
110
114
  }
115
+ /** The banner's machine-readable coverage claim. Parsers must only consult
116
+ * the banner blockquote line, never body prose. */
117
+ export declare const BRIEF_COVERED_RE: RegExp;
111
118
  /** Render the canonical brief markdown. Deterministic shell; the LLM only
112
119
  * supplies the summary/threads/decisions prose. */
113
120
  export declare function renderBrief(input: BriefInput): string;
@@ -128,19 +128,23 @@ export function briefPath(roomName) {
128
128
  .slice(0, 60) || "room";
129
129
  return `briefs/${slug}.md`;
130
130
  }
131
+ /** The banner's machine-readable coverage claim. Parsers must only consult
132
+ * the banner blockquote line, never body prose. */
133
+ export const BRIEF_COVERED_RE = /\bCovers through seq (\d+)\./;
131
134
  /** Render the canonical brief markdown. Deterministic shell; the LLM only
132
135
  * supplies the summary/threads/decisions prose. */
133
136
  export function renderBrief(input) {
137
+ const covered = input.coveredSeq !== undefined ? ` Covers through seq ${input.coveredSeq}.` : "";
134
138
  const lines = [];
135
139
  lines.push(`# Brief: ${input.room}`);
136
140
  lines.push("");
137
- lines.push(`> Auto-generated by the room agent, read-only. Updated ${input.updatedAtLabel}.`);
141
+ lines.push(`> Auto-generated by the room agent, read-only. Updated ${input.updatedAtLabel}.${covered}`);
138
142
  lines.push("");
139
143
  lines.push("## Summary");
140
144
  lines.push("");
141
145
  lines.push(input.summary.trim() || "_No summary yet._");
142
146
  lines.push("");
143
- lines.push("## Open threads");
147
+ lines.push("## Open questions");
144
148
  lines.push("");
145
149
  if (input.openThreads.length === 0)
146
150
  lines.push("_None._");
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type RoomAccessMode, type RoomAttachmentInput, type RoomAuditLogPayload, type RoomAuthSuccessPayload, type RoomBackfillPayload, type RoomClientPlatform, type RoomDmHistoryResultPayload, type RoomDmMessagePayload, type RoomDmOpenedPayload, type RoomFriendPresence, type RoomInvitedPayload, type RoomLedgerEntry, type RoomMemberRemovedPayload, type RoomMemberRoleChangedPayload, type RoomMeta, type RoomPinsPayload, type RoomPresencePayload, type RoomReactorsPayload, type RoomReadStatePayload, type RoomReportedPayload, type RoomRole, type RoomSearchResultsPayload, type RoomSearchScope, type RoomSpace, type RoomThreadPayload, type RoomTopic, type RoomTopicAttention, type RoomTopicResultPayload, type RoomTopicsResultPayload, type RoomUserStatus, type RoomWhoPayload } from "./types.js";
1
+ import { type RoomAccessMode, type RoomAttachmentInput, type RoomAuditLogPayload, type RoomAuthSuccessPayload, type RoomBackfillPayload, type RoomClientPlatform, type RoomDmHistoryResultPayload, type RoomDmInboxUpdatedPayload, type RoomDmMessagePayload, type RoomDmOpenedPayload, type RoomFriendPresence, type RoomInvitedPayload, type RoomLedgerEntry, type RoomMemberRemovedPayload, type RoomMemberRoleChangedPayload, type RoomMeta, type RoomPinsPayload, type RoomPresencePayload, type RoomReactorsPayload, type RoomReadStatePayload, type RoomReportedPayload, type RoomRole, type RoomSearchResultsPayload, type RoomSearchScope, type RoomSpace, type RoomThreadPayload, type RoomTopic, type RoomTopicAttention, type RoomTopicResultPayload, type RoomTopicsResultPayload, type RoomUserStatus, type RoomWhoPayload } from "./types.js";
2
2
  import { type RoomWebSocketCtor, RoomWsClient } from "./ws-client.js";
3
3
  export interface RoomClientConfig {
4
4
  url: string;
@@ -213,6 +213,10 @@ export interface RoomDmSendRequest {
213
213
  * Additive — omitted for text-only sends. */
214
214
  imageUrl?: string;
215
215
  }
216
+ export interface RoomDmReadRequest {
217
+ username?: string;
218
+ conversationId?: string;
219
+ }
216
220
  export interface RoomThreadRequest {
217
221
  room: string;
218
222
  rootSeq: number;
@@ -254,6 +258,7 @@ export declare function whoamiRoom(config: RoomClientConfig): Promise<RoomAuthSu
254
258
  export declare function requestRoomFriends(client: RoomWsClient): Promise<RoomFriendPresence[]>;
255
259
  export declare function openRoomDmOnClient(client: RoomWsClient, request: RoomDmOpenRequest, timeoutMs?: number): Promise<RoomDmOpenedPayload>;
256
260
  export declare function requestRoomDmHistoryOnClient(client: RoomWsClient, request: RoomDmHistoryRequest, timeoutMs?: number): Promise<RoomDmHistoryResultPayload>;
261
+ export declare function markRoomDmReadOnClient(client: RoomWsClient, request: RoomDmReadRequest, timeoutMs?: number): Promise<RoomDmInboxUpdatedPayload>;
257
262
  export declare function sendRoomDmOnClient(client: RoomWsClient, request: RoomDmSendRequest, timeoutMs?: number): Promise<RoomDmMessagePayload>;
258
263
  /** Edit one of my DM messages. Fire-and-forget over the WS; the relay fans out
259
264
  * DM_MESSAGE_EDITED to both participants. */
package/dist/client.js CHANGED
@@ -454,6 +454,20 @@ export async function requestRoomDmHistoryOnClient(client, request, timeoutMs) {
454
454
  const history = await client.waitFor(RoomServerMessageType.DM_HISTORY, (msg) => msg.payload.requestId === requestId, timeoutMs, requestId);
455
455
  return history.payload;
456
456
  }
457
+ export async function markRoomDmReadOnClient(client, request, timeoutMs) {
458
+ const requestId = randomUUID();
459
+ client.send({
460
+ type: RoomClientMessageType.DM_READ,
461
+ payload: {
462
+ requestId,
463
+ ...(request.username ? { username: request.username } : {}),
464
+ ...(request.conversationId ? { conversationId: request.conversationId } : {}),
465
+ },
466
+ timestamp: Date.now(),
467
+ });
468
+ const updated = await client.waitFor(RoomServerMessageType.DM_INBOX_UPDATED, (msg) => msg.payload.requestId === requestId, timeoutMs, requestId);
469
+ return updated.payload;
470
+ }
457
471
  export async function sendRoomDmOnClient(client, request, timeoutMs) {
458
472
  const requestId = randomUUID();
459
473
  const clientMsgId = request.clientMsgId ?? randomUUID();
@@ -575,6 +575,7 @@ export interface RoomDmMessagePayload {
575
575
  clientMsgId?: string;
576
576
  }
577
577
  export interface RoomDmInboxUpdatedPayload {
578
+ requestId?: string;
578
579
  conversationId: string;
579
580
  participant: RoomDmParticipant;
580
581
  unreadCount: number;
@@ -174,7 +174,8 @@ export interface RoomSpaceSummary {
174
174
  export declare function listRoomSpacesViaChat(config: RoomSocialConfig): Promise<RoomSpaceSummary[]>;
175
175
  export interface RoomSpaceMember {
176
176
  userId: string;
177
- role: "owner" | "admin" | "member";
177
+ /** The ladder role. 'librarian' maintains the generated briefs/ docs. */
178
+ role: "owner" | "admin" | "librarian" | "member";
178
179
  /** Named identity roles (RoomSpaceRole.roleId). */
179
180
  roleIds?: string[];
180
181
  joinedAt?: string;
@@ -329,7 +330,7 @@ export declare function listRoomChannelMembers(config: RoomSocialConfig, roomId:
329
330
  export declare function removeSpaceMember(config: RoomSocialConfig, spaceId: string, targetUserId: string): Promise<{
330
331
  removed?: boolean;
331
332
  }>;
332
- export declare function changeSpaceMemberRole(config: RoomSocialConfig, spaceId: string, targetUserId: string, role: "admin" | "member"): Promise<RoomSpaceMember>;
333
+ export declare function changeSpaceMemberRole(config: RoomSocialConfig, spaceId: string, targetUserId: string, role: "admin" | "librarian" | "member"): Promise<RoomSpaceMember>;
333
334
  /** Set (string) or clear (null) a member's per-space nickname; the store validates and enforces uniqueness. */
334
335
  export declare function setSpaceMemberNickname(config: RoomSocialConfig, spaceId: string, targetUserId: string, nickname: string | null): Promise<RoomSpaceMember>;
335
336
  export declare function createRoomSpace(config: RoomSocialConfig, input: {
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.5.1";
2
- export declare const RUNNER_VERSION = "0.5.1";
1
+ export declare const VERSION = "0.6.0";
2
+ export declare const RUNNER_VERSION = "0.6.0";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = "0.5.1";
2
- export const RUNNER_VERSION = "0.5.1";
1
+ export const VERSION = "0.6.0";
2
+ export const RUNNER_VERSION = "0.6.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmarket/rooms-client",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "OM Rooms protocol client: wire types, WebSocket + REST clients, and chat view-models. Browser-safe (no node:/bun: imports).",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -202,7 +202,7 @@ export function buildBriefRefreshBootstrap(opts: {
202
202
  "## Summary",
203
203
  "<one or two short paragraphs on what this room is about and where it stands>",
204
204
  "",
205
- "## Open threads",
205
+ "## Open questions",
206
206
  "- <unresolved questions, or `None.`>",
207
207
  "",
208
208
  "## Decisions",
@@ -202,21 +202,32 @@ export interface BriefInput {
202
202
  openThreads: string[];
203
203
  decisions: string[];
204
204
  docs: BriefDocRef[];
205
+ /** Highest message seq this brief has incorporated. Rendered into the
206
+ * banner as the librarian's shared cursor; co-librarians read it before
207
+ * spending anything. */
208
+ coveredSeq?: number;
205
209
  }
206
210
 
211
+ /** The banner's machine-readable coverage claim. Parsers must only consult
212
+ * the banner blockquote line, never body prose. */
213
+ export const BRIEF_COVERED_RE = /\bCovers through seq (\d+)\./;
214
+
207
215
  /** Render the canonical brief markdown. Deterministic shell; the LLM only
208
216
  * supplies the summary/threads/decisions prose. */
209
217
  export function renderBrief(input: BriefInput): string {
218
+ const covered = input.coveredSeq !== undefined ? ` Covers through seq ${input.coveredSeq}.` : "";
210
219
  const lines: string[] = [];
211
220
  lines.push(`# Brief: ${input.room}`);
212
221
  lines.push("");
213
- lines.push(`> Auto-generated by the room agent, read-only. Updated ${input.updatedAtLabel}.`);
222
+ lines.push(
223
+ `> Auto-generated by the room agent, read-only. Updated ${input.updatedAtLabel}.${covered}`,
224
+ );
214
225
  lines.push("");
215
226
  lines.push("## Summary");
216
227
  lines.push("");
217
228
  lines.push(input.summary.trim() || "_No summary yet._");
218
229
  lines.push("");
219
- lines.push("## Open threads");
230
+ lines.push("## Open questions");
220
231
  lines.push("");
221
232
  if (input.openThreads.length === 0) lines.push("_None._");
222
233
  else for (const t of input.openThreads) lines.push(`- ${t}`);
package/src/client.ts CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  RoomClientMessageType,
16
16
  type RoomClientPlatform,
17
17
  type RoomDmHistoryResultPayload,
18
+ type RoomDmInboxUpdatedPayload,
18
19
  type RoomDmMessagePayload,
19
20
  type RoomDmOpenedPayload,
20
21
  type RoomFriendPresence,
@@ -293,6 +294,11 @@ export interface RoomDmSendRequest {
293
294
  imageUrl?: string;
294
295
  }
295
296
 
297
+ export interface RoomDmReadRequest {
298
+ username?: string;
299
+ conversationId?: string;
300
+ }
301
+
296
302
  export interface RoomThreadRequest {
297
303
  room: string;
298
304
  rootSeq: number;
@@ -923,6 +929,30 @@ export async function requestRoomDmHistoryOnClient(
923
929
  return history.payload;
924
930
  }
925
931
 
932
+ export async function markRoomDmReadOnClient(
933
+ client: RoomWsClient,
934
+ request: RoomDmReadRequest,
935
+ timeoutMs?: number,
936
+ ): Promise<RoomDmInboxUpdatedPayload> {
937
+ const requestId = randomUUID();
938
+ client.send({
939
+ type: RoomClientMessageType.DM_READ,
940
+ payload: {
941
+ requestId,
942
+ ...(request.username ? { username: request.username } : {}),
943
+ ...(request.conversationId ? { conversationId: request.conversationId } : {}),
944
+ },
945
+ timestamp: Date.now(),
946
+ });
947
+ const updated = await client.waitFor(
948
+ RoomServerMessageType.DM_INBOX_UPDATED,
949
+ (msg) => msg.payload.requestId === requestId,
950
+ timeoutMs,
951
+ requestId,
952
+ );
953
+ return updated.payload;
954
+ }
955
+
926
956
  export async function sendRoomDmOnClient(
927
957
  client: RoomWsClient,
928
958
  request: RoomDmSendRequest,
@@ -674,6 +674,7 @@ export interface RoomDmMessagePayload {
674
674
  }
675
675
 
676
676
  export interface RoomDmInboxUpdatedPayload {
677
+ requestId?: string;
677
678
  conversationId: string;
678
679
  participant: RoomDmParticipant;
679
680
  unreadCount: number;
@@ -657,7 +657,8 @@ export async function listRoomSpacesViaChat(config: RoomSocialConfig): Promise<R
657
657
 
658
658
  export interface RoomSpaceMember {
659
659
  userId: string;
660
- role: "owner" | "admin" | "member";
660
+ /** The ladder role. 'librarian' maintains the generated briefs/ docs. */
661
+ role: "owner" | "admin" | "librarian" | "member";
661
662
  /** Named identity roles (RoomSpaceRole.roleId). */
662
663
  roleIds?: string[];
663
664
  joinedAt?: string;
@@ -1047,7 +1048,7 @@ export async function changeSpaceMemberRole(
1047
1048
  config: RoomSocialConfig,
1048
1049
  spaceId: string,
1049
1050
  targetUserId: string,
1050
- role: "admin" | "member",
1051
+ role: "admin" | "librarian" | "member",
1051
1052
  ): Promise<RoomSpaceMember> {
1052
1053
  const result = await socialRequest<{ member: RoomSpaceMember }>(
1053
1054
  config,
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = "0.5.1";
2
- export const RUNNER_VERSION = "0.5.1";
1
+ export const VERSION = "0.6.0";
2
+ export const RUNNER_VERSION = "0.6.0";