@underdogai/mesh-event-schemas 0.3.0 → 0.8.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 (45) hide show
  1. package/dist/apppacks.d.ts +6070 -693
  2. package/dist/apppacks.d.ts.map +1 -1
  3. package/dist/apppacks.js +1 -1
  4. package/dist/blocks.d.ts +1402 -84
  5. package/dist/blocks.d.ts.map +1 -1
  6. package/dist/blocks.js +246 -13
  7. package/dist/blocks.js.map +1 -1
  8. package/dist/capabilities.d.ts +13 -1
  9. package/dist/capabilities.d.ts.map +1 -1
  10. package/dist/capabilities.js +13 -1
  11. package/dist/capabilities.js.map +1 -1
  12. package/dist/events.d.ts +1875 -174
  13. package/dist/events.d.ts.map +1 -1
  14. package/dist/events.js +190 -2
  15. package/dist/events.js.map +1 -1
  16. package/dist/geo.d.ts +52 -0
  17. package/dist/geo.d.ts.map +1 -0
  18. package/dist/geo.js +65 -0
  19. package/dist/geo.js.map +1 -0
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +1 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/namespace.d.ts +13 -0
  25. package/dist/namespace.d.ts.map +1 -1
  26. package/dist/namespace.js +13 -0
  27. package/dist/namespace.js.map +1 -1
  28. package/dist/registry.d.ts +3 -2
  29. package/dist/registry.d.ts.map +1 -1
  30. package/dist/registry.js +36 -3
  31. package/dist/registry.js.map +1 -1
  32. package/dist/surfaces.d.ts +31135 -3417
  33. package/dist/surfaces.d.ts.map +1 -1
  34. package/dist/surfaces.js +8 -1
  35. package/dist/surfaces.js.map +1 -1
  36. package/package.json +1 -1
  37. package/src/apppacks.ts +1 -1
  38. package/src/blocks.ts +260 -14
  39. package/src/capabilities.ts +13 -1
  40. package/src/events.ts +207 -5
  41. package/src/geo.ts +75 -0
  42. package/src/index.ts +1 -0
  43. package/src/namespace.ts +13 -0
  44. package/src/registry.ts +38 -2
  45. package/src/surfaces.ts +8 -0
package/dist/blocks.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 설계 원칙 (docs/custom-event-ui.md 참조):
5
5
  * - 닫힌(화이트리스트) 컴포넌트 집합. 임의 HTML/코드 실행 없음.
6
- * - 순수 데이터(JSON). 렌더는 @chatops/ui-blocks(React)가 담당.
6
+ * - 순수 데이터(JSON). 렌더는 @chatops/spec-renderer(React)가 담당.
7
7
  * - 알 수 없는 블록 타입은 클라이언트가 안전한 fallback으로 렌더.
8
8
  * - 권한은 절대 클라이언트가 아니라 appservice(서버측)가 재검증한다. 여기 disabled/confirm은 UX일 뿐.
9
9
  *
@@ -15,6 +15,56 @@ export declare const ToneSchema: z.ZodEnum<["neutral", "success", "warning", "da
15
15
  export type Tone = z.infer<typeof ToneSchema>;
16
16
  export declare const ButtonStyleSchema: z.ZodEnum<["default", "primary", "danger"]>;
17
17
  export type ButtonStyle = z.infer<typeof ButtonStyleSchema>;
18
+ /**
19
+ * **참조 값**(0.8.0) — 사람·엔티티를 문자열이 아니라 가리키는 값으로 싣는다.
20
+ *
21
+ * 왜 필요한가: 같은 사람이 카드 안에서 세 표기로 흩어진다 — fields 의 "현호 손", 옵션 라벨
22
+ * "goya@bluepinlabs.com", 이력의 "heetae". 앱이 서버에서 표시명을 만들어 문자열로 박기 때문인데,
23
+ * 그러면 형식이 갈리고 얼굴이 없고 개명·동명이인에 취약하다. 값이 **MXID 참조**이고 클라가 방 상태로
24
+ * 이름·아바타를 해석하면, 어느 블록에 놓여도 같은 얼굴로 선다.
25
+ *
26
+ * 🔴 **평문 사본은 남는다**(`fields.parts` 와 같은 규칙 — §4). `ref` 를 모르는 옛 클라는 이 키를
27
+ * zod strip 으로 벗기고 `value`/`label`/`name` 문자열을 지금처럼 그린다. 그래서 참조를 실으면서도
28
+ * 사본을 비우면 **그 필드가 빈칸이 된다** — 사본은 선택이 아니라 계약이다.
29
+ *
30
+ * 🔴 **이것도 권한이 아니다.** 값이 MXID 라는 것은 서버가 멤버십으로 재검증할 수 있다는 뜻이지,
31
+ * 클라가 신원을 판정한다는 뜻이 아니다.
32
+ */
33
+ export declare const RefSchema: z.ZodUnion<[z.ZodObject<{
34
+ /** Matrix 사용자 id — `@local:server` 형태. 해석(이름·아바타)은 호스트가 주입한다(PeopleProvider). */
35
+ user: z.ZodString;
36
+ }, "strip", z.ZodTypeAny, {
37
+ user: string;
38
+ }, {
39
+ user: string;
40
+ }>, z.ZodObject<{
41
+ /** 도메인 엔티티 — `entityRef` **블록**이 이미 쓰는 종류/식별자 짝이 값 안으로 들어온 것. */
42
+ entity: z.ZodObject<{
43
+ type: z.ZodString;
44
+ id: z.ZodString;
45
+ }, "strip", z.ZodTypeAny, {
46
+ type: string;
47
+ id: string;
48
+ }, {
49
+ type: string;
50
+ id: string;
51
+ }>;
52
+ /** 클릭 시 이동할 https URL(선택). 출처는 클라가 검증한다. */
53
+ url: z.ZodOptional<z.ZodString>;
54
+ }, "strip", z.ZodTypeAny, {
55
+ entity: {
56
+ type: string;
57
+ id: string;
58
+ };
59
+ url?: string | undefined;
60
+ }, {
61
+ entity: {
62
+ type: string;
63
+ id: string;
64
+ };
65
+ url?: string | undefined;
66
+ }>]>;
67
+ export type Ref = z.infer<typeof RefSchema>;
18
68
  /** 파괴적 액션 전에 클라이언트가 띄우는 확인 다이얼로그. 서버도 별도로 HITL 재검증한다. */
19
69
  export declare const ConfirmSchema: z.ZodObject<{
20
70
  title: z.ZodString;
@@ -36,7 +86,16 @@ export type Confirm = z.infer<typeof ConfirmSchema>;
36
86
  export declare const TextBlockSchema: z.ZodObject<{
37
87
  type: z.ZodLiteral<"text">;
38
88
  text: z.ZodString;
39
- /** true면 안전 화이트리스트 마크다운으로 렌더 (raw HTML 금지) */
89
+ /**
90
+ * true면 안전 화이트리스트 마크다운으로 렌더 (raw HTML 금지).
91
+ *
92
+ * 인라인: `**굵게**` `*기울임*` `` `코드` `` `[텍스트](http…)`.
93
+ * 블록: 문단(빈 줄) · 목록(`-` `*` `+` / `1.`, 중첩 가능) · 제목(`#`~`###`) · 인용(`>`) ·
94
+ * 구분선(`---`) · 펜스 코드(``` ```` ```).
95
+ * 표는 지원하지 않는다 — 표는 `table` 블록이 따로 있다.
96
+ *
97
+ * 플래그를 안 주면 평문이다(줄바꿈만 살아난다). 긴 글에는 켜는 쪽이 읽힌다 — #581.
98
+ */
40
99
  markdown: z.ZodOptional<z.ZodBoolean>;
41
100
  }, "strip", z.ZodTypeAny, {
42
101
  type: "text";
@@ -92,6 +151,44 @@ export declare const FieldsBlockSchema: z.ZodObject<{
92
151
  text: string;
93
152
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
94
153
  }>, "many">>;
154
+ /**
155
+ * 이 값이 가리키는 사람/엔티티 (0.8.0). 있으면 렌더러가 칩(아바타+이름 / 종류+라벨)으로 그린다.
156
+ * 🔴 **`value` 는 평문 사본으로 남긴다** — `parts` 와 같은 규칙이다(RefSchema 머리말).
157
+ */
158
+ ref: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
159
+ /** Matrix 사용자 id — `@local:server` 형태. 해석(이름·아바타)은 호스트가 주입한다(PeopleProvider). */
160
+ user: z.ZodString;
161
+ }, "strip", z.ZodTypeAny, {
162
+ user: string;
163
+ }, {
164
+ user: string;
165
+ }>, z.ZodObject<{
166
+ /** 도메인 엔티티 — `entityRef` **블록**이 이미 쓰는 종류/식별자 짝이 값 안으로 들어온 것. */
167
+ entity: z.ZodObject<{
168
+ type: z.ZodString;
169
+ id: z.ZodString;
170
+ }, "strip", z.ZodTypeAny, {
171
+ type: string;
172
+ id: string;
173
+ }, {
174
+ type: string;
175
+ id: string;
176
+ }>;
177
+ /** 클릭 시 이동할 https URL(선택). 출처는 클라가 검증한다. */
178
+ url: z.ZodOptional<z.ZodString>;
179
+ }, "strip", z.ZodTypeAny, {
180
+ entity: {
181
+ type: string;
182
+ id: string;
183
+ };
184
+ url?: string | undefined;
185
+ }, {
186
+ entity: {
187
+ type: string;
188
+ id: string;
189
+ };
190
+ url?: string | undefined;
191
+ }>]>>;
95
192
  }, "strip", z.ZodTypeAny, {
96
193
  value: string;
97
194
  label: string;
@@ -100,6 +197,15 @@ export declare const FieldsBlockSchema: z.ZodObject<{
100
197
  text: string;
101
198
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
102
199
  }[] | undefined;
200
+ ref?: {
201
+ user: string;
202
+ } | {
203
+ entity: {
204
+ type: string;
205
+ id: string;
206
+ };
207
+ url?: string | undefined;
208
+ } | undefined;
103
209
  }, {
104
210
  value: string;
105
211
  label: string;
@@ -108,6 +214,15 @@ export declare const FieldsBlockSchema: z.ZodObject<{
108
214
  text: string;
109
215
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
110
216
  }[] | undefined;
217
+ ref?: {
218
+ user: string;
219
+ } | {
220
+ entity: {
221
+ type: string;
222
+ id: string;
223
+ };
224
+ url?: string | undefined;
225
+ } | undefined;
111
226
  }>, "many">;
112
227
  }, "strip", z.ZodTypeAny, {
113
228
  type: "fields";
@@ -119,6 +234,15 @@ export declare const FieldsBlockSchema: z.ZodObject<{
119
234
  text: string;
120
235
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
121
236
  }[] | undefined;
237
+ ref?: {
238
+ user: string;
239
+ } | {
240
+ entity: {
241
+ type: string;
242
+ id: string;
243
+ };
244
+ url?: string | undefined;
245
+ } | undefined;
122
246
  }[];
123
247
  }, {
124
248
  type: "fields";
@@ -130,6 +254,15 @@ export declare const FieldsBlockSchema: z.ZodObject<{
130
254
  text: string;
131
255
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
132
256
  }[] | undefined;
257
+ ref?: {
258
+ user: string;
259
+ } | {
260
+ entity: {
261
+ type: string;
262
+ id: string;
263
+ };
264
+ url?: string | undefined;
265
+ } | undefined;
133
266
  }[];
134
267
  }>;
