@zooid/transport-matrix 0.7.4 → 0.9.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.
package/src/router.ts CHANGED
@@ -16,6 +16,16 @@ export interface AgentBinding {
16
16
  */
17
17
  rooms: RoomBinding[]
18
18
  trigger: 'mention' | 'any'
19
+ /** Host path of the agent's workspace (resolved agent.workdir). Media files land here. */
20
+ workspaceDir?: string
21
+ /** Path prefix as the agent sees it: '/workspace' for containers, = workspaceDir for local. */
22
+ agentWorkspacePath?: string
23
+ }
24
+
25
+ export const MEDIA_MSGTYPES = new Set(['m.image', 'm.file', 'm.video', 'm.audio'])
26
+
27
+ export function isMediaMsgtype(t: string | undefined): boolean {
28
+ return t !== undefined && MEDIA_MSGTYPES.has(t)
19
29
  }
20
30
 
21
31
  export interface ThreadState {
@@ -49,6 +59,7 @@ export function route(
49
59
  ): RouteMatch[] {
50
60
  if (event.type !== 'm.room.message') return []
51
61
  if (!event.content?.msgtype) return []
62
+ if (isMediaMsgtype(event.content.msgtype)) return []
52
63
  const mentions = new Set(extractMentions(event as never))
53
64
  const matches: RouteMatch[] = []
54
65
  const threadRoot = inboundThreadRoot(event)
@@ -75,7 +75,7 @@ describe('ensureWorkforceSpace', () => {
75
75
  })
76
76
 
77
77
  describe('ensureWorkforceSpace privacy', () => {
78
- it('creates the space invite-only (overriding any public preset)', async () => {
78
+ it('creates the space invite-only by default (overriding any public preset)', async () => {
79
79
  const { client } = clientWithFetches(
80
80
  () => new Response(JSON.stringify({ errcode: 'M_NOT_FOUND' }), { status: 404 }),
81
81
  (url, init) => {
@@ -99,6 +99,31 @@ describe('ensureWorkforceSpace privacy', () => {
99
99
  })
100
100
  expect(id).toBe('!space:hs.zoon.local')
101
101
  })
102
+
103
+ it('creates a publicly-joinable space when joinRule is public (zooid dev)', async () => {
104
+ const { client } = clientWithFetches(
105
+ () => new Response(JSON.stringify({ errcode: 'M_NOT_FOUND' }), { status: 404 }),
106
+ (url, init) => {
107
+ expect(url).toContain('/_matrix/client/v3/createRoom')
108
+ const body = JSON.parse(init!.body as string)
109
+ expect(body.initial_state).toContainEqual({
110
+ type: 'm.room.join_rules',
111
+ state_key: '',
112
+ content: { join_rule: 'public' },
113
+ })
114
+ return new Response(JSON.stringify({ room_id: '!space:hs.zoon.local' }), { status: 200 })
115
+ },
116
+ )
117
+ const id = await ensureWorkforceSpace({
118
+ client,
119
+ asUserId: '@zooid:hs.zoon.local',
120
+ serverName: 'hs.zoon.local',
121
+ spaceLocalpart: 'dev',
122
+ preset: 'public_chat',
123
+ joinRule: 'public',
124
+ })
125
+ expect(id).toBe('!space:hs.zoon.local')
126
+ })
102
127
  })
103
128
 
104
129
  describe('ensureWorkforceSpace admins', () => {
@@ -13,6 +13,15 @@ export interface EnsureSpaceOpts {
13
13
  * if the alias already resolves we return the existing room untouched.
14
14
  */
15
15
  admins?: string[]
16
+ /**
17
+ * Join rule pinned on the space at creation. Defaults to `invite`: a
18
+ * workspace is joined by invitation, not self-service, so it can't be walked
19
+ * into (which would otherwise satisfy every restricted child room's `allow`).
20
+ * `zooid dev` passes `public` so a self-service-registered local account can
21
+ * join `#<space>` straight from the web client without an invite — acceptable
22
+ * because the dev homeserver is local-only and never deployed.
23
+ */
24
+ joinRule?: 'invite' | 'public'
16
25
  }
17
26
 
18
27
  export async function ensureWorkforceSpace(opts: EnsureSpaceOpts): Promise<string> {
@@ -26,10 +35,12 @@ export async function ensureWorkforceSpace(opts: EnsureSpaceOpts): Promise<strin
26
35
  name: display,
27
36
  preset: opts.preset,
28
37
  creation_content: { type: 'm.space' },
29
- // A workspace is joined by invitation, not self-service. Pin the space's
30
- // join rule to invite regardless of preset so it can't be walked into
31
- // (which would otherwise satisfy every restricted child room's allow).
32
- initial_state: [{ type: 'm.room.join_rules', state_key: '', content: { join_rule: 'invite' } }],
38
+ // Pin the join rule regardless of preset. Defaults to invite so the space
39
+ // can't be walked into (which would otherwise satisfy every restricted
40
+ // child room's allow); `zooid dev` opts into `public` for local-only use.
41
+ initial_state: [
42
+ { type: 'm.room.join_rules', state_key: '', content: { join_rule: opts.joinRule ?? 'invite' } },
43
+ ],
33
44
  }
34
45
  if (opts.admins && opts.admins.length > 0) {
35
46
  // Invite each admin so they actually become members — PL 100 alone does