@underdogai/mesh-app-sdk 0.6.0 → 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/README.md CHANGED
@@ -53,6 +53,152 @@ await serve(app, { homeserver: "https://your-homeserver", accessToken: process.e
53
53
  | `ctx.invoke(actionId, values)` | 다른 앱의 기능을 이름으로 호출 |
54
54
  | `handlers: { [actionId]: handler }` | 내 기능이 불리면 실행 (내 것이 아니면 조용히 무시) |
55
55
 
56
+ ## 고르는 자리 — 후보가 카드 밖에 있을 때 (0.9.0)
57
+
58
+ "검색하기" 버튼 · 체크박스 18개 · "사람 더 보기 · 13명" 은 서로 다른 기능이 아니라 **후보가 카드 밖에 있을 때** 손으로 만든 우회 UI 다. `select` 에 공급원 축을 선언하면 셋이 한 컨트롤이 된다.
59
+
60
+ ```ts
61
+ // 방 멤버가 곧 후보 — 아바타·이름·MXID 행, 값은 MXID 배열
62
+ card.select("to", [], {
63
+ label: "받을 사람",
64
+ source: { kind: "room", exclude_self: true },
65
+ multi: true, min: 1, style: "chips",
66
+ });
67
+
68
+ // 서버에 묻는 후보 — 타이핑이 멎으면 클라가 action_type: "query" 로 묻는다
69
+ card.select("issue", recentIssues, { // 정적 사본 = 답이 오기 전과 옛 클라의 화면
70
+ label: "이슈",
71
+ source: { kind: "query", action_id: "issue.search", min_chars: 2 },
72
+ });
73
+ ```
74
+
75
+ 질의를 받는 핸들러는 **부작용 없이 후보만** 돌려준다:
76
+
77
+ ```ts
78
+ handlers: {
79
+ "issue.search": async (ctx) => {
80
+ if (ctx.action_type === "query") {
81
+ const hits = await api.searchIssues(String(ctx.values.q ?? ""));
82
+ ctx.result({ kind: "options", name: String(ctx.values.name), options: hits.map((i) => ({
83
+ value: i.key, label: i.title, hint: i.key,
84
+ })) });
85
+ return; // 🔴 여기서 아무것도 만들지 않는다
86
+ }
87
+ await api.assign(ctx.values.issue); // 같은 액션의 진짜 제출
88
+ },
89
+ },
90
+ ```
91
+
92
+ 🔴 **`options` 사본은 `source` 가 있어도 계약이다.** 이 키를 모르는 클라이언트는 `source` 를 벗기고 `options` 만 그린다 — 비워 보내면 그쪽 화면에는 고를 것이 없는 select 가 선다. 방 멤버처럼 서버가 채울 수 없는 후보라면 **카드 `fallback` 이 그 사실을 말해야 한다**(빌더가 경고를 남긴다).
93
+
94
+ ## mesh-bot 마이그레이션 — 우회 UI 4개를 걷어내기
95
+
96
+ 지금 봇들이 손으로 조립한 우회 UI 넷은 서로 다른 기능이 없어서가 아니라 **계약에 축이 없어서** 생겼다.
97
+ 축이 생겼으니 넷 다 지운다. 필요한 단계는 이렇게 갈린다:
98
+
99
+ | 필요한 것 | SDK |
100
+ |---|---|
101
+ | 제약 선언(`required`·`min`/`max`·`pattern`…) + `ctx.result` | `0.7.0` |
102
+ | 참조 값 `ref` + `card.activity` | `0.8.0` |
103
+ | `select` 의 `source`/`style`/`searchable` + `priority`·`long`·`summary` | `0.9.0` |
104
+
105
+ 🔴 **`0.9.0` 은 빌더 API 가 한 군데 바뀐다 — `card.actions(...)` 가 블록 하나가 아니라 `Block[]` 을 돌려준다.**
106
+ 액션 줄 안의 ⋯ 는 옛 클라가 **actions 블록을 통째로 떨구게** 만들어서, 같은 ⋯ 를 최상위 사본으로 병기해야
107
+ 하기 때문이다(`card.activity` 와 같은 규약). 호출부는 펼쳐 준다:
108
+
109
+ ```diff
110
+ - blocks: [card.fields(items), card.actions([...])]
111
+ + blocks: [card.fields(items), ...card.actions([...])]
112
+ ```
113
+
114
+ ### ① "처리하지 못했어요" 오류 카드 → `ctx.result`
115
+
116
+ ```jsonc
117
+ // before — 방 전원의 타임라인에 실패 카드가 쌓인다
118
+ { "card_id": "report-err-1", "title": "보고를 처리하지 못했어요",
119
+ "context": { "state": "submitted" },
120
+ "blocks": [{ "type": "text", "text": "기한을 선택해 주세요." }] }
121
+ ```
122
+
123
+ ```ts
124
+ // after — 누른 사람의 그 필드 아래로. 타임라인엔 아무것도 안 쌓인다
125
+ // ① 누르기 전에 보여 준다. ⚠️ `card.input` 헬퍼는 아직 제약 키를 안 받으므로 블록을 직접 적는다
126
+ // ("today" 는 카드를 **보는 날** 기준으로 렌더러가 푼다 — 카드는 며칠 뒤에도 눌린다)
127
+ const due: Block = { type: "input", name: "due", input: "date", label: "기한",
128
+ required: true, min: "today", error: "기한은 오늘 이후로 선택해 주세요" };
129
+
130
+ // ② 서버 판정은 새 카드가 아니라 그 컨트롤로
131
+ ctx.result({ kind: "reject", errors: { due: "오늘 이후여야 해요" } });
132
+ ctx.result({ kind: "denied", reason: "현재 수신자만 처리할 수 있어요" });
133
+ ctx.result({ kind: "ok", message: "확인 처리됨" });
134
+ ```
135
+
136
+ 권한 거절도 같은 채널이다. 버튼에 `visible_for: [수신자]` + `disabled_reason` 을 달면 **누르기 전에** 안다.
137
+
138
+ ### ② 입력창 + "검색하기" 버튼 → `select` 의 `source: { kind: "query" }`
139
+
140
+ ```jsonc
141
+ // before — 세 블록이 한 컨트롤을 흉내 낸다. 타이핑해도 안 줄고 버튼을 눌러야 온다
142
+ "blocks": [
143
+ { "type": "input", "name": "q", "label": "받을 사람 찾기", "placeholder": "이름이나 이메일" },
144
+ { "type": "actions", "elements": [{ "type": "button", "action_id": "search", "text": "검색하기" }] },
145
+ { "type": "checkbox", "name": "p1", "label": "KANG MINJI" }
146
+ ]
147
+ ```
148
+
149
+ ```jsonc
150
+ // after — 한 컨트롤. 타이핑이 곧 필터이고, 왕복은 source:query 일 때만 돈다
151
+ { "type": "select", "name": "issue", "label": "이슈",
152
+ "source": { "kind": "query", "action_id": "issue.search", "min_chars": 2 },
153
+ "options": [ { "value": "T-01", "label": "테스트-01" } ] } // 🔴 사본은 계약이다
154
+ ```
155
+
156
+ 핸들러는 `ctx.action_type === "query"` 일 때 **부작용 없이** `ctx.result({ kind: "options", … })` 로만 답한다
157
+ (위 "고르는 자리" 절의 예제).
158
+
159
+ ### ③ 체크박스 18개 + "사람 더 보기 · 13명" → `source: { kind: "room" }` + `multi` + `style: "chips"`
160
+
161
+ ```jsonc
162
+ // before — 값이 표시명 문자열이라 동명이인·개명에 깨지고, 나도 후보고, 얼굴이 없다
163
+ "blocks": [
164
+ { "type": "checkbox", "name": "to_1", "label": "KANG MINJI" },
165
+ { "type": "checkbox", "name": "to_2", "label": "goya@bluepinlabs.com" },
166
+ { "type": "collapsible", "title": "사람 더 보기 · 13명", "blocks": [ /* … */ ] }
167
+ ]
168
+ ```
169
+
170
+ ```ts
171
+ // after — 값은 MXID 배열. 아바타·이름·MXID 는 방 상태가 나르고, 넘치는 후보는 상자 안에서 스크롤한다
172
+ card.select("to", [], {
173
+ label: "받을 사람",
174
+ source: { kind: "room", exclude_self: true },
175
+ multi: true, min: 1, style: "chips",
176
+ });
177
+ ```
178
+
179
+ ⚠️ 방 멤버는 서버가 미리 채울 수 없어 `options` 사본이 비게 된다(빌더가 경고한다) — 그 경우 카드
180
+ `fallback` 이 "옛 클라에서는 고를 수 없다"는 사실을 말해야 한다.
181
+
182
+ ### ④ `collapsible` 안의 처리 이력 마크다운 → `card.activity(items)`
183
+
184
+ ```jsonc
185
+ // before — 접힌 상태에서 정보가 0이고, 펼쳐도 사람·시각에 구조가 없다
186
+ { "type": "collapsible", "title": "처리 이력", "blocks": [
187
+ { "type": "text", "text": "- 18:10 현호손 보고 올림\n- 18:12 heetae 에게 전달" } ] }
188
+ ```
189
+
190
+ ```ts
191
+ // after — 주어가 참조라 아바타·이름으로 서고, maxVisible 을 넘는 나머지는 렌더러가 접는다
192
+ ...card.activity([ // 🔴 items 는 최신순(맨 앞이 가장 최근)
193
+ { who: { user: "@heetae:theunderdog.ai" }, what: "1차 리마인드", at: "2026-09-20T18:15+09:00" },
194
+ { who: { user: "@hyunho:theunderdog.ai" }, what: "전달", at: "2026-09-20T18:12+09:00",
195
+ to: { user: "@heetae:theunderdog.ai" } },
196
+ ], { label: "처리 이력", maxVisible: 3 })
197
+ ```
198
+
199
+ `card.activity` 는 옛 클라용 `collapsible` 사본을 **자동으로 병기**한다(그래서 여기도 `Block[]` 이라 펼친다).
200
+ 새 렌더러는 `legacy_for: "activity"` 표식을 보고 사본을 안 그린다 — 클라 배포가 퍼지면 `{ legacy: false }`.
201
+
56
202
  ## 실행 방식
57
203
 
58
204
  ```js
package/dist/action.d.ts CHANGED
@@ -8,11 +8,18 @@
8
8
  */
9
9
  import { z } from "zod";
10
10
  import type { Block, ButtonStyle } from "@underdogai/mesh-event-schemas";
11
- /** UiCardContent 의 actions 블록 element 타입을 스키마에서 직접 파생(닫힌 집합과 100% 일치 보장). */
11
+ /**
12
+ * UiCardContent 의 actions 블록 element 타입을 스키마에서 직접 파생(닫힌 집합과 100% 일치 보장).
13
+ *
14
+ * ⚠️ 0.9.0 에서 줄의 원소가 셋이 됐다(button · linkButton · overflow). `.button()` 이 돌려주는 것은
15
+ * 그중 **버튼 하나**라 여기서 좁힌다 — 안 좁히면 반환 타입이 유니온이 되어 호출자가 매번 narrow 해야 한다.
16
+ */
12
17
  type ActionsBlock = Extract<Block, {
13
18
  type: "actions";
14
19
  }>;
15
- export type ButtonElement = ActionsBlock["elements"][number];
20
+ export type ButtonElement = Extract<ActionsBlock["elements"][number], {
21
+ type: "button";
22
+ }>;
16
23
  export interface ActionButtonOpts {
17
24
  style?: ButtonStyle;
18
25
  /** true → 기본 확인 다이얼로그, 객체 → 커스텀 확인 문구. UI 게이트일 뿐(권한은 서버). */
@@ -1 +1 @@
1
- {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../src/action.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAEzE,6EAA6E;AAC7E,KAAK,YAAY,GAAG,OAAO,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AACxD,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,OAAO,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;CACtD;AAED,MAAM,WAAW,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU;IAC9D,2DAA2D;IAC3D,EAAE,EAAE,MAAM,CAAC;IACX,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,WAAW,EAAE,OAAO,CAAC;IACrB,8DAA8D;IAC9D,MAAM,EAAE,CAAC,CAAC;IACV;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,uEAAuE;IACvE,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,wEAAwE;IACxE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,aAAa,CAAC;CAC9D;AAED,6DAA6D;AAC7D,wBAAgB,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,CAAC;IACX,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB,GAAG,SAAS,CAAC,CAAC,CAAC,CAuBf"}
1
+ {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../src/action.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAEzE;;;;;GAKG;AACH,KAAK,YAAY,GAAG,OAAO,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AACxD,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC;AAE1F,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,OAAO,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;CACtD;AAED,MAAM,WAAW,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU;IAC9D,2DAA2D;IAC3D,EAAE,EAAE,MAAM,CAAC;IACX,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,WAAW,EAAE,OAAO,CAAC;IACrB,8DAA8D;IAC9D,MAAM,EAAE,CAAC,CAAC;IACV;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,uEAAuE;IACvE,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,wEAAwE;IACxE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,aAAa,CAAC;CAC9D;AAED,6DAA6D;AAC7D,wBAAgB,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,CAAC;IACX,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB,GAAG,SAAS,CAAC,CAAC,CAAC,CAuBf"}
@@ -1 +1 @@
1
- {"version":3,"file":"action.js","sourceRoot":"","sources":["../src/action.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkDxB,6DAA6D;AAC7D,MAAM,UAAU,YAAY,CAAwC,GASnE;IACC,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAiB,CAAC;IAC1E,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,KAAK;QACrC,MAAM;QACN,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,MAAM,CAAC,IAAI,EAAE,IAAI;YACf,MAAM,OAAO,GACX,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,IAAI,SAAS,CAAC;YAC/F,MAAM,EAAE,GAAG;gBACT,IAAI,EAAE,QAAiB;gBACvB,SAAS,EAAE,GAAG,CAAC,EAAE;gBACjB,IAAI;gBACJ,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7C,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/B,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC9C,CAAC;YACF,OAAO,EAAmB,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"action.js","sourceRoot":"","sources":["../src/action.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAuDxB,6DAA6D;AAC7D,MAAM,UAAU,YAAY,CAAwC,GASnE;IACC,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAiB,CAAC;IAC1E,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,KAAK;QACrC,MAAM;QACN,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,MAAM,CAAC,IAAI,EAAE,IAAI;YACf,MAAM,OAAO,GACX,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,IAAI,SAAS,CAAC;YAC/F,MAAM,EAAE,GAAG;gBACT,IAAI,EAAE,QAAiB;gBACvB,SAAS,EAAE,GAAG,CAAC,EAAE;gBACjB,IAAI;gBACJ,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7C,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/B,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC9C,CAAC;YACF,OAAO,EAAmB,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -4,8 +4,7 @@
4
4
  * 핵심: 새 블록을 만들지 않는다(코어 어휘만 조합). 그래서 결과가 "데이터"로 남고 — App Service 가
5
5
  * 그대로 와이어에 실어 보내면 클라가 가진 렌더러로 그린다(클라 무변경 = "AS만 추가해도 UI 등록").
6
6
  */
7
- import { type Block, type PanelSpec, type SurfaceSection, type Tone, type UiCardContent } from "@underdogai/mesh-event-schemas";
8
- import type { ButtonElement } from "./action.js";
7
+ import { type ActivityBlock, type Block, type ActionElement, type PanelSpec, type SelectBlock, type SelectOption, type SelectSource, type SurfaceSection, type Tone, type UiCardContent } from "@underdogai/mesh-event-schemas";
9
8
  export interface CardOpts {
10
9
  title?: string;
11
10
  fallback?: string;
@@ -24,7 +23,21 @@ export declare const card: {
24
23
  type: "fields";
25
24
  }>["items"]): Block;
26
25
  text(text: string): Block;
27
- actions(elements: ButtonElement[]): Block;
26
+ /**
27
+ * 액션 줄 — 버튼·링크버튼·⋯ 메뉴를 한 줄에 둔다. **블록 하나가 아니라 배열을 돌려준다**(0.9.0).
28
+ *
29
+ * 🔴 **왜 배열인가**: 줄 안의 `overflow` 는 **새 클라에만** 보인다 — `actions.elements` 는 닫힌
30
+ * 유니온이라 옛 클라의 `dropUnknownBlocks` 가 그 원소 하나 때문에 **actions 블록을 통째로 떨군다**
31
+ * (버튼이 전부 사라진다). 그래서 전환기 동안 같은 ⋯ 를 **최상위 블록 사본**으로 같이 낸다 —
32
+ * 옛 클라는 사본만, 새 클라는 줄 안의 것만 그린다(`legacyOverflowIndices` 가 사본을 건너뛴다).
33
+ * `card.activity` + `collapsible.legacy_for` 와 같은 규약이다.
34
+ *
35
+ * ⚠️ ⋯ 가 없는 줄은 배열 길이가 **1** 이다 — 사본을 낼 것이 없다(옛 클라도 그대로 읽는다).
36
+ * 클라 배포가 충분히 퍼지면 `{ legacy: false }` 로 끄고, 그다음 기본값을 바꾼다(이 시리즈 밖).
37
+ */
38
+ actions(elements: ActionElement[], opts?: {
39
+ legacy?: boolean;
40
+ }): Block[];
28
41
  /** 상태 배지(톤 강조 칩). */
29
42
  badge(text: string, tone?: Tone): Block;
30
43
  /** 표(열 이름 + 행 문자열 배열). */
@@ -74,15 +87,37 @@ export declare const card: {
74
87
  value?: number;
75
88
  unit?: string;
76
89
  }): Block;
77
- /** 드롭다운 선택(단일/다중). */
78
- select(name: string, options: {
79
- value: string;
80
- label: string;
81
- }[], opts?: {
90
+ /**
91
+ * **선택** (0.9.0 부터 축) — 공급원(`source`) × 개수(`multi`) × 표현(`style`·`searchable`).
92
+ *
93
+ * 컨트롤은 **작성자가 안 고른다**: 후보 수·`multi`·`source` 를 보고 렌더러가 네이티브 셀렉트 /
94
+ * 펼친 목록 / 콤보박스(검색·칩·아바타 행)를 정한다. 여기서 말하는 건 사실뿐이다.
95
+ *
96
+ * ```ts
97
+ * card.select("to", [], { label: "받을 사람", source: { kind: "room", exclude_self: true },
98
+ * multi: true, min: 1, style: "chips" })
99
+ * card.select("issue", recent, { source: { kind: "query", action_id: "issue.search" } })
100
+ * ```
101
+ *
102
+ * 🔴 **`options` 는 `source` 가 있어도 계약이다** — 이 키를 모르는 옛 클라는 `source` 를 벗기고
103
+ * `options` 만 그린다. 비워 보내면 그 클라에서 **고를 것이 없는 select** 가 선다. 방 멤버처럼
104
+ * 서버가 채울 수 없는 후보라면 빈 배열이 불가피하니, 그때는 **카드 `fallback` 이 그 사실을 말해야
105
+ * 한다**(예: "이 클라이언트에서는 사람 선택을 지원하지 않아요 — 앱을 업데이트해 주세요").
106
+ * 그 자리를 빠뜨리면 아래 경고가 뜬다 — 경고는 빌드를 막지 않지만 로그에 남는다.
107
+ */
108
+ select(name: string, options: SelectOption[], opts?: {
82
109
  label?: string;
83
110
  placeholder?: string;
84
111
  value?: string;
85
112
  multi?: boolean;
113
+ source?: SelectSource;
114
+ style?: SelectBlock["style"];
115
+ searchable?: boolean;
116
+ required?: boolean;
117
+ /** `multi` 전용 — 고를 **개수**의 하한/상한. */
118
+ min?: number;
119
+ max?: number;
120
+ error?: string;
86
121
  }): Block;
87
122
  /** 라디오 그룹(옵션이 펼쳐져 보이는 단일 선택). */
88
123
  radio(name: string, options: {
@@ -121,6 +156,23 @@ export declare const card: {
121
156
  onText?: string;
122
157
  offText?: string;
123
158
  }): Block;
159
+ /**
160
+ * 처리 이력(0.8.0) — 주어가 참조인 시간순 목록. **블록 하나가 아니라 배열을 돌려준다.**
161
+ *
162
+ * 🔴 **왜 배열인가**: `activity` 는 새 *블록 타입*이라 옛 클라의 `dropUnknownBlocks` 에서 **통째로
163
+ * 떨어진다**(키 추가와 달리 평문 사본이 곁에 설 자리가 없다). 그래서 전환기 동안 같은 내용을
164
+ * `collapsible`+`text` 사본으로 **같이** 낸다 — 옛 클라는 사본만, 새 클라는 원본만 그린다
165
+ * (새 렌더러가 `legacy_for: "activity"` 를 보고 사본을 건너뛴다).
166
+ *
167
+ * 클라 배포가 충분히 퍼지면 `{ legacy: false }` 로 끄고, 그다음 기본값을 바꾼다(이 시리즈 밖).
168
+ *
169
+ * @param items **최신순**(맨 앞이 가장 최근).
170
+ */
171
+ activity(items: ActivityBlock["items"], opts?: {
172
+ label?: string;
173
+ maxVisible?: number;
174
+ legacy?: boolean;
175
+ }): Block[];
124
176
  };
125
177
  /** 우측 셸 패널(PanelSpec) 빌더 — 닫힌 SurfaceBody 조합. value 문자열의 {{entity.path}} 는 클라가 바인딩. */
126
178
  export declare const panel: {
@@ -1 +1 @@
1
- {"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../src/builders.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../src/builders.ts"],"names":[],"mappings":"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"}
package/dist/builders.js CHANGED
@@ -28,8 +28,25 @@ export const card = {
28
28
  text(text) {
29
29
  return { type: "text", text };
30
30
  },
31
- actions(elements) {
32
- return { type: "actions", elements };
31
+ /**
32
+ * 액션 버튼·링크버튼·⋯ 메뉴를 한 줄에 둔다. **블록 하나가 아니라 배열을 돌려준다**(0.9.0).
33
+ *
34
+ * 🔴 **왜 배열인가**: 줄 안의 `overflow` 는 **새 클라에만** 보인다 — `actions.elements` 는 닫힌
35
+ * 유니온이라 옛 클라의 `dropUnknownBlocks` 가 그 원소 하나 때문에 **actions 블록을 통째로 떨군다**
36
+ * (버튼이 전부 사라진다). 그래서 전환기 동안 같은 ⋯ 를 **최상위 블록 사본**으로 같이 낸다 —
37
+ * 옛 클라는 사본만, 새 클라는 줄 안의 것만 그린다(`legacyOverflowIndices` 가 사본을 건너뛴다).
38
+ * `card.activity` + `collapsible.legacy_for` 와 같은 규약이다.
39
+ *
40
+ * ⚠️ ⋯ 가 없는 줄은 배열 길이가 **1** 이다 — 사본을 낼 것이 없다(옛 클라도 그대로 읽는다).
41
+ * 클라 배포가 충분히 퍼지면 `{ legacy: false }` 로 끄고, 그다음 기본값을 바꾼다(이 시리즈 밖).
42
+ */
43
+ actions(elements, opts = {}) {
44
+ const row = { type: "actions", elements };
45
+ if (opts.legacy === false)
46
+ return [row];
47
+ // 사본은 **같은 객체**다 — `action_id` 집합이 같아야 새 렌더러가 사본으로 알아본다.
48
+ const menus = elements.filter((el) => el.type === "overflow");
49
+ return menus.length ? [row, ...menus] : [row];
33
50
  },
34
51
  // --- 표시 블록 헬퍼(B1 — 스키마엔 있는데 헬퍼가 없던 갭) ---
35
52
  /** 상태 배지(톤 강조 칩). */
@@ -67,8 +84,32 @@ export const card = {
67
84
  slider(name, opts = {}) {
68
85
  return { type: "slider", name, ...opts };
69
86
  },
70
- /** 드롭다운 선택(단일/다중). */
87
+ /**
88
+ * **선택** (0.9.0 부터 세 축) — 공급원(`source`) × 개수(`multi`) × 표현(`style`·`searchable`).
89
+ *
90
+ * 컨트롤은 **작성자가 안 고른다**: 후보 수·`multi`·`source` 를 보고 렌더러가 네이티브 셀렉트 /
91
+ * 펼친 목록 / 콤보박스(검색·칩·아바타 행)를 정한다. 여기서 말하는 건 사실뿐이다.
92
+ *
93
+ * ```ts
94
+ * card.select("to", [], { label: "받을 사람", source: { kind: "room", exclude_self: true },
95
+ * multi: true, min: 1, style: "chips" })
96
+ * card.select("issue", recent, { source: { kind: "query", action_id: "issue.search" } })
97
+ * ```
98
+ *
99
+ * 🔴 **`options` 는 `source` 가 있어도 계약이다** — 이 키를 모르는 옛 클라는 `source` 를 벗기고
100
+ * `options` 만 그린다. 비워 보내면 그 클라에서 **고를 것이 없는 select** 가 선다. 방 멤버처럼
101
+ * 서버가 채울 수 없는 후보라면 빈 배열이 불가피하니, 그때는 **카드 `fallback` 이 그 사실을 말해야
102
+ * 한다**(예: "이 클라이언트에서는 사람 선택을 지원하지 않아요 — 앱을 업데이트해 주세요").
103
+ * 그 자리를 빠뜨리면 아래 경고가 뜬다 — 경고는 빌드를 막지 않지만 로그에 남는다.
104
+ */
71
105
  select(name, options, opts = {}) {
106
+ if (opts.source && options.length === 0) {
107
+ // SDK 는 런타임 환경을 가정하지 않는다(lib 에 console 없음) — `runtime.ts` 의 기본 로그와 같은 자세.
108
+ const g = globalThis;
109
+ g.console?.warn(`[app-sdk] card.select("${name}") — source: "${opts.source.kind}" 인데 options 사본이 비어 있습니다. ` +
110
+ "이 키를 모르는 클라이언트에는 고를 것이 없는 select 가 섭니다. " +
111
+ "정적 사본을 채우거나, 카드 fallback 에 그 사실을 적어 주세요(card.build 의 opts.fallback).");
112
+ }
72
113
  return { type: "select", name, options, ...opts };
73
114
  },
74
115
  /** 라디오 그룹(옵션이 펼쳐져 보이는 단일 선택). */
@@ -98,7 +139,55 @@ export const card = {
98
139
  toggle(name, label, opts = {}) {
99
140
  return { type: "toggle", name, label, ...opts };
100
141
  },
142
+ /**
143
+ * 처리 이력(0.8.0) — 주어가 참조인 시간순 목록. **블록 하나가 아니라 배열을 돌려준다.**
144
+ *
145
+ * 🔴 **왜 배열인가**: `activity` 는 새 *블록 타입*이라 옛 클라의 `dropUnknownBlocks` 에서 **통째로
146
+ * 떨어진다**(키 추가와 달리 평문 사본이 곁에 설 자리가 없다). 그래서 전환기 동안 같은 내용을
147
+ * `collapsible`+`text` 사본으로 **같이** 낸다 — 옛 클라는 사본만, 새 클라는 원본만 그린다
148
+ * (새 렌더러가 `legacy_for: "activity"` 를 보고 사본을 건너뛴다).
149
+ *
150
+ * 클라 배포가 충분히 퍼지면 `{ legacy: false }` 로 끄고, 그다음 기본값을 바꾼다(이 시리즈 밖).
151
+ *
152
+ * @param items **최신순**(맨 앞이 가장 최근).
153
+ */
154
+ activity(items, opts = {}) {
155
+ const block = {
156
+ type: "activity",
157
+ items,
158
+ ...(opts.label ? { label: opts.label } : {}),
159
+ ...(opts.maxVisible ? { maxVisible: opts.maxVisible } : {}),
160
+ };
161
+ if (opts.legacy === false)
162
+ return [block];
163
+ return [block, legacyActivityCopy(items, opts.label)];
164
+ },
101
165
  };
166
+ /**
167
+ * 옛 클라용 `activity` 사본 — 접기 안의 평문 여러 줄("누가 · 무엇 · 언제").
168
+ *
169
+ * 마크다운을 켜지 않는다: `what` 은 인라인 마크다운이 허용되지만, 여기서 켜면 옛 클라가 굵게·링크를
170
+ * 그리면서 줄 구조를 잃는다. 사본의 목적은 **정보가 사라지지 않는 것**이지 예쁘게 보이는 게 아니다.
171
+ */
172
+ function legacyActivityCopy(items, label) {
173
+ const lines = items.map((it) => {
174
+ const who = refText(it.who);
175
+ const to = it.to ? ` → ${refText(it.to)}` : "";
176
+ return `${who} · ${it.what}${to} · ${it.at}`;
177
+ });
178
+ return {
179
+ type: "collapsible",
180
+ title: label ?? "Activity",
181
+ legacy_for: "activity",
182
+ blocks: [{ type: "text", text: lines.join("\n") }],
183
+ };
184
+ }
185
+ /** 참조를 사본용 문자열로 — 사람은 MXID, 엔티티는 `type · id`(해석기가 없는 쪽이 읽는 글이다). */
186
+ function refText(v) {
187
+ if (typeof v === "string")
188
+ return v;
189
+ return "user" in v ? v.user : `${v.entity.type} · ${v.entity.id}`;
190
+ }
102
191
  /** 우측 셸 패널(PanelSpec) 빌더 — 닫힌 SurfaceBody 조합. value 문자열의 {{entity.path}} 는 클라가 바인딩. */
103
192
  export const panel = {
104
193
  sections(sections) {
@@ -1 +1 @@
1
- {"version":3,"file":"builders.js","sourceRoot":"","sources":["../src/builders.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"builders.js","sourceRoot":"","sources":["../src/builders.ts"],"names":[],"mappings":"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"}
package/dist/runtime.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  * 핸들러는 부작용을 직접 실행하지 않고 "효과(Effect)"를 선언한다 → 실 AS 는 matrix client 로 적용,
9
9
  * 증명 스크립트는 효과 배열을 검사한다(같은 SDK 코드를 양쪽에서 검증 = 테스트성).
10
10
  */
11
- import { type UiActionClient, type UiCardContent } from "@underdogai/mesh-event-schemas";
11
+ import { type UiActionClient, type UiActionContent, type UiActionResultContent, type UiCardContent } from "@underdogai/mesh-event-schemas";
12
12
  import type { App } from "./app.js";
13
13
  /**
14
14
  * 발행 형태 — 같은 사실을 어떤 Matrix 형태로 보낼지(킥오프 §2.3).
@@ -48,7 +48,19 @@ export type Effect = {
48
48
  actionId: string;
49
49
  values: Record<string, unknown>;
50
50
  label?: string;
51
+ }
52
+ /**
53
+ * 액션 한 건의 판정 결과를 **누른 사람에게** 되돌린다(0.7.0 — `org.corp.ui.action.result`).
54
+ *
55
+ * 선언은 "무엇을 말하는가"만 담는다: 수신자(`to`)·카드 이벤트·액션 참조는 **호스트가 채운다**
56
+ * (핸들러는 자기가 어떤 이벤트에 응답 중인지 알 필요가 없다 — `edit` 가 `cardEventId` 를 모르는 것과 같다).
57
+ */
58
+ | {
59
+ kind: "result";
60
+ result: ActionResult;
51
61
  };
62
+ /** `ctx.result(...)` 가 받는 것 — 와이어에서 호스트가 채우는 네 키를 뺀 나머지. */
63
+ export type ActionResult = Omit<UiActionResultContent, "v" | "to" | "card_event_id" | "m.relates_to">;
52
64
  /**
53
65
  * 호스트가 주입하는 백엔드 핸들 — 핸들러가 "권위 데이터를 읽고 → 판단 → 효과 선언"(read-then-decide)할 때 쓴다.
54
66
  * SDK 는 호출 형태(도구 이름 + 구조화 인자)만 정의하고, 구현(MCP 도구/HTTP)·권한 스코프는 호스트가 소유한다
@@ -85,6 +97,15 @@ export interface ActionCtx {
85
97
  cardId?: string;
86
98
  /** 폼 입력(원본). 핸들러는 action.values.parse(ctx.values) 로 타입 확보. */
87
99
  values: Record<string, unknown>;
100
+ /**
101
+ * 이 호출이 **무엇이었나** (0.9.0). 대개 안 봐도 된다 — 단 하나, `"query"` 는 다르다:
102
+ * 사람이 누른 게 아니라 `select` 의 `source: { kind: "query" }` 가 **타이핑 중에** 보낸 요청이라,
103
+ * 핸들러는 부작용 없이 `ctx.result({ kind: "options", … })` 로만 답해야 한다.
104
+ *
105
+ * 🔴 **자기 신고다** — 권위는 여전히 `sender` 와 액션 정의(`scope`·`destructive`)다. 이 값으로
106
+ * 권한을 가르지 말고, "무엇을 만들지"만 가른다. 옛 클라는 안 싣거나 `"button"` 을 싣는다.
107
+ */
108
+ action_type?: UiActionContent["action_type"];
88
109
  /** 작성 클라이언트 환경(있으면, G6) — 클라의 자기 신고라 표시·진단용이지 권위 아님(권위는 sender). */
89
110
  client?: UiActionClient;
90
111
  /** 편집 대상 원본 카드 event_id(있으면). */
@@ -126,7 +147,24 @@ export interface ActionCtx {
126
147
  invoke(actionId: string, values?: Record<string, unknown>, opts?: {
127
148
  label?: string;
128
149
  }): void;
150
+ /**
151
+ * 효과 선언 헬퍼 — 이 액션의 **판정 결과를 누른 사람에게** 되돌린다(0.7.0).
152
+ *
153
+ * ctx.result({ kind: "reject", errors: { due: "오늘 이후여야 해요" } })
154
+ * ctx.result({ kind: "denied", reason: "현재 수신자만 처리할 수 있어요" })
155
+ * ctx.result({ kind: "ok", message: "확인 처리됨" })
156
+ * ctx.result({ kind: "options", name: "to", options: [...] }) // 동적 후보(select source:query)
157
+ *
158
+ * 🔴 **`send` 로 오류 카드를 쌓던 자리를 대신한다** — 결과가 방이 아니라 누른 사람의 그 컨트롤로 간다.
159
+ * ⚠️ 한 핸들러가 `result` 를 여러 번 내면 **마지막 것만** 남는다(같은 액션에 대한 판정이 여럿일 수
160
+ * 없다 — 클라 인덱스도 같은 규칙으로 최신 하나만 그린다). 효과 배열에는 그대로 쌓이지만
161
+ * `applyEffects` 가 마지막 하나만 보낸다.
162
+ * ⚠️ `card_id`·`action_id` 는 안 줘도 된다 — 지금 처리 중인 액션의 것을 SDK 가 채운다.
163
+ */
164
+ result(r: PartialActionResult): void;
129
165
  }
166
+ /** `ctx.result(...)` 의 인자 — `card_id`/`action_id` 는 SDK 가 채우므로 생략할 수 있다. */
167
+ export type PartialActionResult = Omit<ActionResult, "card_id" | "action_id"> & Partial<Pick<ActionResult, "card_id" | "action_id">>;
130
168
  export type ActionHandler = (ctx: ActionCtx) => void | Promise<void>;
131
169
  /** 호스트가 주입하는 권한 게이트(= appservice-agent/policy.evaluateAction 의 얇은 래퍼). */
132
170
  export type GateFn = (input: {
@@ -163,6 +201,17 @@ export interface DispatchInput {
163
201
  stateReader?: (type: string, stateKey: string) => Promise<Record<string, unknown> | null>;
164
202
  /** 호스트 주입 앱 정책 설정(선택) — ctx.config 로 핸들러에 전달(예: { approvalThreshold }). */
165
203
  config?: Record<string, unknown>;
204
+ /**
205
+ * 값 검증 실패·권한 거절에 **결과 효과를 자동으로 붙일지**(기본 true, 0.7.0).
206
+ *
207
+ * 왜 기본이 켬인가: 이 두 경로는 지금까지 **핸들러에 도달조차 안 했다** — 앱 코드가 개입할 자리가
208
+ * 없어서 사용자는 아무 반응도 못 봤다(`ignored`) 또는 앱이 따로 오류 카드를 쌓았다. 자동으로 붙이면
209
+ * **앱을 한 줄도 안 고치고** 옛 앱의 거절·검증 실패가 누른 사람의 그 컨트롤로 인라인 회신된다.
210
+ *
211
+ * 끄는 경우: 결과 문구를 앱이 전부 소유하고 싶거나(전환기 중복 방지), 증명 스크립트가 효과 배열을
212
+ * 엄격히 재는 경우.
213
+ */
214
+ autoResult?: boolean;
166
215
  }
167
216
  export interface DispatchResult {
168
217
  status: "ran" | "denied" | "ignored";
@@ -245,6 +294,14 @@ export interface ApplyEffectsInput {
245
294
  };
246
295
  /** workflow.updated_by 로 기록할 주체(보통 액션 발신자). */
247
296
  sender?: string;
297
+ /**
298
+ * `result` 효과의 **수신자**(0.7.0) — 이 액션을 누른 사람의 MXID. 없으면 결과를 보낼 곳이 없으므로
299
+ * 경고 후 건너뛴다(throw 하지 않는다 — 결과 회신은 부가 기능이고, 그것 때문에 뒤따르는 카드 편집이
300
+ * 취소되면 더 나쁘다. `workflow` 가 로그 후 계속하는 것과 같은 판단).
301
+ */
302
+ actor?: string;
303
+ /** `result` 효과가 가리킬 **액션** 이벤트 id(0.7.0). 없으면 `m.relates_to` 없이 보낸다(card_id 로 붙는다). */
304
+ actionEventId?: string;
248
305
  /**
249
306
  * delegate 효과 콜백 — stateful·교차에이전트(A2A) 프로토콜은 호스트가 소유한다. 미주입 호스트(1회 발행·
250
307
  * 단순 봇)에서 delegate 가 나오면 경고 후 무시한다(조용한 유실 방지 로그).
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}