135
268
  export declare const ImageBlockSchema: z.ZodObject<{
@@ -149,9 +282,18 @@ export declare const ImageBlockSchema: z.ZodObject<{
149
282
  mxc?: string | undefined;
150
283
  alt?: string | undefined;
151
284
  }>;
285
+ /**
286
+ * 작은 보조 텍스트/아이콘 줄.
287
+ *
288
+ * ⬜ **여기엔 `ref` 원소를 안 둔다(0.8.0에서 일부러 뺐다).** 다른 자리의 참조는 *기존 객체의 새 키*라
289
+ * 옛 클라가 zod strip 으로 벗기고 평문 사본을 그리지만, 여기 `elements` 는 **닫힌 유니온**이라 새
290
+ * 모양의 원소 하나가 유니온 전체를 실패시키고 → 배열이 실패하고 → `dropUnknownBlocks` 가 **context
291
+ * 블록을 통째로 떨군다**. 즉 "평문 사본이 곁에 선다"는 규칙이 성립하지 않는 유일한 자리다
292
+ * (`parts`·`hidden_for`·`ref` 가 다 되는 이유가 그 셋은 키 추가이기 때문이다).
293
+ * 사람을 보조 줄에 그리고 싶으면 `activity` 블록이나 `fields` 항목의 `ref` 를 쓴다.
294
+ */
152
295
  export declare const ContextBlockSchema: z.ZodObject<{
153
296
  type: z.ZodLiteral<"context">;
154
- /** 작은 보조 텍스트/아이콘 줄 */
155
297
  elements: z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodObject<{
156
298
  icon: z.ZodString;
157
299
  }, "strip", z.ZodTypeAny, {
@@ -228,26 +370,68 @@ export declare const InputBlockSchema: z.ZodObject<{
228
370
  * 단일 업로드로 동작한다(기능 축소일 뿐 파손 없음).
229
371
  */
230
372
  multiple: z.ZodOptional<z.ZodBoolean>;
373
+ /**
374
+ * 하한/상한 (0.7.0) — number/date/datetime/time 공용. **문자열**이다: 날짜·시각은 그 타입의 값
375
+ * 형식(`2026-09-22`·`18:15`)이고, number 면 숫자를 적은 문자열이다(와이어 canonical JSON 은
376
+ * 소수를 허용하지 않아 숫자 축을 열 수 없다 — `slider` 가 int 만 받는 것과 같은 제약).
377
+ *
378
+ * `"today"` 리터럴을 허용한다 — "기한은 오늘 이후"는 카드를 **보낸 날**이 아니라 **보는 날** 기준이라야
379
+ * 맞다(카드는 타임라인에 남고 며칠 뒤에도 눌린다). 렌더러가 그릴 때 해석한다.
380
+ *
381
+ * 🔴 **UX 다, 진실은 서버**(`hidden_for` 와 같은 자세). 클라가 미리 잠그는 건 헛걸음을 줄이려는
382
+ * 것뿐이고, 진짜 판정은 언제나 핸들러·게이트가 한다. 이 키를 모르는 옛 클라는 strip 하고 지금처럼
383
+ * 아무 제약 없이 제출한다 — 그러면 서버가 사람이 읽을 이유와 함께 거절한다(`action.result`).
384
+ */
385
+ min: z.ZodOptional<z.ZodString>;
386
+ max: z.ZodOptional<z.ZodString>;
387
+ /** 글자 수 하한/상한 (0.7.0) — 텍스트 계열 전용. 🔴 UX 다, 진실은 서버. */
388
+ minLength: z.ZodOptional<z.ZodNumber>;
389
+ maxLength: z.ZodOptional<z.ZodNumber>;
390
+ /**
391
+ * 값이 맞아야 하는 정규식 **소스**(0.7.0, 예: `"^[A-Z]{2}-\\d{4}$"`). 플래그·구분자 없이 패턴만 적는다.
392
+ *
393
+ * 🔴 렌더러는 `new RegExp` 를 **try/catch 로 감싼다** — 작성자가 자바스크립트가 아닌 방언(파이썬
394
+ * `(?P<x>…)` 등)을 보내면 던지는데, 그걸로 카드 전체가 죽으면 안 된다. 못 읽는 패턴은 무시한다
395
+ * (= 제약 없음). 진짜 판정은 여전히 서버다.
396
+ */
397
+ pattern: z.ZodOptional<z.ZodString>;
398
+ /**
399
+ * 제약 위반 시 보여 줄 **작성자 소유 문장**(0.7.0). 없으면 렌더러 크롬 문구를 쓴다
400
+ * (`LabelContext` — "누구의 문자열인가"가 경계선이고, 도메인 사정을 아는 문장은 작성자 것이다).
401
+ */
402
+ error: z.ZodOptional<z.ZodString>;
231
403
  }, "strip", z.ZodTypeAny, {
232
404
  type: "input";
233
405
  name: string;
234
406
  value?: string | undefined;
235
407
  label?: string | undefined;
236
- input?: "number" | "text" | "date" | "url" | "textarea" | "datetime" | "time" | "email" | "file" | undefined;
408
+ input?: "number" | "date" | "url" | "text" | "textarea" | "datetime" | "time" | "email" | "file" | undefined;
237
409
  placeholder?: string | undefined;
238
410
  required?: boolean | undefined;
239
411
  accept?: string | undefined;
240
412
  multiple?: boolean | undefined;
413
+ min?: string | undefined;
414
+ max?: string | undefined;
415
+ minLength?: number | undefined;
416
+ maxLength?: number | undefined;
417
+ pattern?: string | undefined;
418
+ error?: string | undefined;
241
419
  }, {
242
420
  type: "input";
243
421
  name: string;
244
422
  value?: string | undefined;
245
423
  label?: string | undefined;
246
- input?: "number" | "text" | "date" | "url" | "textarea" | "datetime" | "time" | "email" | "file" | undefined;
424
+ input?: "number" | "date" | "url" | "text" | "textarea" | "datetime" | "time" | "email" | "file" | undefined;
247
425
  placeholder?: string | undefined;
248
426
  required?: boolean | undefined;
249
427
  accept?: string | undefined;
250
428
  multiple?: boolean | undefined;
429
+ min?: string | undefined;
430
+ max?: string | undefined;
431
+ minLength?: number | undefined;
432
+ maxLength?: number | undefined;
433
+ pattern?: string | undefined;
434
+ error?: string | undefined;
251
435
  }>;
252
436
  /** 토글(스위치) — checkbox 와 같은 불리언을 수집하되 on/off 스위치 어포던스로 렌더. */
253
437
  export declare const ToggleBlockSchema: z.ZodObject<{
@@ -311,7 +495,12 @@ export declare const SliderBlockSchema: z.ZodObject<{
311
495
  unit?: string | undefined;
312
496
  }>;
313
497
  export type SliderBlock = z.infer<typeof SliderBlockSchema>;
314
- /** 단일 선택 라디오 그룹. select 와 달리 옵션이 펼쳐져 보인다. */
498
+ /** 단일 선택 라디오 그룹. select 와 달리 옵션이 펼쳐져 보인다.
499
+ * 옵션 `hint` = 라벨 아래 한 줄 보조 설명(선택) — "버그 — 뭔가 잘못 동작해요" 처럼 라벨에 설명을
500
+ * 욱여넣던 것을 두 줄로 가른다(가독성). 옛 클라는 zod 가 벗겨내므로 라벨만 보인다(하위호환).
501
+ * `style` = 표현 힌트(선택): "cards" 는 옵션을 전체폭 카드 행으로, "segmented" 는 한 줄 세그먼트로
502
+ * (짧은 라벨 전용 — 렌더러가 hint 를 숨긴다). 값 의미는 동일하고 옛 클라는 평 라디오로 그린다.
503
+ * ⚠️ 위치 선택자(:first-child)로 특정 폼만 다르게 칠하지 말 것 — 표현은 이 필드로 선언한다. */
315
504
  export declare const RadioBlockSchema: z.ZodObject<{
316
505
  type: z.ZodLiteral<"radio">;
317
506
  name: z.ZodString;
@@ -319,71 +508,180 @@ export declare const RadioBlockSchema: z.ZodObject<{
319
508
  options: z.ZodArray<z.ZodObject<{
320
509
  value: z.ZodString;
321
510
  label: z.ZodString;
511
+ hint: z.ZodOptional<z.ZodString>;
322
512
  }, "strip", z.ZodTypeAny, {
323
513
  value: string;
324
514
  label: string;
515
+ hint?: string | undefined;
325
516
  }, {
326
517
  value: string;
327
518
  label: string;
519
+ hint?: string | undefined;
328
520
  }>, "many">;
329
521
  value: z.ZodOptional<z.ZodString>;
522
+ style: z.ZodOptional<z.ZodEnum<["cards", "segmented"]>>;
523
+ /** 고르지 않으면 제출을 잠근다 (0.7.0). 🔴 UX 다, 진실은 서버 — `input.required` 와 같은 자세. */
524
+ required: z.ZodOptional<z.ZodBoolean>;
525
+ /** 미선택 시 보여 줄 작성자 소유 문장 (0.7.0). 없으면 렌더러 크롬 문구. */
526
+ error: z.ZodOptional<z.ZodString>;
330
527
  }, "strip", z.ZodTypeAny, {
331
528
  options: {
332
529
  value: string;
333
530
  label: string;
531
+ hint?: string | undefined;
334
532
  }[];
335
533
  type: "radio";
336
534
  name: string;
337
535
  value?: string | undefined;
338
536
  label?: string | undefined;
537
+ required?: boolean | undefined;
538
+ error?: string | undefined;
539
+ style?: "cards" | "segmented" | undefined;
339
540
  }, {
340
541
  options: {
341
542
  value: string;
342
543
  label: string;
544
+ hint?: string | undefined;
343
545
  }[];
344
546
  type: "radio";
345
547
  name: string;
346
548
  value?: string | undefined;
347
549
  label?: string | undefined;
550
+ required?: boolean | undefined;
551
+ error?: string | undefined;
552
+ style?: "cards" | "segmented" | undefined;
348
553
  }>;
349
554
  export declare const SelectBlockSchema: z.ZodObject<{
350
555
  type: z.ZodLiteral<"select">;
351
556
  name: z.ZodString;
352
557
  label: z.ZodOptional<z.ZodString>;
353
558
  placeholder: z.ZodOptional<z.ZodString>;
559
+ /**
560
+ * 후보 목록. `ref`(0.8.0)를 주면 렌더러가 행을 칩(아바타·이름·MXID)으로 그린다 —
561
+ * 🔴 `label` 은 평문 사본으로 남긴다(RefSchema 머리말). 그리는 쪽은 P5(선택 모델)가 맡는다.
562
+ */
354
563
  options: z.ZodArray<z.ZodObject<{
355
564
  value: z.ZodString;
356
565
  label: z.ZodString;
566
+ ref: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
567
+ /** Matrix 사용자 id — `@local:server` 형태. 해석(이름·아바타)은 호스트가 주입한다(PeopleProvider). */
568
+ user: z.ZodString;
569
+ }, "strip", z.ZodTypeAny, {
570
+ user: string;
571
+ }, {
572
+ user: string;
573
+ }>, z.ZodObject<{
574
+ /** 도메인 엔티티 — `entityRef` **블록**이 이미 쓰는 종류/식별자 짝이 값 안으로 들어온 것. */
575
+ entity: z.ZodObject<{
576
+ type: z.ZodString;
577
+ id: z.ZodString;
578
+ }, "strip", z.ZodTypeAny, {
579
+ type: string;
580
+ id: string;
581
+ }, {
582
+ type: string;
583
+ id: string;
584
+ }>;
585
+ /** 클릭 시 이동할 https URL(선택). 출처는 클라가 검증한다. */
586
+ url: z.ZodOptional<z.ZodString>;
587
+ }, "strip", z.ZodTypeAny, {
588
+ entity: {
589
+ type: string;
590
+ id: string;
591
+ };
592
+ url?: string | undefined;
593
+ }, {
594
+ entity: {
595
+ type: string;
596
+ id: string;
597
+ };
598
+ url?: string | undefined;
599
+ }>]>>;
357
600
  }, "strip", z.ZodTypeAny, {
358
601
  value: string;
359
602
  label: string;
603
+ ref?: {
604
+ user: string;
605
+ } | {
606
+ entity: {
607
+ type: string;
608
+ id: string;
609
+ };
610
+ url?: string | undefined;
611
+ } | undefined;
360
612
  }, {
361
613
  value: string;
362
614
  label: string;
615
+ ref?: {
616
+ user: string;
617
+ } | {
618
+ entity: {
619
+ type: string;
620
+ id: string;
621
+ };
622
+ url?: string | undefined;
623
+ } | undefined;
363
624
  }>, "many">;
364
625
  value: z.ZodOptional<z.ZodString>;
365
626
  multi: z.ZodOptional<z.ZodBoolean>;
627
+ /** 고르지 않으면 제출을 잠근다 (0.7.0). 🔴 UX 다, 진실은 서버. */
628
+ required: z.ZodOptional<z.ZodBoolean>;
629
+ /**
630
+ * `multi: true` 전용 — **고른 개수**의 하한/상한 (0.7.0). 단일 선택에선 무시한다.
631
+ * (`input` 의 `min`/`max` 는 값의 크기라 문자열인데, 여기는 개수라 정수다.)
632
+ * 🔴 UX 다, 진실은 서버.
633
+ */
634
+ min: z.ZodOptional<z.ZodNumber>;
635
+ max: z.ZodOptional<z.ZodNumber>;
636
+ /** 제약 위반 시 보여 줄 작성자 소유 문장 (0.7.0). 없으면 렌더러 크롬 문구. */
637
+ error: z.ZodOptional<z.ZodString>;
366
638
  }, "strip", z.ZodTypeAny, {
367
639
  options: {
368
640
  value: string;
369
641
  label: string;
642
+ ref?: {
643
+ user: string;
644
+ } | {
645
+ entity: {
646
+ type: string;
647
+ id: string;
648
+ };
649
+ url?: string | undefined;
650
+ } | undefined;
370
651
  }[];
371
652
  type: "select";
372
653
  name: string;
373
654
  value?: string | undefined;
374
655
  label?: string | undefined;
375
656
  placeholder?: string | undefined;
657
+ required?: boolean | undefined;
658
+ min?: number | undefined;
659
+ max?: number | undefined;
660
+ error?: string | undefined;
376
661
  multi?: boolean | undefined;
377
662
  }, {
378
663
  options: {
379
664
  value: string;
380
665
  label: string;
666
+ ref?: {
667
+ user: string;
668
+ } | {
669
+ entity: {
670
+ type: string;
671
+ id: string;
672
+ };
673
+ url?: string | undefined;
674
+ } | undefined;
381
675
  }[];
382
676
  type: "select";
383
677
  name: string;
384
678
  value?: string | undefined;
385
679
  label?: string | undefined;
386
680
  placeholder?: string | undefined;
681
+ required?: boolean | undefined;
682
+ min?: number | undefined;
683
+ max?: number | undefined;
684
+ error?: string | undefined;
387
685
  multi?: boolean | undefined;
388
686
  }>;
389
687
  export declare const CheckboxBlockSchema: z.ZodObject<{
@@ -402,6 +700,51 @@ export declare const CheckboxBlockSchema: z.ZodObject<{
402
700
  name: string;
403
701
  checked?: boolean | undefined;
404
702
  }>;
703
+ /**
704
+ * 위치 입력 — "지금 내 위치" 한 번을 **사용자 제스처로** 받아 폼 값으로 수집한다.
705
+ *
706
+ * 왜 입력 블록인가: 위치는 앱이 가져가는 게 아니라 **사람이 주는 것**이다. 그래서 다른 입력과 같은
707
+ * 자리에 서고(name 으로 수집 → 제출 버튼의 values 에 실림), 카드/모달 어느 쪽에도 놓을 수 있다.
708
+ * 버튼을 누르는 순간 OS 권한창이 뜨므로 "위치 권한 수락"과 "현재 위치 가져오기"가 한 동작이다 —
709
+ * 웹에는 애초에 "권한만 요청" 하는 API 가 없고, 네이티브도 쓰지 않을 권한을 미리 묻는 앱은 심사에서
710
+ * 이유를 설명해야 한다. 그래서 **쓸 때 묻는다**.
711
+ *
712
+ * 값의 모양은 `LocationValue`(geo.ts) — 좌표는 문자열 geo URI 다(canonical JSON 소수 금지).
713
+ * 수집 전에는 `""`. 못 쓰는 클라(구 셸·위치 없는 브라우저)에서는 렌더러가 **버튼을 비활성 + 이유**로
714
+ * degrade 한다 → 누른 뒤에 실패를 알게 되지 않는다.
715
+ */
716
+ export declare const LocationBlockSchema: z.ZodObject<{
717
+ type: z.ZodLiteral<"location">;
718
+ name: z.ZodString;
719
+ label: z.ZodOptional<z.ZodString>;
720
+ /**
721
+ * 왜 필요한지 한 줄 — **OS 권한창보다 먼저** 보인다. 시스템 문구(Info.plist·Android 권한창)는
722
+ * 앱 전체에 하나뿐이라 이 카드가 왜 묻는지는 여기서만 말할 수 있다(그리고 그게 심사가 보는 것이다).
723
+ */
724
+ purpose: z.ZodOptional<z.ZodString>;
725
+ required: z.ZodOptional<z.ZodBoolean>;
726
+ /** GPS 급 정확도로 받을지(느리고 배터리를 더 쓴다). 기본 false = 네트워크/대략 위치. */
727
+ precise: z.ZodOptional<z.ZodBoolean>;
728
+ /** 버튼 문구(작성자 소유 문장). 미지정이면 렌더러 크롬 문구를 쓴다. */
729
+ buttonText: z.ZodOptional<z.ZodString>;
730
+ }, "strip", z.ZodTypeAny, {
731
+ type: "location";
732
+ name: string;
733
+ label?: string | undefined;
734
+ required?: boolean | undefined;
735
+ purpose?: string | undefined;
736
+ precise?: boolean | undefined;
737
+ buttonText?: string | undefined;
738
+ }, {
739
+ type: "location";
740
+ name: string;
741
+ label?: string | undefined;
742
+ required?: boolean | undefined;
743
+ purpose?: string | undefined;
744
+ precise?: boolean | undefined;
745
+ buttonText?: string | undefined;
746
+ }>;
747
+ export type LocationBlock = z.infer<typeof LocationBlockSchema>;
405
748
  export declare const ButtonBlockSchema: z.ZodObject<{
406
749
  type: z.ZodLiteral<"button">;
407
750
  /** 어떤 액션인지 식별. 클릭 시 org.corp.ui.action.action_id 로 회신됨. */
@@ -427,6 +770,39 @@ export declare const ButtonBlockSchema: z.ZodObject<{
427
770
  cancel?: string | undefined;
428
771
  }>>;
429
772
  disabled: z.ZodOptional<z.ZodBoolean>;
773
+ /**
774
+ * 이 MXID 들에게는 버튼을 **감춘다**(뷰어별 어포던스).
775
+ *
776
+ * 왜 필요한가: 카드 한 장은 방 전체가 같이 본다. 그런데 "이 사람만 절대 못 누르는 버튼"이 있다 —
777
+ * Forgejo 는 **자기 PR 자기 승인**을 422 로 거절한다(`approve your own pull is not allowed`).
778
+ * 그래서 작성자에게 Approve 를 보여 주면 눌러도 실패 카드만 쌓인다. 카드 전체에서 버튼을 빼면
779
+ * 남들이 승인을 못 하므로, 판정은 **보는 사람별**이어야 한다.
780
+ *
781
+ * 🔴 **권한이 아니다.** 진짜 게이트는 언제나 서버다(disabled/confirm 과 같은 자세) — 이건 없는
782
+ * 어포던스를 안 보여 주기 위한 것뿐이다. 그래서 이 키를 모르는 옛 클라이언트가 버튼을 그대로
783
+ * 보여 줘도 안전하다(누르면 서버가 사람이 읽을 이유와 함께 거절한다).
784
+ */
785
+ hidden_for: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
786
+ /**
787
+ * `hidden_for` 의 **짝**(0.7.0) — 이 MXID 들에게만 버튼을 보인다(화이트리스트).
788
+ *
789
+ * 왜 둘 다 있나: 두 축은 아는 것이 다르다. `hidden_for` 는 "이 사람은 절대 못 누른다"를 아는 경우고
790
+ * (자기 PR 자기 승인), `visible_for` 는 "이 사람만 누를 수 있다"를 아는 경우다(현재 수신자). 후자를
791
+ * `hidden_for` 로 쓰려면 방 멤버 전원을 열거해야 하고, 그 목록은 카드를 만든 **순간**에 굳는다 —
792
+ * 나중에 들어온 사람에게 버튼이 그냥 보인다.
793
+ *
794
+ * 🔴 **둘 다 있으면 `hidden_for` 가 이긴다.** "못 누른다"가 "누를 수 있다"보다 강한 진술이라서다
795
+ * (겹치는 경우는 보통 작성자의 실수이고, 그때 안전한 쪽은 감추는 쪽이다).
796
+ * 🔴 **권한이 아니다** — `hidden_for` 와 똑같이 UX 고, 진짜 게이트는 언제나 서버다.
797
+ * 이 키를 모르는 옛 클라는 strip 하고 **전원에게** 버튼을 보인다 → 누르면 서버가 거절한다.
798
+ */
799
+ visible_for: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
800
+ /**
801
+ * 버튼이 잠기거나 감춰진 **이유 한 줄**(0.7.0) — 사람이 읽을 문장(작성자 소유).
802
+ * `disabled` 면 버튼 옆 보조 텍스트로, `visible_for` 로 감춰졌으면 버튼 자리에 이 줄만 남는다.
803
+ * "눌러 봐야 안다"를 없애는 것이 요점이다. 🔴 UX 다, 진실은 서버.
804
+ */
805
+ disabled_reason: z.ZodOptional<z.ZodString>;
430
806
  }, "strip", z.ZodTypeAny, {
431
807
  type: "button";
432
808
  text: string;
@@ -440,6 +816,9 @@ export declare const ButtonBlockSchema: z.ZodObject<{
440
816
  cancel?: string | undefined;
441
817
  } | undefined;
442
818
  disabled?: boolean | undefined;
819
+ hidden_for?: string[] | undefined;
820
+ visible_for?: string[] | undefined;
821
+ disabled_reason?: string | undefined;
443
822
  }, {
444
823
  type: "button";
445
824
  text: string;
@@ -453,6 +832,9 @@ export declare const ButtonBlockSchema: z.ZodObject<{
453
832
  cancel?: string | undefined;
454
833
  } | undefined;
455
834
  disabled?: boolean | undefined;
835
+ hidden_for?: string[] | undefined;
836
+ visible_for?: string[] | undefined;
837
+ disabled_reason?: string | undefined;
456
838
  }>;
457
839
  export type ButtonBlock = z.infer<typeof ButtonBlockSchema>;
458
840
  /**
@@ -469,14 +851,14 @@ export declare const LinkButtonBlockSchema: z.ZodObject<{
469
851
  external: z.ZodOptional<z.ZodBoolean>;
470
852
  }, "strip", z.ZodTypeAny, {
471
853
  type: "linkButton";
472
- text: string;
473
854
  url: string;
855
+ text: string;
474
856
  style?: "danger" | "default" | "primary" | undefined;
475
857
  external?: boolean | undefined;
476
858
  }, {
477
859
  type: "linkButton";
478
- text: string;
479
860
  url: string;
861
+ text: string;
480
862
  style?: "danger" | "default" | "primary" | undefined;
481
863
  external?: boolean | undefined;
482
864
  }>;
@@ -509,6 +891,39 @@ export declare const ActionsBlockSchema: z.ZodObject<{
509
891
  cancel?: string | undefined;
510
892
  }>>;
511
893
  disabled: z.ZodOptional<z.ZodBoolean>;
894
+ /**
895
+ * 이 MXID 들에게는 버튼을 **감춘다**(뷰어별 어포던스).
896
+ *
897
+ * 왜 필요한가: 카드 한 장은 방 전체가 같이 본다. 그런데 "이 사람만 절대 못 누르는 버튼"이 있다 —
898
+ * Forgejo 는 **자기 PR 자기 승인**을 422 로 거절한다(`approve your own pull is not allowed`).
899
+ * 그래서 작성자에게 Approve 를 보여 주면 눌러도 실패 카드만 쌓인다. 카드 전체에서 버튼을 빼면
900
+ * 남들이 승인을 못 하므로, 판정은 **보는 사람별**이어야 한다.
901
+ *
902
+ * 🔴 **권한이 아니다.** 진짜 게이트는 언제나 서버다(disabled/confirm 과 같은 자세) — 이건 없는
903
+ * 어포던스를 안 보여 주기 위한 것뿐이다. 그래서 이 키를 모르는 옛 클라이언트가 버튼을 그대로
904
+ * 보여 줘도 안전하다(누르면 서버가 사람이 읽을 이유와 함께 거절한다).
905
+ */
906
+ hidden_for: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
907
+ /**
908
+ * `hidden_for` 의 **짝**(0.7.0) — 이 MXID 들에게만 버튼을 보인다(화이트리스트).
909
+ *
910
+ * 왜 둘 다 있나: 두 축은 아는 것이 다르다. `hidden_for` 는 "이 사람은 절대 못 누른다"를 아는 경우고
911
+ * (자기 PR 자기 승인), `visible_for` 는 "이 사람만 누를 수 있다"를 아는 경우다(현재 수신자). 후자를
912
+ * `hidden_for` 로 쓰려면 방 멤버 전원을 열거해야 하고, 그 목록은 카드를 만든 **순간**에 굳는다 —
913
+ * 나중에 들어온 사람에게 버튼이 그냥 보인다.
914
+ *
915
+ * 🔴 **둘 다 있으면 `hidden_for` 가 이긴다.** "못 누른다"가 "누를 수 있다"보다 강한 진술이라서다
916
+ * (겹치는 경우는 보통 작성자의 실수이고, 그때 안전한 쪽은 감추는 쪽이다).
917
+ * 🔴 **권한이 아니다** — `hidden_for` 와 똑같이 UX 고, 진짜 게이트는 언제나 서버다.
918
+ * 이 키를 모르는 옛 클라는 strip 하고 **전원에게** 버튼을 보인다 → 누르면 서버가 거절한다.
919
+ */
920
+ visible_for: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
921
+ /**
922
+ * 버튼이 잠기거나 감춰진 **이유 한 줄**(0.7.0) — 사람이 읽을 문장(작성자 소유).
923
+ * `disabled` 면 버튼 옆 보조 텍스트로, `visible_for` 로 감춰졌으면 버튼 자리에 이 줄만 남는다.
924
+ * "눌러 봐야 안다"를 없애는 것이 요점이다. 🔴 UX 다, 진실은 서버.
925
+ */
926
+ disabled_reason: z.ZodOptional<z.ZodString>;
512
927
  }, "strip", z.ZodTypeAny, {
513
928
  type: "button";
514
929
  text: string;
@@ -522,6 +937,9 @@ export declare const ActionsBlockSchema: z.ZodObject<{
522
937
  cancel?: string | undefined;
523
938
  } | undefined;
524
939
  disabled?: boolean | undefined;
940
+ hidden_for?: string[] | undefined;
941
+ visible_for?: string[] | undefined;
942
+ disabled_reason?: string | undefined;
525
943
  }, {
526
944
  type: "button";
527
945
  text: string;
@@ -535,6 +953,9 @@ export declare const ActionsBlockSchema: z.ZodObject<{
535
953
  cancel?: string | undefined;
536
954
  } | undefined;
537
955
  disabled?: boolean | undefined;
956
+ hidden_for?: string[] | undefined;
957
+ visible_for?: string[] | undefined;
958
+ disabled_reason?: string | undefined;
538
959
  }>, z.ZodObject<{
539
960
  type: z.ZodLiteral<"linkButton">;
540
961
  text: z.ZodString;
@@ -545,14 +966,14 @@ export declare const ActionsBlockSchema: z.ZodObject<{
545
966
  external: z.ZodOptional<z.ZodBoolean>;
546
967
  }, "strip", z.ZodTypeAny, {
547
968
  type: "linkButton";
548
- text: string;
549
969
  url: string;
970
+ text: string;
550
971
  style?: "danger" | "default" | "primary" | undefined;
551
972
  external?: boolean | undefined;
552
973
  }, {
553
974
  type: "linkButton";
554
- text: string;
555
975
  url: string;
976
+ text: string;
556
977
  style?: "danger" | "default" | "primary" | undefined;
557
978
  external?: boolean | undefined;
558
979
  }>]>, "many">;
@@ -571,10 +992,13 @@ export declare const ActionsBlockSchema: z.ZodObject<{
571
992
  cancel?: string | undefined;
572
993
  } | undefined;
573
994
  disabled?: boolean | undefined;
995
+ hidden_for?: string[] | undefined;
996
+ visible_for?: string[] | undefined;
997
+ disabled_reason?: string | undefined;
574
998
  } | {
575
999
  type: "linkButton";
576
- text: string;
577
1000
  url: string;
1001
+ text: string;
578
1002
  style?: "danger" | "default" | "primary" | undefined;
579
1003
  external?: boolean | undefined;
580
1004
  })[];
@@ -593,10 +1017,13 @@ export declare const ActionsBlockSchema: z.ZodObject<{
593
1017
  cancel?: string | undefined;
594
1018
  } | undefined;
595
1019
  disabled?: boolean | undefined;
1020
+ hidden_for?: string[] | undefined;
1021
+ visible_for?: string[] | undefined;
1022
+ disabled_reason?: string | undefined;
596
1023
  } | {
597
1024
  type: "linkButton";
598
- text: string;
599
1025
  url: string;
1026
+ text: string;
600
1027
  style?: "danger" | "default" | "primary" | undefined;
601
1028
  external?: boolean | undefined;
602
1029
  })[];
@@ -633,6 +1060,12 @@ export declare const OverflowBlockSchema: z.ZodObject<{
633
1060
  cancel?: string | undefined;
634
1061
  }>>;
635
1062
  disabled: z.ZodOptional<z.ZodBoolean>;
1063
+ /** 이 MXID 들에게만 항목을 보인다 (0.7.0) — `ButtonBlockSchema.visible_for` 와 같은 규칙. 🔴 UX 다, 진실은 서버. */
1064
+ visible_for: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1065
+ /** 이 MXID 들에게 항목을 감춘다 (0.7.0) — 둘 다 있으면 이쪽이 이긴다(버튼과 같은 규칙). */
1066
+ hidden_for: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1067
+ /** 잠기거나 감춰진 이유 한 줄 (0.7.0, 작성자 소유 문장). 🔴 UX 다, 진실은 서버. */
1068
+ disabled_reason: z.ZodOptional<z.ZodString>;
636
1069
  }, "strip", z.ZodTypeAny, {
637
1070
  text: string;
638
1071
  action_id: string;
@@ -645,6 +1078,9 @@ export declare const OverflowBlockSchema: z.ZodObject<{
645
1078
  cancel?: string | undefined;
646
1079
  } | undefined;
647
1080
  disabled?: boolean | undefined;
1081
+ hidden_for?: string[] | undefined;
1082
+ visible_for?: string[] | undefined;
1083
+ disabled_reason?: string | undefined;
648
1084
  }, {
649
1085
  text: string;
650
1086
  action_id: string;
@@ -657,6 +1093,9 @@ export declare const OverflowBlockSchema: z.ZodObject<{
657
1093
  cancel?: string | undefined;
658
1094
  } | undefined;
659
1095
  disabled?: boolean | undefined;
1096
+ hidden_for?: string[] | undefined;
1097
+ visible_for?: string[] | undefined;
1098
+ disabled_reason?: string | undefined;
660
1099
  }>, "many">;
661
1100
  }, "strip", z.ZodTypeAny, {
662
1101
  type: "overflow";
@@ -672,6 +1111,9 @@ export declare const OverflowBlockSchema: z.ZodObject<{
672
1111
  cancel?: string | undefined;
673
1112
  } | undefined;
674
1113
  disabled?: boolean | undefined;
1114
+ hidden_for?: string[] | undefined;
1115
+ visible_for?: string[] | undefined;
1116
+ disabled_reason?: string | undefined;
675
1117
  }[];
676
1118
  label?: string | undefined;
677
1119
  }, {
@@ -688,27 +1130,34 @@ export declare const OverflowBlockSchema: z.ZodObject<{
688
1130
  cancel?: string | undefined;
689
1131
  } | undefined;
690
1132
  disabled?: boolean | undefined;
1133
+ hidden_for?: string[] | undefined;
1134
+ visible_for?: string[] | undefined;
1135
+ disabled_reason?: string | undefined;
691
1136
  }[];
692
1137
  label?: string | undefined;
693
1138
  }>;
694
1139
  export type OverflowBlock = z.infer<typeof OverflowBlockSchema>;
695
- /** 진행률 바 (0~100). 에이전트가 m.replace 편집으로 갱신해 "스트리밍" 진행 표시 가능. */
1140
+ /**
1141
+ * 진행률 바 (0~100). 에이전트가 m.replace 편집으로 갱신해 "스트리밍" 진행 표시 가능.
1142
+ *
1143
+ * 🔴 **톤 축이 없다** — 배지·콜아웃·메트릭과 갈리는 자리다. 이 블록의 렌더러는 shadcn `Progress`
1144
+ * 이고 채움 색이 `bg-primary` 하나뿐이라(라이브러리에 그 축이 없다) 톤을 받아 봐야 그릴 곳이 없다.
1145
+ * 색을 넣고 싶으면 스키마가 아니라 **렌더러부터** 물을 것(`docs/cob-to-shadcn-map.md` 의 `progress` 행).
1146
+ * 진행 바 옆에서 성패를 말해야 하면 `label` 이나 형제 `badge`·`callout` 블록이 그 자리다.
1147
+ */
696
1148
  export declare const ProgressBlockSchema: z.ZodObject<{
697
1149
  type: z.ZodLiteral<"progress">;
698
1150
  /** 0~100 백분율(정수). 생략하면 indeterminate(불확정) 표시. 와이어 canonical JSON 은 소수 금지 → int 강제. */
699
1151
  value: z.ZodOptional<z.ZodNumber>;
700
1152
  label: z.ZodOptional<z.ZodString>;
701
- tone: z.ZodOptional<z.ZodEnum<["neutral", "success", "warning", "danger", "info"]>>;
702
1153
  }, "strip", z.ZodTypeAny, {
703
1154
  type: "progress";
704
1155
  value?: number | undefined;
705
1156
  label?: string | undefined;
706
- tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
707
1157
  }, {
708
1158
  type: "progress";
709
1159
  value?: number | undefined;
710
1160
  label?: string | undefined;
711
- tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
712
1161
  }>;
713
1162
  /** 멀티스텝 진행 상태 표시(타임라인). 폼 마법사와 별개로, 작업 단계 시각화에 쓴다. */
714
1163
  export declare const StepsBlockSchema: z.ZodObject<{
@@ -719,25 +1168,25 @@ export declare const StepsBlockSchema: z.ZodObject<{
719
1168
  note: z.ZodOptional<z.ZodString>;
720
1169
  }, "strip", z.ZodTypeAny, {
721
1170
  label: string;
722
- status?: "done" | "active" | "todo" | "error" | undefined;
1171
+ status?: "error" | "done" | "active" | "todo" | undefined;
723
1172
  note?: string | undefined;
724
1173
  }, {
725
1174
  label: string;
726
- status?: "done" | "active" | "todo" | "error" | undefined;
1175
+ status?: "error" | "done" | "active" | "todo" | undefined;
727
1176
  note?: string | undefined;
728
1177
  }>, "many">;
729
1178
  }, "strip", z.ZodTypeAny, {
730
1179
  type: "steps";
731
1180
  items: {
732
1181
  label: string;
733
- status?: "done" | "active" | "todo" | "error" | undefined;
1182
+ status?: "error" | "done" | "active" | "todo" | undefined;
734
1183
  note?: string | undefined;
735
1184
  }[];
736
1185
  }, {
737
1186
  type: "steps";
738
1187
  items: {
739
1188
  label: string;
740
- status?: "done" | "active" | "todo" | "error" | undefined;
1189
+ status?: "error" | "done" | "active" | "todo" | undefined;
741
1190
  note?: string | undefined;
742
1191
  }[];
743
1192
  }>;
@@ -901,29 +1350,90 @@ export declare const ChartBlockSchema: z.ZodObject<{
901
1350
  caption?: string | undefined;
902
1351
  }>;
903
1352
  export type ChartBlock = z.infer<typeof ChartBlockSchema>;
904
- /** 단일 아바타 — 얼굴 동그라미(이미지/이니셜) + 이름·보조텍스트 + 상태점. 담당자 표시. */
1353
+ /**
1354
+ * 단일 아바타 — 얼굴 동그라미(이미지/이니셜) + 이름·보조텍스트 + 상태점. 담당자 표시.
1355
+ *
1356
+ * 🔴 **`color` 는 뺐다**(0.6.0). 이니셜 면은 shadcn `AvatarFallback` 의 `bg-muted` 한 벌이고
1357
+ * 렌더러엔 그 색을 받을 자리가 없다 — 계약에 두면 작성자가 보내고 아무 일도 안 일어난다
1358
+ * (`progress.tone` 을 뺀 것과 같은 이유). 누구인지는 이니셜·이름·프로필 사진이 나른다.
1359
+ */
905
1360
  export declare const AvatarBlockSchema: z.ZodObject<{
906
1361
  type: z.ZodLiteral<"avatar">;
907
1362
  name: z.ZodString;
908
1363
  initials: z.ZodOptional<z.ZodString>;
909
- color: z.ZodOptional<z.ZodString>;
910
1364
  src: z.ZodOptional<z.ZodString>;
911
1365
  subtitle: z.ZodOptional<z.ZodString>;
1366
+ /**
1367
+ * 이 아바타가 가리키는 사람/엔티티 (0.8.0). 있으면 렌더러가 해석 결과(이름·사진)로 `name`/`src` 를
1368
+ * **덮어쓴다** — 방 상태가 정답이라 개명·프로필 변경이 즉시 반영된다.
1369
+ * 🔴 `name` 은 평문 사본으로 남긴다: 해석기가 없거나(외부 임베더) 옛 클라면 그 문자열이 유일한 답이다.
1370
+ */
1371
+ ref: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
1372
+ /** Matrix 사용자 id — `@local:server` 형태. 해석(이름·아바타)은 호스트가 주입한다(PeopleProvider). */
1373
+ user: z.ZodString;
1374
+ }, "strip", z.ZodTypeAny, {
1375
+ user: string;
1376
+ }, {
1377
+ user: string;
1378
+ }>, z.ZodObject<{
1379
+ /** 도메인 엔티티 — `entityRef` **블록**이 이미 쓰는 종류/식별자 짝이 값 안으로 들어온 것. */
1380
+ entity: z.ZodObject<{
1381
+ type: z.ZodString;
1382
+ id: z.ZodString;
1383
+ }, "strip", z.ZodTypeAny, {
1384
+ type: string;
1385
+ id: string;
1386
+ }, {
1387
+ type: string;
1388
+ id: string;
1389
+ }>;
1390
+ /** 클릭 시 이동할 https URL(선택). 출처는 클라가 검증한다. */
1391
+ url: z.ZodOptional<z.ZodString>;
1392
+ }, "strip", z.ZodTypeAny, {
1393
+ entity: {
1394
+ type: string;
1395
+ id: string;
1396
+ };
1397
+ url?: string | undefined;
1398
+ }, {
1399
+ entity: {
1400
+ type: string;
1401
+ id: string;
1402
+ };
1403
+ url?: string | undefined;
1404
+ }>]>>;
1405
+ /** 우하단 상태점 — 네 상태가 각자 색을 갖는다(`--cob-color-presence-*`). 색만으로 안 나르도록 `aria-label` 이 상태를 병기한다. */
912
1406
  status: z.ZodOptional<z.ZodEnum<["online", "away", "busy", "offline"]>>;
913
1407
  }, "strip", z.ZodTypeAny, {
914
1408
  type: "avatar";
915
1409
  name: string;
916
1410
  status?: "online" | "away" | "busy" | "offline" | undefined;
1411
+ ref?: {
1412
+ user: string;
1413
+ } | {
1414
+ entity: {
1415
+ type: string;
1416
+ id: string;
1417
+ };
1418
+ url?: string | undefined;
1419
+ } | undefined;
917
1420
  initials?: string | undefined;
918
- color?: string | undefined;
919
1421
  src?: string | undefined;
920
1422
  subtitle?: string | undefined;
921
1423
  }, {
922
1424
  type: "avatar";
923
1425
  name: string;
924
1426
  status?: "online" | "away" | "busy" | "offline" | undefined;
1427
+ ref?: {
1428
+ user: string;
1429
+ } | {
1430
+ entity: {
1431
+ type: string;
1432
+ id: string;
1433
+ };
1434
+ url?: string | undefined;
1435
+ } | undefined;
925
1436
  initials?: string | undefined;
926
- color?: string | undefined;
927
1437
  src?: string | undefined;
928
1438
  subtitle?: string | undefined;
929
1439
  }>;
@@ -935,19 +1445,15 @@ export declare const AvatarGroupBlockSchema: z.ZodObject<{
935
1445
  name: z.ZodString;
936
1446
  /** 이니셜(미지정 시 name 에서 자동 생성). */
937
1447
  initials: z.ZodOptional<z.ZodString>;
938
- /** 배경색(CSS 색/토큰). 미지정 시 name 해시로 팔레트에서 고름. */
939
- color: z.ZodOptional<z.ZodString>;
940
1448
  /** 이미지 URL(https). 있으면 이미지, 없으면 이니셜. */
941
1449
  src: z.ZodOptional<z.ZodString>;
942
1450
  }, "strip", z.ZodTypeAny, {
943
1451
  name: string;
944
1452
  initials?: string | undefined;
945
- color?: string | undefined;
946
1453
  src?: string | undefined;
947
1454
  }, {
948
1455
  name: string;
949
1456
  initials?: string | undefined;
950
- color?: string | undefined;
951
1457
  src?: string | undefined;
952
1458
  }>, "many">;
953
1459
  /** 앞에서 몇 명까지 보일지(기본 5). 나머지는 +N. */
@@ -958,7 +1464,6 @@ export declare const AvatarGroupBlockSchema: z.ZodObject<{
958
1464
  people: {
959
1465
  name: string;
960
1466
  initials?: string | undefined;
961
- color?: string | undefined;
962
1467
  src?: string | undefined;
963
1468
  }[];
964
1469
  label?: string | undefined;
@@ -968,7 +1473,6 @@ export declare const AvatarGroupBlockSchema: z.ZodObject<{
968
1473
  people: {
969
1474
  name: string;
970
1475
  initials?: string | undefined;
971
- color?: string | undefined;
972
1476
  src?: string | undefined;
973
1477
  }[];
974
1478
  label?: string | undefined;
@@ -1062,15 +1566,15 @@ export declare const EntityRefBlockSchema: z.ZodObject<{
1062
1566
  }, "strip", z.ZodTypeAny, {
1063
1567
  type: "entityRef";
1064
1568
  label: string;
1065
- tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1066
- url?: string | undefined;
1067
1569
  entity?: string | undefined;
1570
+ url?: string | undefined;
1571
+ tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1068
1572
  }, {
1069
1573
  type: "entityRef";
1070
1574
  label: string;
1071
- tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1072
- url?: string | undefined;
1073
1575
  entity?: string | undefined;
1576
+ url?: string | undefined;
1577
+ tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1074
1578
  }>;
1075
1579
  export type EntityRefBlock = z.infer<typeof EntityRefBlockSchema>;
1076
1580
  /**
@@ -1101,8 +1605,8 @@ export declare const KanbanBlockSchema: z.ZodObject<{
1101
1605
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1102
1606
  }>>;
1103
1607
  }, "strip", z.ZodTypeAny, {
1104
- title: string;
1105
1608
  id: string;
1609
+ title: string;
1106
1610
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1107
1611
  badge?: {
1108
1612
  label: string;
@@ -1110,8 +1614,8 @@ export declare const KanbanBlockSchema: z.ZodObject<{
1110
1614
  } | undefined;
1111
1615
  meta?: string[] | undefined;
1112
1616
  }, {
1113
- title: string;
1114
1617
  id: string;
1618
+ title: string;
1115
1619
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1116
1620
  badge?: {
1117
1621
  label: string;
@@ -1120,11 +1624,11 @@ export declare const KanbanBlockSchema: z.ZodObject<{
1120
1624
  meta?: string[] | undefined;
1121
1625
  }>, "many">;
1122
1626
  }, "strip", z.ZodTypeAny, {
1123
- title: string;
1124
1627
  id: string;
1628
+ title: string;
1125
1629
  cards: {
1126
- title: string;
1127
1630
  id: string;
1631
+ title: string;
1128
1632
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1129
1633
  badge?: {
1130
1634
  label: string;
@@ -1134,11 +1638,11 @@ export declare const KanbanBlockSchema: z.ZodObject<{
1134
1638
  }[];
1135
1639
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1136
1640
  }, {
1137
- title: string;
1138
1641
  id: string;
1642
+ title: string;
1139
1643
  cards: {
1140
- title: string;
1141
1644
  id: string;
1645
+ title: string;
1142
1646
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1143
1647
  badge?: {
1144
1648
  label: string;
@@ -1152,11 +1656,11 @@ export declare const KanbanBlockSchema: z.ZodObject<{
1152
1656
  }, "strip", z.ZodTypeAny, {
1153
1657
  type: "kanban";
1154
1658
  columns: {
1155
- title: string;
1156
1659
  id: string;
1660
+ title: string;
1157
1661
  cards: {
1158
- title: string;
1159
1662
  id: string;
1663
+ title: string;
1160
1664
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1161
1665
  badge?: {
1162
1666
  label: string;
@@ -1170,11 +1674,11 @@ export declare const KanbanBlockSchema: z.ZodObject<{
1170
1674
  }, {
1171
1675
  type: "kanban";
1172
1676
  columns: {
1173
- title: string;
1174
1677
  id: string;
1678
+ title: string;
1175
1679
  cards: {
1176
- title: string;
1177
1680
  id: string;
1681
+ title: string;
1178
1682
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1179
1683
  badge?: {
1180
1684
  label: string;
@@ -1226,6 +1730,18 @@ export declare const CollapsibleBlockSchema: z.ZodObject<{
1226
1730
  /** 처음부터 펼쳐둘지(기본 접힘). */
1227
1731
  open: z.ZodOptional<z.ZodBoolean>;
1228
1732
  tone: z.ZodOptional<z.ZodEnum<["neutral", "success", "warning", "danger", "info"]>>;
1733
+ /**
1734
+ * **옛 클라용 사본이라는 표식**(0.8.0). 빌더가 새 블록을 낼 때 같은 내용을 이 접기 블록으로 병기하고
1735
+ * 여기에 원본 블록 타입을 적는다.
1736
+ *
1737
+ * 왜 필요한가: 새 *블록 타입*은 `dropUnknownBlocks` 에서 **통째로 떨어진다**(키 추가와 달리 degrade
1738
+ * 경로가 없다). 그래서 `activity` 는 빌더가 사본을 같이 내고, **새 렌더러는 원본을 아니까 사본을
1739
+ * 안 그린다** — 안 그러면 새 클라에서 같은 이력이 두 번 보인다.
1740
+ * 이 키를 모르는 옛 클라는 strip 하고 평범한 접기 블록으로 그린다(그게 목적이다).
1741
+ *
1742
+ * 전환기가 끝나 클라 배포가 충분히 퍼지면 빌더의 `legacy` 기본값을 false 로 바꾼다(이 시리즈 밖).
1743
+ */
1744
+ legacy_for: z.ZodOptional<z.ZodEnum<["activity"]>>;
1229
1745
  /**
1230
1746
  * 펼치면 보이는 중첩 블록(재귀). 런타임은 z.lazy 로 BlockSchema 를 지연 참조해 재귀 검증하지만,
1231
1747
  * 정적 타입은 z.ZodTypeAny 로 끊는다 — Block 이 z.infer 기반이라 재귀 타입 별칭이 conditional type
@@ -1238,20 +1754,217 @@ export declare const CollapsibleBlockSchema: z.ZodObject<{
1238
1754
  blocks: any[];
1239
1755
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1240
1756
  open?: boolean | undefined;
1757
+ legacy_for?: "activity" | undefined;
1241
1758
  }, {
1242
1759
  type: "collapsible";
1243
1760
  title: string;
1244
1761
  blocks: any[];
1245
1762
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1246
1763
  open?: boolean | undefined;
1764
+ legacy_for?: "activity" | undefined;
1247
1765
  }>;
1248
1766
  export type CollapsibleBlock = {
1249
1767
  type: "collapsible";
1250
1768
  title: string;
1251
1769
  open?: boolean;
1252
1770
  tone?: Tone;
1771
+ legacy_for?: "activity";
1253
1772
  blocks: Block[];
1254
1773
  };
1774
+ /**
1775
+ * **처리 이력**(0.8.0) — 참조가 주어인 시간순 목록. 이 시리즈의 **유일한 새 블록**이다.
1776
+ *
1777
+ * 왜 블록인가(감사 문서 C): "누가 · 무엇을 · 언제"는 지금 `collapsible` 안의 마크다운 텍스트로 산다.
1778
+ * 그래서 접힌 상태에선 정보가 0이고, 펼쳐도 사람·시각에 구조가 없어 아바타도 상대 시각도 못 붙는다.
1779
+ * 기존 블록의 새 축으로는 표현할 수 없는 모양이라("주어가 참조인 행의 목록") 블록이 정당하다.
1780
+ *
1781
+ * 🔴 **새 블록은 `dropUnknownBlocks` 에서 통째로 떨어진다** — 키 추가와 달리 degrade 경로가 없다.
1782
+ * 그래서 빌더(`card.activity`)가 옛 클라용 `collapsible` 사본을 **같이** 낸다(`legacy_for: "activity"`).
1783
+ *
1784
+ * 항목은 **최신순**이다(맨 앞이 가장 최근). `maxVisible` 을 넘는 나머지는 렌더러가 접는다.
1785
+ */
1786
+ export declare const ActivityBlockSchema: z.ZodObject<{
1787
+ type: z.ZodLiteral<"activity">;
1788
+ label: z.ZodOptional<z.ZodString>;
1789
+ /** 펼쳐 둘 최근 항목 수(기본 3). 나머지는 "이전 N건 더 보기"로 접힌다. */
1790
+ maxVisible: z.ZodOptional<z.ZodNumber>;
1791
+ items: z.ZodArray<z.ZodObject<{
1792
+ /** 행위의 주어 — 참조면 아바타·이름으로, 문자열이면 그대로. */
1793
+ who: z.ZodUnion<[z.ZodString, z.ZodUnion<[z.ZodObject<{
1794
+ /** Matrix 사용자 id — `@local:server` 형태. 해석(이름·아바타)은 호스트가 주입한다(PeopleProvider). */
1795
+ user: z.ZodString;
1796
+ }, "strip", z.ZodTypeAny, {
1797
+ user: string;
1798
+ }, {
1799
+ user: string;
1800
+ }>, z.ZodObject<{
1801
+ /** 도메인 엔티티 — `entityRef` **블록**이 이미 쓰는 종류/식별자 짝이 값 안으로 들어온 것. */
1802
+ entity: z.ZodObject<{
1803
+ type: z.ZodString;
1804
+ id: z.ZodString;
1805
+ }, "strip", z.ZodTypeAny, {
1806
+ type: string;
1807
+ id: string;
1808
+ }, {
1809
+ type: string;
1810
+ id: string;
1811
+ }>;
1812
+ /** 클릭 시 이동할 https URL(선택). 출처는 클라가 검증한다. */
1813
+ url: z.ZodOptional<z.ZodString>;
1814
+ }, "strip", z.ZodTypeAny, {
1815
+ entity: {
1816
+ type: string;
1817
+ id: string;
1818
+ };
1819
+ url?: string | undefined;
1820
+ }, {
1821
+ entity: {
1822
+ type: string;
1823
+ id: string;
1824
+ };
1825
+ url?: string | undefined;
1826
+ }>]>]>;
1827
+ /** 무엇을 했나 — 인라인 마크다운 허용(`text` 블록의 인라인 규칙과 같다). */
1828
+ what: z.ZodString;
1829
+ /** 언제 — ISO 8601 타임스탬프 문자열. 렌더러가 상대 시각으로 그린다. */
1830
+ at: z.ZodString;
1831
+ tone: z.ZodOptional<z.ZodEnum<["neutral", "success", "warning", "danger", "info"]>>;
1832
+ /** 대상(선택) — "A 가 **B 에게** 전달" 의 B. */
1833
+ to: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodUnion<[z.ZodObject<{
1834
+ /** Matrix 사용자 id — `@local:server` 형태. 해석(이름·아바타)은 호스트가 주입한다(PeopleProvider). */
1835
+ user: z.ZodString;
1836
+ }, "strip", z.ZodTypeAny, {
1837
+ user: string;
1838
+ }, {
1839
+ user: string;
1840
+ }>, z.ZodObject<{
1841
+ /** 도메인 엔티티 — `entityRef` **블록**이 이미 쓰는 종류/식별자 짝이 값 안으로 들어온 것. */
1842
+ entity: z.ZodObject<{
1843
+ type: z.ZodString;
1844
+ id: z.ZodString;
1845
+ }, "strip", z.ZodTypeAny, {
1846
+ type: string;
1847
+ id: string;
1848
+ }, {
1849
+ type: string;
1850
+ id: string;
1851
+ }>;
1852
+ /** 클릭 시 이동할 https URL(선택). 출처는 클라가 검증한다. */
1853
+ url: z.ZodOptional<z.ZodString>;
1854
+ }, "strip", z.ZodTypeAny, {
1855
+ entity: {
1856
+ type: string;
1857
+ id: string;
1858
+ };
1859
+ url?: string | undefined;
1860
+ }, {
1861
+ entity: {
1862
+ type: string;
1863
+ id: string;
1864
+ };
1865
+ url?: string | undefined;
1866
+ }>]>]>>;
1867
+ }, "strip", z.ZodTypeAny, {
1868
+ at: string;
1869
+ who: string | {
1870
+ user: string;
1871
+ } | {
1872
+ entity: {
1873
+ type: string;
1874
+ id: string;
1875
+ };
1876
+ url?: string | undefined;
1877
+ };
1878
+ what: string;
1879
+ tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1880
+ to?: string | {
1881
+ user: string;
1882
+ } | {
1883
+ entity: {
1884
+ type: string;
1885
+ id: string;
1886
+ };
1887
+ url?: string | undefined;
1888
+ } | undefined;
1889
+ }, {
1890
+ at: string;
1891
+ who: string | {
1892
+ user: string;
1893
+ } | {
1894
+ entity: {
1895
+ type: string;
1896
+ id: string;
1897
+ };
1898
+ url?: string | undefined;
1899
+ };
1900
+ what: string;
1901
+ tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1902
+ to?: string | {
1903
+ user: string;
1904
+ } | {
1905
+ entity: {
1906
+ type: string;
1907
+ id: string;
1908
+ };
1909
+ url?: string | undefined;
1910
+ } | undefined;
1911
+ }>, "many">;
1912
+ }, "strip", z.ZodTypeAny, {
1913
+ type: "activity";
1914
+ items: {
1915
+ at: string;
1916
+ who: string | {
1917
+ user: string;
1918
+ } | {
1919
+ entity: {
1920
+ type: string;
1921
+ id: string;
1922
+ };
1923
+ url?: string | undefined;
1924
+ };
1925
+ what: string;
1926
+ tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1927
+ to?: string | {
1928
+ user: string;
1929
+ } | {
1930
+ entity: {
1931
+ type: string;
1932
+ id: string;
1933
+ };
1934
+ url?: string | undefined;
1935
+ } | undefined;
1936
+ }[];
1937
+ label?: string | undefined;
1938
+ maxVisible?: number | undefined;
1939
+ }, {
1940
+ type: "activity";
1941
+ items: {
1942
+ at: string;
1943
+ who: string | {
1944
+ user: string;
1945
+ } | {
1946
+ entity: {
1947
+ type: string;
1948
+ id: string;
1949
+ };
1950
+ url?: string | undefined;
1951
+ };
1952
+ what: string;
1953
+ tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1954
+ to?: string | {
1955
+ user: string;
1956
+ } | {
1957
+ entity: {
1958
+ type: string;
1959
+ id: string;
1960
+ };
1961
+ url?: string | undefined;
1962
+ } | undefined;
1963
+ }[];
1964
+ label?: string | undefined;
1965
+ maxVisible?: number | undefined;
1966
+ }>;
1967
+ export type ActivityBlock = z.infer<typeof ActivityBlockSchema>;
1255
1968
  /**
1256
1969
  * 탈출구(escape hatch): A2UI/UI Blocks로 표현하기 어려운 무거운 UI(차트·대형 그리드·지도)는
1257
1970
  * Matrix Widget으로. 클라이언트가 신뢰 경계 안에서 sandboxed iframe으로 렌더한다.
@@ -1286,7 +1999,16 @@ export declare const WidgetBlockSchema: z.ZodObject<{
1286
1999
  export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1287
2000
  type: z.ZodLiteral<"text">;
1288
2001
  text: z.ZodString;
1289
- /** true면 안전 화이트리스트 마크다운으로 렌더 (raw HTML 금지) */
2002
+ /**
2003
+ * true면 안전 화이트리스트 마크다운으로 렌더 (raw HTML 금지).
2004
+ *
2005
+ * 인라인: `**굵게**` `*기울임*` `` `코드` `` `[텍스트](http…)`.
2006
+ * 블록: 문단(빈 줄) · 목록(`-` `*` `+` / `1.`, 중첩 가능) · 제목(`#`~`###`) · 인용(`>`) ·
2007
+ * 구분선(`---`) · 펜스 코드(``` ```` ```).
2008
+ * 표는 지원하지 않는다 — 표는 `table` 블록이 따로 있다.
2009
+ *
2010
+ * 플래그를 안 주면 평문이다(줄바꿈만 살아난다). 긴 글에는 켜는 쪽이 읽힌다 — #581.
2011
+ */
1290
2012
  markdown: z.ZodOptional<z.ZodBoolean>;
1291
2013
  }, "strip", z.ZodTypeAny, {
1292
2014
  type: "text";
@@ -1339,6 +2061,44 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1339
2061
  text: string;
1340
2062
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1341
2063
  }>, "many">>;
2064
+ /**
2065
+ * 이 값이 가리키는 사람/엔티티 (0.8.0). 있으면 렌더러가 칩(아바타+이름 / 종류+라벨)으로 그린다.
2066
+ * 🔴 **`value` 는 평문 사본으로 남긴다** — `parts` 와 같은 규칙이다(RefSchema 머리말).
2067
+ */
2068
+ ref: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
2069
+ /** Matrix 사용자 id — `@local:server` 형태. 해석(이름·아바타)은 호스트가 주입한다(PeopleProvider). */
2070
+ user: z.ZodString;
2071
+ }, "strip", z.ZodTypeAny, {
2072
+ user: string;
2073
+ }, {
2074
+ user: string;
2075
+ }>, z.ZodObject<{
2076
+ /** 도메인 엔티티 — `entityRef` **블록**이 이미 쓰는 종류/식별자 짝이 값 안으로 들어온 것. */
2077
+ entity: z.ZodObject<{
2078
+ type: z.ZodString;
2079
+ id: z.ZodString;
2080
+ }, "strip", z.ZodTypeAny, {
2081
+ type: string;
2082
+ id: string;
2083
+ }, {
2084
+ type: string;
2085
+ id: string;
2086
+ }>;
2087
+ /** 클릭 시 이동할 https URL(선택). 출처는 클라가 검증한다. */
2088
+ url: z.ZodOptional<z.ZodString>;
2089
+ }, "strip", z.ZodTypeAny, {
2090
+ entity: {
2091
+ type: string;
2092
+ id: string;
2093
+ };
2094
+ url?: string | undefined;
2095
+ }, {
2096
+ entity: {
2097
+ type: string;
2098
+ id: string;
2099
+ };
2100
+ url?: string | undefined;
2101
+ }>]>>;
1342
2102
  }, "strip", z.ZodTypeAny, {
1343
2103
  value: string;
1344
2104
  label: string;
@@ -1347,6 +2107,15 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1347
2107
  text: string;
1348
2108
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1349
2109
  }[] | undefined;
2110
+ ref?: {
2111
+ user: string;
2112
+ } | {
2113
+ entity: {
2114
+ type: string;
2115
+ id: string;
2116
+ };
2117
+ url?: string | undefined;
2118
+ } | undefined;
1350
2119
  }, {
1351
2120
  value: string;
1352
2121
  label: string;
@@ -1355,6 +2124,15 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1355
2124
  text: string;
1356
2125
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1357
2126
  }[] | undefined;
2127
+ ref?: {
2128
+ user: string;
2129
+ } | {
2130
+ entity: {
2131
+ type: string;
2132
+ id: string;
2133
+ };
2134
+ url?: string | undefined;
2135
+ } | undefined;
1358
2136
  }>, "many">;
1359
2137
  }, "strip", z.ZodTypeAny, {
1360
2138
  type: "fields";
@@ -1366,6 +2144,15 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1366
2144
  text: string;
1367
2145
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1368
2146
  }[] | undefined;
2147
+ ref?: {
2148
+ user: string;
2149
+ } | {
2150
+ entity: {
2151
+ type: string;
2152
+ id: string;
2153
+ };
2154
+ url?: string | undefined;
2155
+ } | undefined;
1369
2156
  }[];
1370
2157
  }, {
1371
2158
  type: "fields";
@@ -1377,6 +2164,15 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1377
2164
  text: string;
1378
2165
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1379
2166
  }[] | undefined;
2167
+ ref?: {
2168
+ user: string;
2169
+ } | {
2170
+ entity: {
2171
+ type: string;
2172
+ id: string;
2173
+ };
2174
+ url?: string | undefined;
2175
+ } | undefined;
1380
2176
  }[];
1381
2177
  }>, z.ZodObject<{
1382
2178
  type: z.ZodLiteral<"image">;
@@ -1396,7 +2192,6 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1396
2192
  alt?: string | undefined;
1397
2193
  }>, z.ZodObject<{
1398
2194
  type: z.ZodLiteral<"context">;
1399
- /** 작은 보조 텍스트/아이콘 줄 */
1400
2195
  elements: z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodObject<{
1401
2196
  icon: z.ZodString;
1402
2197
  }, "strip", z.ZodTypeAny, {
@@ -1453,17 +2248,14 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1453
2248
  /** 0~100 백분율(정수). 생략하면 indeterminate(불확정) 표시. 와이어 canonical JSON 은 소수 금지 → int 강제. */
1454
2249
  value: z.ZodOptional<z.ZodNumber>;
1455
2250
  label: z.ZodOptional<z.ZodString>;
1456
- tone: z.ZodOptional<z.ZodEnum<["neutral", "success", "warning", "danger", "info"]>>;
1457
2251
  }, "strip", z.ZodTypeAny, {
1458
2252
  type: "progress";
1459
2253
  value?: number | undefined;
1460
2254
  label?: string | undefined;
1461
- tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1462
2255
  }, {
1463
2256
  type: "progress";
1464
2257
  value?: number | undefined;
1465
2258
  label?: string | undefined;
1466
- tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1467
2259
  }>, z.ZodObject<{
1468
2260
  type: z.ZodLiteral<"steps">;
1469
2261
  items: z.ZodArray<z.ZodObject<{
@@ -1472,25 +2264,25 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1472
2264
  note: z.ZodOptional<z.ZodString>;
1473
2265
  }, "strip", z.ZodTypeAny, {
1474
2266
  label: string;
1475
- status?: "done" | "active" | "todo" | "error" | undefined;
2267
+ status?: "error" | "done" | "active" | "todo" | undefined;
1476
2268
  note?: string | undefined;
1477
2269
  }, {
1478
2270
  label: string;
1479
- status?: "done" | "active" | "todo" | "error" | undefined;
2271
+ status?: "error" | "done" | "active" | "todo" | undefined;
1480
2272
  note?: string | undefined;
1481
2273
  }>, "many">;
1482
2274
  }, "strip", z.ZodTypeAny, {
1483
2275
  type: "steps";
1484
2276
  items: {
1485
2277
  label: string;
1486
- status?: "done" | "active" | "todo" | "error" | undefined;
2278
+ status?: "error" | "done" | "active" | "todo" | undefined;
1487
2279
  note?: string | undefined;
1488
2280
  }[];
1489
2281
  }, {
1490
2282
  type: "steps";
1491
2283
  items: {
1492
2284
  label: string;
1493
- status?: "done" | "active" | "todo" | "error" | undefined;
2285
+ status?: "error" | "done" | "active" | "todo" | undefined;
1494
2286
  note?: string | undefined;
1495
2287
  }[];
1496
2288
  }>, z.ZodObject<{
@@ -1565,24 +2357,79 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1565
2357
  type: z.ZodLiteral<"avatar">;
1566
2358
  name: z.ZodString;
1567
2359
  initials: z.ZodOptional<z.ZodString>;
1568
- color: z.ZodOptional<z.ZodString>;
1569
2360
  src: z.ZodOptional<z.ZodString>;
1570
2361
  subtitle: z.ZodOptional<z.ZodString>;
2362
+ /**
2363
+ * 이 아바타가 가리키는 사람/엔티티 (0.8.0). 있으면 렌더러가 해석 결과(이름·사진)로 `name`/`src` 를
2364
+ * **덮어쓴다** — 방 상태가 정답이라 개명·프로필 변경이 즉시 반영된다.
2365
+ * 🔴 `name` 은 평문 사본으로 남긴다: 해석기가 없거나(외부 임베더) 옛 클라면 그 문자열이 유일한 답이다.
2366
+ */
2367
+ ref: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
2368
+ /** Matrix 사용자 id — `@local:server` 형태. 해석(이름·아바타)은 호스트가 주입한다(PeopleProvider). */
2369
+ user: z.ZodString;
2370
+ }, "strip", z.ZodTypeAny, {
2371
+ user: string;
2372
+ }, {
2373
+ user: string;
2374
+ }>, z.ZodObject<{
2375
+ /** 도메인 엔티티 — `entityRef` **블록**이 이미 쓰는 종류/식별자 짝이 값 안으로 들어온 것. */
2376
+ entity: z.ZodObject<{
2377
+ type: z.ZodString;
2378
+ id: z.ZodString;
2379
+ }, "strip", z.ZodTypeAny, {
2380
+ type: string;
2381
+ id: string;
2382
+ }, {
2383
+ type: string;
2384
+ id: string;
2385
+ }>;
2386
+ /** 클릭 시 이동할 https URL(선택). 출처는 클라가 검증한다. */
2387
+ url: z.ZodOptional<z.ZodString>;
2388
+ }, "strip", z.ZodTypeAny, {
2389
+ entity: {
2390
+ type: string;
2391
+ id: string;
2392
+ };
2393
+ url?: string | undefined;
2394
+ }, {
2395
+ entity: {
2396
+ type: string;
2397
+ id: string;
2398
+ };
2399
+ url?: string | undefined;
2400
+ }>]>>;
2401
+ /** 우하단 상태점 — 네 상태가 각자 색을 갖는다(`--cob-color-presence-*`). 색만으로 안 나르도록 `aria-label` 이 상태를 병기한다. */
1571
2402
  status: z.ZodOptional<z.ZodEnum<["online", "away", "busy", "offline"]>>;
1572
2403
  }, "strip", z.ZodTypeAny, {
1573
2404
  type: "avatar";
1574
2405
  name: string;
1575
2406
  status?: "online" | "away" | "busy" | "offline" | undefined;
2407
+ ref?: {
2408
+ user: string;
2409
+ } | {
2410
+ entity: {
2411
+ type: string;
2412
+ id: string;
2413
+ };
2414
+ url?: string | undefined;
2415
+ } | undefined;
1576
2416
  initials?: string | undefined;
1577
- color?: string | undefined;
1578
2417
  src?: string | undefined;
1579
2418
  subtitle?: string | undefined;
1580
2419
  }, {
1581
2420
  type: "avatar";
1582
2421
  name: string;
1583
2422
  status?: "online" | "away" | "busy" | "offline" | undefined;
2423
+ ref?: {
2424
+ user: string;
2425
+ } | {
2426
+ entity: {
2427
+ type: string;
2428
+ id: string;
2429
+ };
2430
+ url?: string | undefined;
2431
+ } | undefined;
1584
2432
  initials?: string | undefined;
1585
- color?: string | undefined;
1586
2433
  src?: string | undefined;
1587
2434
  subtitle?: string | undefined;
1588
2435
  }>, z.ZodObject<{
@@ -1591,19 +2438,15 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1591
2438
  name: z.ZodString;
1592
2439
  /** 이니셜(미지정 시 name 에서 자동 생성). */
1593
2440
  initials: z.ZodOptional<z.ZodString>;
1594
- /** 배경색(CSS 색/토큰). 미지정 시 name 해시로 팔레트에서 고름. */
1595
- color: z.ZodOptional<z.ZodString>;
1596
2441
  /** 이미지 URL(https). 있으면 이미지, 없으면 이니셜. */
1597
2442
  src: z.ZodOptional<z.ZodString>;
1598
2443
  }, "strip", z.ZodTypeAny, {
1599
2444
  name: string;
1600
2445
  initials?: string | undefined;
1601
- color?: string | undefined;
1602
2446
  src?: string | undefined;
1603
2447
  }, {
1604
2448
  name: string;
1605
2449
  initials?: string | undefined;
1606
- color?: string | undefined;
1607
2450
  src?: string | undefined;
1608
2451
  }>, "many">;
1609
2452
  /** 앞에서 몇 명까지 보일지(기본 5). 나머지는 +N. */
@@ -1614,7 +2457,6 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1614
2457
  people: {
1615
2458
  name: string;
1616
2459
  initials?: string | undefined;
1617
- color?: string | undefined;
1618
2460
  src?: string | undefined;
1619
2461
  }[];
1620
2462
  label?: string | undefined;
@@ -1624,7 +2466,6 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1624
2466
  people: {
1625
2467
  name: string;
1626
2468
  initials?: string | undefined;
1627
- color?: string | undefined;
1628
2469
  src?: string | undefined;
1629
2470
  }[];
1630
2471
  label?: string | undefined;
@@ -1706,15 +2547,15 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1706
2547
  }, "strip", z.ZodTypeAny, {
1707
2548
  type: "entityRef";
1708
2549
  label: string;
1709
- tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1710
- url?: string | undefined;
1711
2550
  entity?: string | undefined;
2551
+ url?: string | undefined;
2552
+ tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1712
2553
  }, {
1713
2554
  type: "entityRef";
1714
2555
  label: string;
1715
- tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1716
- url?: string | undefined;
1717
2556
  entity?: string | undefined;
2557
+ url?: string | undefined;
2558
+ tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1718
2559
  }>, z.ZodObject<{
1719
2560
  type: z.ZodLiteral<"kanban">;
1720
2561
  columns: z.ZodArray<z.ZodObject<{
@@ -1738,8 +2579,8 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1738
2579
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1739
2580
  }>>;
1740
2581
  }, "strip", z.ZodTypeAny, {
1741
- title: string;
1742
2582
  id: string;
2583
+ title: string;
1743
2584
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1744
2585
  badge?: {
1745
2586
  label: string;
@@ -1747,8 +2588,8 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1747
2588
  } | undefined;
1748
2589
  meta?: string[] | undefined;
1749
2590
  }, {
1750
- title: string;
1751
2591
  id: string;
2592
+ title: string;
1752
2593
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1753
2594
  badge?: {
1754
2595
  label: string;
@@ -1757,11 +2598,11 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1757
2598
  meta?: string[] | undefined;
1758
2599
  }>, "many">;
1759
2600
  }, "strip", z.ZodTypeAny, {
1760
- title: string;
1761
2601
  id: string;
2602
+ title: string;
1762
2603
  cards: {
1763
- title: string;
1764
2604
  id: string;
2605
+ title: string;
1765
2606
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1766
2607
  badge?: {
1767
2608
  label: string;
@@ -1771,11 +2612,11 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1771
2612
  }[];
1772
2613
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1773
2614
  }, {
1774
- title: string;
1775
2615
  id: string;
2616
+ title: string;
1776
2617
  cards: {
1777
- title: string;
1778
2618
  id: string;
2619
+ title: string;
1779
2620
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1780
2621
  badge?: {
1781
2622
  label: string;
@@ -1789,11 +2630,11 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1789
2630
  }, "strip", z.ZodTypeAny, {
1790
2631
  type: "kanban";
1791
2632
  columns: {
1792
- title: string;
1793
2633
  id: string;
2634
+ title: string;
1794
2635
  cards: {
1795
- title: string;
1796
2636
  id: string;
2637
+ title: string;
1797
2638
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1798
2639
  badge?: {
1799
2640
  label: string;
@@ -1807,11 +2648,11 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1807
2648
  }, {
1808
2649
  type: "kanban";
1809
2650
  columns: {
1810
- title: string;
1811
2651
  id: string;
2652
+ title: string;
1812
2653
  cards: {
1813
- title: string;
1814
2654
  id: string;
2655
+ title: string;
1815
2656
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1816
2657
  badge?: {
1817
2658
  label: string;
@@ -1842,6 +2683,186 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1842
2683
  label?: string | undefined;
1843
2684
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1844
2685
  expiredText?: string | undefined;
2686
+ }>, z.ZodObject<{
2687
+ type: z.ZodLiteral<"activity">;
2688
+ label: z.ZodOptional<z.ZodString>;
2689
+ /** 펼쳐 둘 최근 항목 수(기본 3). 나머지는 "이전 N건 더 보기"로 접힌다. */
2690
+ maxVisible: z.ZodOptional<z.ZodNumber>;
2691
+ items: z.ZodArray<z.ZodObject<{
2692
+ /** 행위의 주어 — 참조면 아바타·이름으로, 문자열이면 그대로. */
2693
+ who: z.ZodUnion<[z.ZodString, z.ZodUnion<[z.ZodObject<{
2694
+ /** Matrix 사용자 id — `@local:server` 형태. 해석(이름·아바타)은 호스트가 주입한다(PeopleProvider). */
2695
+ user: z.ZodString;
2696
+ }, "strip", z.ZodTypeAny, {
2697
+ user: string;
2698
+ }, {
2699
+ user: string;
2700
+ }>, z.ZodObject<{
2701
+ /** 도메인 엔티티 — `entityRef` **블록**이 이미 쓰는 종류/식별자 짝이 값 안으로 들어온 것. */
2702
+ entity: z.ZodObject<{
2703
+ type: z.ZodString;
2704
+ id: z.ZodString;
2705
+ }, "strip", z.ZodTypeAny, {
2706
+ type: string;
2707
+ id: string;
2708
+ }, {
2709
+ type: string;
2710
+ id: string;
2711
+ }>;
2712
+ /** 클릭 시 이동할 https URL(선택). 출처는 클라가 검증한다. */
2713
+ url: z.ZodOptional<z.ZodString>;
2714
+ }, "strip", z.ZodTypeAny, {
2715
+ entity: {
2716
+ type: string;
2717
+ id: string;
2718
+ };
2719
+ url?: string | undefined;
2720
+ }, {
2721
+ entity: {
2722
+ type: string;
2723
+ id: string;
2724
+ };
2725
+ url?: string | undefined;
2726
+ }>]>]>;
2727
+ /** 무엇을 했나 — 인라인 마크다운 허용(`text` 블록의 인라인 규칙과 같다). */
2728
+ what: z.ZodString;
2729
+ /** 언제 — ISO 8601 타임스탬프 문자열. 렌더러가 상대 시각으로 그린다. */
2730
+ at: z.ZodString;
2731
+ tone: z.ZodOptional<z.ZodEnum<["neutral", "success", "warning", "danger", "info"]>>;
2732
+ /** 대상(선택) — "A 가 **B 에게** 전달" 의 B. */
2733
+ to: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodUnion<[z.ZodObject<{
2734
+ /** Matrix 사용자 id — `@local:server` 형태. 해석(이름·아바타)은 호스트가 주입한다(PeopleProvider). */
2735
+ user: z.ZodString;
2736
+ }, "strip", z.ZodTypeAny, {
2737
+ user: string;
2738
+ }, {
2739
+ user: string;
2740
+ }>, z.ZodObject<{
2741
+ /** 도메인 엔티티 — `entityRef` **블록**이 이미 쓰는 종류/식별자 짝이 값 안으로 들어온 것. */
2742
+ entity: z.ZodObject<{
2743
+ type: z.ZodString;
2744
+ id: z.ZodString;
2745
+ }, "strip", z.ZodTypeAny, {
2746
+ type: string;
2747
+ id: string;
2748
+ }, {
2749
+ type: string;
2750
+ id: string;
2751
+ }>;
2752
+ /** 클릭 시 이동할 https URL(선택). 출처는 클라가 검증한다. */
2753
+ url: z.ZodOptional<z.ZodString>;
2754
+ }, "strip", z.ZodTypeAny, {
2755
+ entity: {
2756
+ type: string;
2757
+ id: string;
2758
+ };
2759
+ url?: string | undefined;
2760
+ }, {
2761
+ entity: {
2762
+ type: string;
2763
+ id: string;
2764
+ };
2765
+ url?: string | undefined;
2766
+ }>]>]>>;
2767
+ }, "strip", z.ZodTypeAny, {
2768
+ at: string;
2769
+ who: string | {
2770
+ user: string;
2771
+ } | {
2772
+ entity: {
2773
+ type: string;
2774
+ id: string;
2775
+ };
2776
+ url?: string | undefined;
2777
+ };
2778
+ what: string;
2779
+ tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
2780
+ to?: string | {
2781
+ user: string;
2782
+ } | {
2783
+ entity: {
2784
+ type: string;
2785
+ id: string;
2786
+ };
2787
+ url?: string | undefined;
2788
+ } | undefined;
2789
+ }, {
2790
+ at: string;
2791
+ who: string | {
2792
+ user: string;
2793
+ } | {
2794
+ entity: {
2795
+ type: string;
2796
+ id: string;
2797
+ };
2798
+ url?: string | undefined;
2799
+ };
2800
+ what: string;
2801
+ tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
2802
+ to?: string | {
2803
+ user: string;
2804
+ } | {
2805
+ entity: {
2806
+ type: string;
2807
+ id: string;
2808
+ };
2809
+ url?: string | undefined;
2810
+ } | undefined;
2811
+ }>, "many">;
2812
+ }, "strip", z.ZodTypeAny, {
2813
+ type: "activity";
2814
+ items: {
2815
+ at: string;
2816
+ who: string | {
2817
+ user: string;
2818
+ } | {
2819
+ entity: {
2820
+ type: string;
2821
+ id: string;
2822
+ };
2823
+ url?: string | undefined;
2824
+ };
2825
+ what: string;
2826
+ tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
2827
+ to?: string | {
2828
+ user: string;
2829
+ } | {
2830
+ entity: {
2831
+ type: string;
2832
+ id: string;
2833
+ };
2834
+ url?: string | undefined;
2835
+ } | undefined;
2836
+ }[];
2837
+ label?: string | undefined;
2838
+ maxVisible?: number | undefined;
2839
+ }, {
2840
+ type: "activity";
2841
+ items: {
2842
+ at: string;
2843
+ who: string | {
2844
+ user: string;
2845
+ } | {
2846
+ entity: {
2847
+ type: string;
2848
+ id: string;
2849
+ };
2850
+ url?: string | undefined;
2851
+ };
2852
+ what: string;
2853
+ tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
2854
+ to?: string | {
2855
+ user: string;
2856
+ } | {
2857
+ entity: {
2858
+ type: string;
2859
+ id: string;
2860
+ };
2861
+ url?: string | undefined;
2862
+ } | undefined;
2863
+ }[];
2864
+ label?: string | undefined;
2865
+ maxVisible?: number | undefined;
1845
2866
  }>, z.ZodObject<{
1846
2867
  type: z.ZodLiteral<"code">;
1847
2868
  code: z.ZodString;
@@ -1912,6 +2933,18 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1912
2933
  /** 처음부터 펼쳐둘지(기본 접힘). */
1913
2934
  open: z.ZodOptional<z.ZodBoolean>;
1914
2935
  tone: z.ZodOptional<z.ZodEnum<["neutral", "success", "warning", "danger", "info"]>>;
2936
+ /**
2937
+ * **옛 클라용 사본이라는 표식**(0.8.0). 빌더가 새 블록을 낼 때 같은 내용을 이 접기 블록으로 병기하고
2938
+ * 여기에 원본 블록 타입을 적는다.
2939
+ *
2940
+ * 왜 필요한가: 새 *블록 타입*은 `dropUnknownBlocks` 에서 **통째로 떨어진다**(키 추가와 달리 degrade
2941
+ * 경로가 없다). 그래서 `activity` 는 빌더가 사본을 같이 내고, **새 렌더러는 원본을 아니까 사본을
2942
+ * 안 그린다** — 안 그러면 새 클라에서 같은 이력이 두 번 보인다.
2943
+ * 이 키를 모르는 옛 클라는 strip 하고 평범한 접기 블록으로 그린다(그게 목적이다).
2944
+ *
2945
+ * 전환기가 끝나 클라 배포가 충분히 퍼지면 빌더의 `legacy` 기본값을 false 로 바꾼다(이 시리즈 밖).
2946
+ */
2947
+ legacy_for: z.ZodOptional<z.ZodEnum<["activity"]>>;
1915
2948
  /**
1916
2949
  * 펼치면 보이는 중첩 블록(재귀). 런타임은 z.lazy 로 BlockSchema 를 지연 참조해 재귀 검증하지만,
1917
2950
  * 정적 타입은 z.ZodTypeAny 로 끊는다 — Block 이 z.infer 기반이라 재귀 타입 별칭이 conditional type
@@ -1924,12 +2957,14 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1924
2957
  blocks: any[];
1925
2958
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1926
2959
  open?: boolean | undefined;
2960
+ legacy_for?: "activity" | undefined;
1927
2961
  }, {
1928
2962
  type: "collapsible";
1929
2963
  title: string;
1930
2964
  blocks: any[];
1931
2965
  tone?: "neutral" | "success" | "warning" | "danger" | "info" | undefined;
1932
2966
  open?: boolean | undefined;
2967
+ legacy_for?: "activity" | undefined;
1933
2968
  }>, z.ZodObject<{
1934
2969
  type: z.ZodLiteral<"widget">;
1935
2970
  url: z.ZodString;
@@ -1976,26 +3011,68 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
1976
3011
  * 단일 업로드로 동작한다(기능 축소일 뿐 파손 없음).
1977
3012
  */
1978
3013
  multiple: z.ZodOptional<z.ZodBoolean>;
3014
+ /**
3015
+ * 하한/상한 (0.7.0) — number/date/datetime/time 공용. **문자열**이다: 날짜·시각은 그 타입의 값
3016
+ * 형식(`2026-09-22`·`18:15`)이고, number 면 숫자를 적은 문자열이다(와이어 canonical JSON 은
3017
+ * 소수를 허용하지 않아 숫자 축을 열 수 없다 — `slider` 가 int 만 받는 것과 같은 제약).
3018
+ *
3019
+ * `"today"` 리터럴을 허용한다 — "기한은 오늘 이후"는 카드를 **보낸 날**이 아니라 **보는 날** 기준이라야
3020
+ * 맞다(카드는 타임라인에 남고 며칠 뒤에도 눌린다). 렌더러가 그릴 때 해석한다.
3021
+ *
3022
+ * 🔴 **UX 다, 진실은 서버**(`hidden_for` 와 같은 자세). 클라가 미리 잠그는 건 헛걸음을 줄이려는
3023
+ * 것뿐이고, 진짜 판정은 언제나 핸들러·게이트가 한다. 이 키를 모르는 옛 클라는 strip 하고 지금처럼
3024
+ * 아무 제약 없이 제출한다 — 그러면 서버가 사람이 읽을 이유와 함께 거절한다(`action.result`).
3025
+ */
3026
+ min: z.ZodOptional<z.ZodString>;
3027
+ max: z.ZodOptional<z.ZodString>;
3028
+ /** 글자 수 하한/상한 (0.7.0) — 텍스트 계열 전용. 🔴 UX 다, 진실은 서버. */
3029
+ minLength: z.ZodOptional<z.ZodNumber>;
3030
+ maxLength: z.ZodOptional<z.ZodNumber>;
3031
+ /**
3032
+ * 값이 맞아야 하는 정규식 **소스**(0.7.0, 예: `"^[A-Z]{2}-\\d{4}$"`). 플래그·구분자 없이 패턴만 적는다.
3033
+ *
3034
+ * 🔴 렌더러는 `new RegExp` 를 **try/catch 로 감싼다** — 작성자가 자바스크립트가 아닌 방언(파이썬
3035
+ * `(?P<x>…)` 등)을 보내면 던지는데, 그걸로 카드 전체가 죽으면 안 된다. 못 읽는 패턴은 무시한다
3036
+ * (= 제약 없음). 진짜 판정은 여전히 서버다.
3037
+ */
3038
+ pattern: z.ZodOptional<z.ZodString>;
3039
+ /**
3040
+ * 제약 위반 시 보여 줄 **작성자 소유 문장**(0.7.0). 없으면 렌더러 크롬 문구를 쓴다
3041
+ * (`LabelContext` — "누구의 문자열인가"가 경계선이고, 도메인 사정을 아는 문장은 작성자 것이다).
3042
+ */
3043
+ error: z.ZodOptional<z.ZodString>;
1979
3044
  }, "strip", z.ZodTypeAny, {
1980
3045
  type: "input";
1981
3046
  name: string;
1982
3047
  value?: string | undefined;
1983
3048
  label?: string | undefined;
1984
- input?: "number" | "text" | "date" | "url" | "textarea" | "datetime" | "time" | "email" | "file" | undefined;
3049
+ input?: "number" | "date" | "url" | "text" | "textarea" | "datetime" | "time" | "email" | "file" | undefined;
1985
3050
  placeholder?: string | undefined;
1986
3051
  required?: boolean | undefined;
1987
3052
  accept?: string | undefined;
1988
3053
  multiple?: boolean | undefined;
3054
+ min?: string | undefined;
3055
+ max?: string | undefined;
3056
+ minLength?: number | undefined;
3057
+ maxLength?: number | undefined;
3058
+ pattern?: string | undefined;
3059
+ error?: string | undefined;
1989
3060
  }, {
1990
3061
  type: "input";
1991
3062
  name: string;
1992
3063
  value?: string | undefined;
1993
3064
  label?: string | undefined;
1994
- input?: "number" | "text" | "date" | "url" | "textarea" | "datetime" | "time" | "email" | "file" | undefined;
3065
+ input?: "number" | "date" | "url" | "text" | "textarea" | "datetime" | "time" | "email" | "file" | undefined;
1995
3066
  placeholder?: string | undefined;
1996
3067
  required?: boolean | undefined;
1997
3068
  accept?: string | undefined;
1998
3069
  multiple?: boolean | undefined;
3070
+ min?: string | undefined;
3071
+ max?: string | undefined;
3072
+ minLength?: number | undefined;
3073
+ maxLength?: number | undefined;
3074
+ pattern?: string | undefined;
3075
+ error?: string | undefined;
1999
3076
  }>, z.ZodObject<{
2000
3077
  type: z.ZodLiteral<"toggle">;
2001
3078
  name: z.ZodString;
@@ -2056,70 +3133,179 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2056
3133
  options: z.ZodArray<z.ZodObject<{
2057
3134
  value: z.ZodString;
2058
3135
  label: z.ZodString;
3136
+ hint: z.ZodOptional<z.ZodString>;
2059
3137
  }, "strip", z.ZodTypeAny, {
2060
3138
  value: string;
2061
3139
  label: string;
3140
+ hint?: string | undefined;
2062
3141
  }, {
2063
3142
  value: string;
2064
3143
  label: string;
3144
+ hint?: string | undefined;
2065
3145
  }>, "many">;
2066
3146
  value: z.ZodOptional<z.ZodString>;
3147
+ style: z.ZodOptional<z.ZodEnum<["cards", "segmented"]>>;
3148
+ /** 고르지 않으면 제출을 잠근다 (0.7.0). 🔴 UX 다, 진실은 서버 — `input.required` 와 같은 자세. */
3149
+ required: z.ZodOptional<z.ZodBoolean>;
3150
+ /** 미선택 시 보여 줄 작성자 소유 문장 (0.7.0). 없으면 렌더러 크롬 문구. */
3151
+ error: z.ZodOptional<z.ZodString>;
2067
3152
  }, "strip", z.ZodTypeAny, {
2068
3153
  options: {
2069
3154
  value: string;
2070
3155
  label: string;
3156
+ hint?: string | undefined;
2071
3157
  }[];
2072
3158
  type: "radio";
2073
3159
  name: string;
2074
3160
  value?: string | undefined;
2075
3161
  label?: string | undefined;
3162
+ required?: boolean | undefined;
3163
+ error?: string | undefined;
3164
+ style?: "cards" | "segmented" | undefined;
2076
3165
  }, {
2077
3166
  options: {
2078
3167
  value: string;
2079
3168
  label: string;
3169
+ hint?: string | undefined;
2080
3170
  }[];
2081
3171
  type: "radio";
2082
3172
  name: string;
2083
3173
  value?: string | undefined;
2084
3174
  label?: string | undefined;
3175
+ required?: boolean | undefined;
3176
+ error?: string | undefined;
3177
+ style?: "cards" | "segmented" | undefined;
2085
3178
  }>, z.ZodObject<{
2086
3179
  type: z.ZodLiteral<"select">;
2087
3180
  name: z.ZodString;
2088
3181
  label: z.ZodOptional<z.ZodString>;
2089
3182
  placeholder: z.ZodOptional<z.ZodString>;
3183
+ /**
3184
+ * 후보 목록. `ref`(0.8.0)를 주면 렌더러가 행을 칩(아바타·이름·MXID)으로 그린다 —
3185
+ * 🔴 `label` 은 평문 사본으로 남긴다(RefSchema 머리말). 그리는 쪽은 P5(선택 모델)가 맡는다.
3186
+ */
2090
3187
  options: z.ZodArray<z.ZodObject<{
2091
3188
  value: z.ZodString;
2092
3189
  label: z.ZodString;
3190
+ ref: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
3191
+ /** Matrix 사용자 id — `@local:server` 형태. 해석(이름·아바타)은 호스트가 주입한다(PeopleProvider). */
3192
+ user: z.ZodString;
3193
+ }, "strip", z.ZodTypeAny, {
3194
+ user: string;
3195
+ }, {
3196
+ user: string;
3197
+ }>, z.ZodObject<{
3198
+ /** 도메인 엔티티 — `entityRef` **블록**이 이미 쓰는 종류/식별자 짝이 값 안으로 들어온 것. */
3199
+ entity: z.ZodObject<{
3200
+ type: z.ZodString;
3201
+ id: z.ZodString;
3202
+ }, "strip", z.ZodTypeAny, {
3203
+ type: string;
3204
+ id: string;
3205
+ }, {
3206
+ type: string;
3207
+ id: string;
3208
+ }>;
3209
+ /** 클릭 시 이동할 https URL(선택). 출처는 클라가 검증한다. */
3210
+ url: z.ZodOptional<z.ZodString>;
3211
+ }, "strip", z.ZodTypeAny, {
3212
+ entity: {
3213
+ type: string;
3214
+ id: string;
3215
+ };
3216
+ url?: string | undefined;
3217
+ }, {
3218
+ entity: {
3219
+ type: string;
3220
+ id: string;
3221
+ };
3222
+ url?: string | undefined;
3223
+ }>]>>;
2093
3224
  }, "strip", z.ZodTypeAny, {
2094
3225
  value: string;
2095
3226
  label: string;
3227
+ ref?: {
3228
+ user: string;
3229
+ } | {
3230
+ entity: {
3231
+ type: string;
3232
+ id: string;
3233
+ };
3234
+ url?: string | undefined;
3235
+ } | undefined;
2096
3236
  }, {
2097
3237
  value: string;
2098
3238
  label: string;
3239
+ ref?: {
3240
+ user: string;
3241
+ } | {
3242
+ entity: {
3243
+ type: string;
3244
+ id: string;
3245
+ };
3246
+ url?: string | undefined;
3247
+ } | undefined;
2099
3248
  }>, "many">;
2100
3249
  value: z.ZodOptional<z.ZodString>;
2101
3250
  multi: z.ZodOptional<z.ZodBoolean>;
3251
+ /** 고르지 않으면 제출을 잠근다 (0.7.0). 🔴 UX 다, 진실은 서버. */
3252
+ required: z.ZodOptional<z.ZodBoolean>;
3253
+ /**
3254
+ * `multi: true` 전용 — **고른 개수**의 하한/상한 (0.7.0). 단일 선택에선 무시한다.
3255
+ * (`input` 의 `min`/`max` 는 값의 크기라 문자열인데, 여기는 개수라 정수다.)
3256
+ * 🔴 UX 다, 진실은 서버.
3257
+ */
3258
+ min: z.ZodOptional<z.ZodNumber>;
3259
+ max: z.ZodOptional<z.ZodNumber>;
3260
+ /** 제약 위반 시 보여 줄 작성자 소유 문장 (0.7.0). 없으면 렌더러 크롬 문구. */
3261
+ error: z.ZodOptional<z.ZodString>;
2102
3262
  }, "strip", z.ZodTypeAny, {
2103
3263
  options: {
2104
3264
  value: string;
2105
3265
  label: string;
3266
+ ref?: {
3267
+ user: string;
3268
+ } | {
3269
+ entity: {
3270
+ type: string;
3271
+ id: string;
3272
+ };
3273
+ url?: string | undefined;
3274
+ } | undefined;
2106
3275
  }[];
2107
3276
  type: "select";
2108
3277
  name: string;
2109
3278
  value?: string | undefined;
2110
3279
  label?: string | undefined;
2111
3280
  placeholder?: string | undefined;
3281
+ required?: boolean | undefined;
3282
+ min?: number | undefined;
3283
+ max?: number | undefined;
3284
+ error?: string | undefined;
2112
3285
  multi?: boolean | undefined;
2113
3286
  }, {
2114
3287
  options: {
2115
3288
  value: string;
2116
3289
  label: string;
3290
+ ref?: {
3291
+ user: string;
3292
+ } | {
3293
+ entity: {
3294
+ type: string;
3295
+ id: string;
3296
+ };
3297
+ url?: string | undefined;
3298
+ } | undefined;
2117
3299
  }[];
2118
3300
  type: "select";
2119
3301
  name: string;
2120
3302
  value?: string | undefined;
2121
3303
  label?: string | undefined;
2122
3304
  placeholder?: string | undefined;
3305
+ required?: boolean | undefined;
3306
+ min?: number | undefined;
3307
+ max?: number | undefined;
3308
+ error?: string | undefined;
2123
3309
  multi?: boolean | undefined;
2124
3310
  }>, z.ZodObject<{
2125
3311
  type: z.ZodLiteral<"checkbox">;
@@ -2136,6 +3322,36 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2136
3322
  label: string;
2137
3323
  name: string;
2138
3324
  checked?: boolean | undefined;
3325
+ }>, z.ZodObject<{
3326
+ type: z.ZodLiteral<"location">;
3327
+ name: z.ZodString;
3328
+ label: z.ZodOptional<z.ZodString>;
3329
+ /**
3330
+ * 왜 필요한지 한 줄 — **OS 권한창보다 먼저** 보인다. 시스템 문구(Info.plist·Android 권한창)는
3331
+ * 앱 전체에 하나뿐이라 이 카드가 왜 묻는지는 여기서만 말할 수 있다(그리고 그게 심사가 보는 것이다).
3332
+ */
3333
+ purpose: z.ZodOptional<z.ZodString>;
3334
+ required: z.ZodOptional<z.ZodBoolean>;
3335
+ /** GPS 급 정확도로 받을지(느리고 배터리를 더 쓴다). 기본 false = 네트워크/대략 위치. */
3336
+ precise: z.ZodOptional<z.ZodBoolean>;
3337
+ /** 버튼 문구(작성자 소유 문장). 미지정이면 렌더러 크롬 문구를 쓴다. */
3338
+ buttonText: z.ZodOptional<z.ZodString>;
3339
+ }, "strip", z.ZodTypeAny, {
3340
+ type: "location";
3341
+ name: string;
3342
+ label?: string | undefined;
3343
+ required?: boolean | undefined;
3344
+ purpose?: string | undefined;
3345
+ precise?: boolean | undefined;
3346
+ buttonText?: string | undefined;
3347
+ }, {
3348
+ type: "location";
3349
+ name: string;
3350
+ label?: string | undefined;
3351
+ required?: boolean | undefined;
3352
+ purpose?: string | undefined;
3353
+ precise?: boolean | undefined;
3354
+ buttonText?: string | undefined;
2139
3355
  }>, z.ZodObject<{
2140
3356
  type: z.ZodLiteral<"button">;
2141
3357
  /** 어떤 액션인지 식별. 클릭 시 org.corp.ui.action.action_id 로 회신됨. */
@@ -2161,6 +3377,39 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2161
3377
  cancel?: string | undefined;
2162
3378
  }>>;
2163
3379
  disabled: z.ZodOptional<z.ZodBoolean>;
3380
+ /**
3381
+ * 이 MXID 들에게는 버튼을 **감춘다**(뷰어별 어포던스).
3382
+ *
3383
+ * 왜 필요한가: 카드 한 장은 방 전체가 같이 본다. 그런데 "이 사람만 절대 못 누르는 버튼"이 있다 —
3384
+ * Forgejo 는 **자기 PR 자기 승인**을 422 로 거절한다(`approve your own pull is not allowed`).
3385
+ * 그래서 작성자에게 Approve 를 보여 주면 눌러도 실패 카드만 쌓인다. 카드 전체에서 버튼을 빼면
3386
+ * 남들이 승인을 못 하므로, 판정은 **보는 사람별**이어야 한다.
3387
+ *
3388
+ * 🔴 **권한이 아니다.** 진짜 게이트는 언제나 서버다(disabled/confirm 과 같은 자세) — 이건 없는
3389
+ * 어포던스를 안 보여 주기 위한 것뿐이다. 그래서 이 키를 모르는 옛 클라이언트가 버튼을 그대로
3390
+ * 보여 줘도 안전하다(누르면 서버가 사람이 읽을 이유와 함께 거절한다).
3391
+ */
3392
+ hidden_for: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
3393
+ /**
3394
+ * `hidden_for` 의 **짝**(0.7.0) — 이 MXID 들에게만 버튼을 보인다(화이트리스트).
3395
+ *
3396
+ * 왜 둘 다 있나: 두 축은 아는 것이 다르다. `hidden_for` 는 "이 사람은 절대 못 누른다"를 아는 경우고
3397
+ * (자기 PR 자기 승인), `visible_for` 는 "이 사람만 누를 수 있다"를 아는 경우다(현재 수신자). 후자를
3398
+ * `hidden_for` 로 쓰려면 방 멤버 전원을 열거해야 하고, 그 목록은 카드를 만든 **순간**에 굳는다 —
3399
+ * 나중에 들어온 사람에게 버튼이 그냥 보인다.
3400
+ *
3401
+ * 🔴 **둘 다 있으면 `hidden_for` 가 이긴다.** "못 누른다"가 "누를 수 있다"보다 강한 진술이라서다
3402
+ * (겹치는 경우는 보통 작성자의 실수이고, 그때 안전한 쪽은 감추는 쪽이다).
3403
+ * 🔴 **권한이 아니다** — `hidden_for` 와 똑같이 UX 고, 진짜 게이트는 언제나 서버다.
3404
+ * 이 키를 모르는 옛 클라는 strip 하고 **전원에게** 버튼을 보인다 → 누르면 서버가 거절한다.
3405
+ */
3406
+ visible_for: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
3407
+ /**
3408
+ * 버튼이 잠기거나 감춰진 **이유 한 줄**(0.7.0) — 사람이 읽을 문장(작성자 소유).
3409
+ * `disabled` 면 버튼 옆 보조 텍스트로, `visible_for` 로 감춰졌으면 버튼 자리에 이 줄만 남는다.
3410
+ * "눌러 봐야 안다"를 없애는 것이 요점이다. 🔴 UX 다, 진실은 서버.
3411
+ */
3412
+ disabled_reason: z.ZodOptional<z.ZodString>;
2164
3413
  }, "strip", z.ZodTypeAny, {
2165
3414
  type: "button";
2166
3415
  text: string;
@@ -2174,6 +3423,9 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2174
3423
  cancel?: string | undefined;
2175
3424
  } | undefined;
2176
3425
  disabled?: boolean | undefined;
3426
+ hidden_for?: string[] | undefined;
3427
+ visible_for?: string[] | undefined;
3428
+ disabled_reason?: string | undefined;
2177
3429
  }, {
2178
3430
  type: "button";
2179
3431
  text: string;
@@ -2187,6 +3439,9 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2187
3439
  cancel?: string | undefined;
2188
3440
  } | undefined;
2189
3441
  disabled?: boolean | undefined;
3442
+ hidden_for?: string[] | undefined;
3443
+ visible_for?: string[] | undefined;
3444
+ disabled_reason?: string | undefined;
2190
3445
  }>, z.ZodObject<{
2191
3446
  type: z.ZodLiteral<"linkButton">;
2192
3447
  text: z.ZodString;
@@ -2197,14 +3452,14 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2197
3452
  external: z.ZodOptional<z.ZodBoolean>;
2198
3453
  }, "strip", z.ZodTypeAny, {
2199
3454
  type: "linkButton";
2200
- text: string;
2201
3455
  url: string;
3456
+ text: string;
2202
3457
  style?: "danger" | "default" | "primary" | undefined;
2203
3458
  external?: boolean | undefined;
2204
3459
  }, {
2205
3460
  type: "linkButton";
2206
- text: string;
2207
3461
  url: string;
3462
+ text: string;
2208
3463
  style?: "danger" | "default" | "primary" | undefined;
2209
3464
  external?: boolean | undefined;
2210
3465
  }>, z.ZodObject<{
@@ -2234,6 +3489,39 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2234
3489
  cancel?: string | undefined;
2235
3490
  }>>;
2236
3491
  disabled: z.ZodOptional<z.ZodBoolean>;
3492
+ /**
3493
+ * 이 MXID 들에게는 버튼을 **감춘다**(뷰어별 어포던스).
3494
+ *
3495
+ * 왜 필요한가: 카드 한 장은 방 전체가 같이 본다. 그런데 "이 사람만 절대 못 누르는 버튼"이 있다 —
3496
+ * Forgejo 는 **자기 PR 자기 승인**을 422 로 거절한다(`approve your own pull is not allowed`).
3497
+ * 그래서 작성자에게 Approve 를 보여 주면 눌러도 실패 카드만 쌓인다. 카드 전체에서 버튼을 빼면
3498
+ * 남들이 승인을 못 하므로, 판정은 **보는 사람별**이어야 한다.
3499
+ *
3500
+ * 🔴 **권한이 아니다.** 진짜 게이트는 언제나 서버다(disabled/confirm 과 같은 자세) — 이건 없는
3501
+ * 어포던스를 안 보여 주기 위한 것뿐이다. 그래서 이 키를 모르는 옛 클라이언트가 버튼을 그대로
3502
+ * 보여 줘도 안전하다(누르면 서버가 사람이 읽을 이유와 함께 거절한다).
3503
+ */
3504
+ hidden_for: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
3505
+ /**
3506
+ * `hidden_for` 의 **짝**(0.7.0) — 이 MXID 들에게만 버튼을 보인다(화이트리스트).
3507
+ *
3508
+ * 왜 둘 다 있나: 두 축은 아는 것이 다르다. `hidden_for` 는 "이 사람은 절대 못 누른다"를 아는 경우고
3509
+ * (자기 PR 자기 승인), `visible_for` 는 "이 사람만 누를 수 있다"를 아는 경우다(현재 수신자). 후자를
3510
+ * `hidden_for` 로 쓰려면 방 멤버 전원을 열거해야 하고, 그 목록은 카드를 만든 **순간**에 굳는다 —
3511
+ * 나중에 들어온 사람에게 버튼이 그냥 보인다.
3512
+ *
3513
+ * 🔴 **둘 다 있으면 `hidden_for` 가 이긴다.** "못 누른다"가 "누를 수 있다"보다 강한 진술이라서다
3514
+ * (겹치는 경우는 보통 작성자의 실수이고, 그때 안전한 쪽은 감추는 쪽이다).
3515
+ * 🔴 **권한이 아니다** — `hidden_for` 와 똑같이 UX 고, 진짜 게이트는 언제나 서버다.
3516
+ * 이 키를 모르는 옛 클라는 strip 하고 **전원에게** 버튼을 보인다 → 누르면 서버가 거절한다.
3517
+ */
3518
+ visible_for: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
3519
+ /**
3520
+ * 버튼이 잠기거나 감춰진 **이유 한 줄**(0.7.0) — 사람이 읽을 문장(작성자 소유).
3521
+ * `disabled` 면 버튼 옆 보조 텍스트로, `visible_for` 로 감춰졌으면 버튼 자리에 이 줄만 남는다.
3522
+ * "눌러 봐야 안다"를 없애는 것이 요점이다. 🔴 UX 다, 진실은 서버.
3523
+ */
3524
+ disabled_reason: z.ZodOptional<z.ZodString>;
2237
3525
  }, "strip", z.ZodTypeAny, {
2238
3526
  type: "button";
2239
3527
  text: string;
@@ -2247,6 +3535,9 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2247
3535
  cancel?: string | undefined;
2248
3536
  } | undefined;
2249
3537
  disabled?: boolean | undefined;
3538
+ hidden_for?: string[] | undefined;
3539
+ visible_for?: string[] | undefined;
3540
+ disabled_reason?: string | undefined;
2250
3541
  }, {
2251
3542
  type: "button";
2252
3543
  text: string;
@@ -2260,6 +3551,9 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2260
3551
  cancel?: string | undefined;
2261
3552
  } | undefined;
2262
3553
  disabled?: boolean | undefined;
3554
+ hidden_for?: string[] | undefined;
3555
+ visible_for?: string[] | undefined;
3556
+ disabled_reason?: string | undefined;
2263
3557
  }>, z.ZodObject<{
2264
3558
  type: z.ZodLiteral<"linkButton">;
2265
3559
  text: z.ZodString;
@@ -2270,14 +3564,14 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2270
3564
  external: z.ZodOptional<z.ZodBoolean>;
2271
3565
  }, "strip", z.ZodTypeAny, {
2272
3566
  type: "linkButton";
2273
- text: string;
2274
3567
  url: string;
3568
+ text: string;
2275
3569
  style?: "danger" | "default" | "primary" | undefined;
2276
3570
  external?: boolean | undefined;
2277
3571
  }, {
2278
3572
  type: "linkButton";
2279
- text: string;
2280
3573
  url: string;
3574
+ text: string;
2281
3575
  style?: "danger" | "default" | "primary" | undefined;
2282
3576
  external?: boolean | undefined;
2283
3577
  }>]>, "many">;
@@ -2296,10 +3590,13 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2296
3590
  cancel?: string | undefined;
2297
3591
  } | undefined;
2298
3592
  disabled?: boolean | undefined;
3593
+ hidden_for?: string[] | undefined;
3594
+ visible_for?: string[] | undefined;
3595
+ disabled_reason?: string | undefined;
2299
3596
  } | {
2300
3597
  type: "linkButton";
2301
- text: string;
2302
3598
  url: string;
3599
+ text: string;
2303
3600
  style?: "danger" | "default" | "primary" | undefined;
2304
3601
  external?: boolean | undefined;
2305
3602
  })[];
@@ -2318,10 +3615,13 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2318
3615
  cancel?: string | undefined;
2319
3616
  } | undefined;
2320
3617
  disabled?: boolean | undefined;
3618
+ hidden_for?: string[] | undefined;
3619
+ visible_for?: string[] | undefined;
3620
+ disabled_reason?: string | undefined;
2321
3621
  } | {
2322
3622
  type: "linkButton";
2323
- text: string;
2324
3623
  url: string;
3624
+ text: string;
2325
3625
  style?: "danger" | "default" | "primary" | undefined;
2326
3626
  external?: boolean | undefined;
2327
3627
  })[];
@@ -2352,6 +3652,12 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2352
3652
  cancel?: string | undefined;
2353
3653
  }>>;
2354
3654
  disabled: z.ZodOptional<z.ZodBoolean>;
3655
+ /** 이 MXID 들에게만 항목을 보인다 (0.7.0) — `ButtonBlockSchema.visible_for` 와 같은 규칙. 🔴 UX 다, 진실은 서버. */
3656
+ visible_for: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
3657
+ /** 이 MXID 들에게 항목을 감춘다 (0.7.0) — 둘 다 있으면 이쪽이 이긴다(버튼과 같은 규칙). */
3658
+ hidden_for: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
3659
+ /** 잠기거나 감춰진 이유 한 줄 (0.7.0, 작성자 소유 문장). 🔴 UX 다, 진실은 서버. */
3660
+ disabled_reason: z.ZodOptional<z.ZodString>;
2355
3661
  }, "strip", z.ZodTypeAny, {
2356
3662
  text: string;
2357
3663
  action_id: string;
@@ -2364,6 +3670,9 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2364
3670
  cancel?: string | undefined;
2365
3671
  } | undefined;
2366
3672
  disabled?: boolean | undefined;
3673
+ hidden_for?: string[] | undefined;
3674
+ visible_for?: string[] | undefined;
3675
+ disabled_reason?: string | undefined;
2367
3676
  }, {
2368
3677
  text: string;
2369
3678
  action_id: string;
@@ -2376,6 +3685,9 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2376
3685
  cancel?: string | undefined;
2377
3686
  } | undefined;
2378
3687
  disabled?: boolean | undefined;
3688
+ hidden_for?: string[] | undefined;
3689
+ visible_for?: string[] | undefined;
3690
+ disabled_reason?: string | undefined;
2379
3691
  }>, "many">;
2380
3692
  }, "strip", z.ZodTypeAny, {
2381
3693
  type: "overflow";
@@ -2391,6 +3703,9 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2391
3703
  cancel?: string | undefined;
2392
3704
  } | undefined;
2393
3705
  disabled?: boolean | undefined;
3706
+ hidden_for?: string[] | undefined;
3707
+ visible_for?: string[] | undefined;
3708
+ disabled_reason?: string | undefined;
2394
3709
  }[];
2395
3710
  label?: string | undefined;
2396
3711
  }, {
@@ -2407,6 +3722,9 @@ export declare const BlockSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2407
3722
  cancel?: string | undefined;
2408
3723
  } | undefined;
2409
3724
  disabled?: boolean | undefined;
3725
+ hidden_for?: string[] | undefined;
3726
+ visible_for?: string[] | undefined;
3727
+ disabled_reason?: string | undefined;
2410
3728
  }[];
2411
3729
  label?: string | undefined;
2412
3730
  }>]>;