@things-factory/board-ai 10.1.4 → 10.1.6

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 (199) hide show
  1. package/client/components/default-catalog-entries.ts +1 -1
  2. package/client/components/default-slash-templates.ts +1 -1
  3. package/client/index.ts +27 -6
  4. package/dist-client/client/components/default-catalog-entries.d.ts +1 -1
  5. package/dist-client/client/components/default-catalog-entries.js.map +1 -1
  6. package/dist-client/client/components/default-slash-templates.d.ts +1 -1
  7. package/dist-client/client/components/default-slash-templates.js.map +1 -1
  8. package/dist-client/client/index.d.ts +3 -11
  9. package/dist-client/client/index.js +25 -6
  10. package/dist-client/client/index.js.map +1 -1
  11. package/dist-client/server/service/assistant.d.ts +22 -22
  12. package/dist-client/server/service/assistant.js +32 -70
  13. package/dist-client/server/service/assistant.js.map +1 -1
  14. package/dist-client/server/service/grounding.d.ts +2 -12
  15. package/dist-client/server/service/grounding.js +15 -23
  16. package/dist-client/server/service/grounding.js.map +1 -1
  17. package/dist-client/server/service/types.d.ts +2 -4
  18. package/dist-client/server/service/types.js.map +1 -1
  19. package/dist-client/server/service/validation/board-model-schema.d.ts +270 -270
  20. package/dist-client/tsconfig.tsbuildinfo +1 -1
  21. package/dist-server/service/assistant.d.ts +22 -22
  22. package/dist-server/service/assistant.js +25 -76
  23. package/dist-server/service/assistant.js.map +1 -1
  24. package/dist-server/service/board-ai-resolver.js +41 -30
  25. package/dist-server/service/board-ai-resolver.js.map +1 -1
  26. package/dist-server/service/board-session-resolver.d.ts +12 -0
  27. package/dist-server/service/board-session-resolver.js +203 -0
  28. package/dist-server/service/board-session-resolver.js.map +1 -0
  29. package/dist-server/service/board-tool-rights.d.ts +7 -0
  30. package/dist-server/service/board-tool-rights.js +62 -0
  31. package/dist-server/service/board-tool-rights.js.map +1 -0
  32. package/dist-server/service/grounding.d.ts +2 -12
  33. package/dist-server/service/grounding.js +16 -24
  34. package/dist-server/service/grounding.js.map +1 -1
  35. package/dist-server/service/index.d.ts +4 -10
  36. package/dist-server/service/index.js +16 -23
  37. package/dist-server/service/index.js.map +1 -1
  38. package/dist-server/service/patch-entry/board-patch-subscription.js +2 -2
  39. package/dist-server/service/patch-entry/board-patch-subscription.js.map +1 -1
  40. package/dist-server/service/patch-entry/patch-entry.d.ts +1 -1
  41. package/dist-server/service/patch-entry/patch-entry.js +3 -3
  42. package/dist-server/service/patch-entry/patch-entry.js.map +1 -1
  43. package/dist-server/service/types.d.ts +2 -4
  44. package/dist-server/service/types.js.map +1 -1
  45. package/dist-server/tsconfig.tsbuildinfo +1 -1
  46. package/package.json +6 -5
  47. package/server/service/apply-patch-drift.test.ts +3 -1
  48. package/server/service/assistant.ts +47 -73
  49. package/server/service/board-ai-resolver.ts +22 -12
  50. package/server/service/board-session-resolver.ts +183 -0
  51. package/server/service/board-tool-rights.test.ts +96 -0
  52. package/server/service/board-tool-rights.ts +73 -0
  53. package/server/service/dock-contract.test.ts +3 -0
  54. package/server/service/grounding.test.ts +3 -3
  55. package/server/service/grounding.ts +15 -34
  56. package/server/service/index.ts +16 -22
  57. package/server/service/patch-entry/board-patch-subscription.ts +1 -1
  58. package/server/service/patch-entry/patch-entry.ts +3 -2
  59. package/server/service/registry-tool-loop.test.ts +1 -0
  60. package/server/service/tool-exposure.test.ts +2 -0
  61. package/server/service/types.ts +3 -4
  62. package/client/components/board-ai-chat.test.ts +0 -149
  63. package/client/components/board-ai-chat.ts +0 -3184
  64. package/client/components/chat-echo-dedup.test.ts +0 -230
  65. package/client/components/chat-echo-dedup.ts +0 -155
  66. package/client/components/chat-input-builder.ts +0 -69
  67. package/client/components/markdown.test.ts +0 -518
  68. package/client/components/markdown.ts +0 -508
  69. package/client/components/mention-popup-helpers.ts +0 -433
  70. package/client/components/mention-popup.test.ts +0 -588
  71. package/client/components/mention-popup.ts +0 -238
  72. package/client/utils/board-edit-patch.ts +0 -374
  73. package/dist-client/client/components/board-ai-chat.d.ts +0 -384
  74. package/dist-client/client/components/board-ai-chat.js +0 -3008
  75. package/dist-client/client/components/board-ai-chat.js.map +0 -1
  76. package/dist-client/client/components/board-ai-chat.test.d.ts +0 -1
  77. package/dist-client/client/components/board-ai-chat.test.js +0 -138
  78. package/dist-client/client/components/board-ai-chat.test.js.map +0 -1
  79. package/dist-client/client/components/chat-echo-dedup.d.ts +0 -54
  80. package/dist-client/client/components/chat-echo-dedup.js +0 -115
  81. package/dist-client/client/components/chat-echo-dedup.js.map +0 -1
  82. package/dist-client/client/components/chat-echo-dedup.test.d.ts +0 -1
  83. package/dist-client/client/components/chat-echo-dedup.test.js +0 -203
  84. package/dist-client/client/components/chat-echo-dedup.test.js.map +0 -1
  85. package/dist-client/client/components/chat-input-builder.d.ts +0 -55
  86. package/dist-client/client/components/chat-input-builder.js +0 -32
  87. package/dist-client/client/components/chat-input-builder.js.map +0 -1
  88. package/dist-client/client/components/markdown.d.ts +0 -60
  89. package/dist-client/client/components/markdown.js +0 -422
  90. package/dist-client/client/components/markdown.js.map +0 -1
  91. package/dist-client/client/components/markdown.test.d.ts +0 -1
  92. package/dist-client/client/components/markdown.test.js +0 -418
  93. package/dist-client/client/components/markdown.test.js.map +0 -1
  94. package/dist-client/client/components/mention-popup-helpers.d.ts +0 -165
  95. package/dist-client/client/components/mention-popup-helpers.js +0 -330
  96. package/dist-client/client/components/mention-popup-helpers.js.map +0 -1
  97. package/dist-client/client/components/mention-popup.d.ts +0 -35
  98. package/dist-client/client/components/mention-popup.js +0 -223
  99. package/dist-client/client/components/mention-popup.js.map +0 -1
  100. package/dist-client/client/components/mention-popup.test.d.ts +0 -1
  101. package/dist-client/client/components/mention-popup.test.js +0 -474
  102. package/dist-client/client/components/mention-popup.test.js.map +0 -1
  103. package/dist-client/client/utils/board-edit-patch.d.ts +0 -157
  104. package/dist-client/client/utils/board-edit-patch.js +0 -284
  105. package/dist-client/client/utils/board-edit-patch.js.map +0 -1
  106. package/dist-server/service/chat-message/chat-message-broadcast.d.ts +0 -13
  107. package/dist-server/service/chat-message/chat-message-broadcast.js +0 -13
  108. package/dist-server/service/chat-message/chat-message-broadcast.js.map +0 -1
  109. package/dist-server/service/chat-message/chat-message-publish.d.ts +0 -6
  110. package/dist-server/service/chat-message/chat-message-publish.js +0 -27
  111. package/dist-server/service/chat-message/chat-message-publish.js.map +0 -1
  112. package/dist-server/service/chat-message/chat-message-subscription.d.ts +0 -8
  113. package/dist-server/service/chat-message/chat-message-subscription.js +0 -53
  114. package/dist-server/service/chat-message/chat-message-subscription.js.map +0 -1
  115. package/dist-server/service/chat-message/chat-message.d.ts +0 -68
  116. package/dist-server/service/chat-message/chat-message.js +0 -172
  117. package/dist-server/service/chat-message/chat-message.js.map +0 -1
  118. package/dist-server/service/chat-message/fold-history.d.ts +0 -43
  119. package/dist-server/service/chat-message/fold-history.js +0 -33
  120. package/dist-server/service/chat-message/fold-history.js.map +0 -1
  121. package/dist-server/service/chat-message/history-summary.d.ts +0 -43
  122. package/dist-server/service/chat-message/history-summary.js +0 -77
  123. package/dist-server/service/chat-message/history-summary.js.map +0 -1
  124. package/dist-server/service/chat-message/index.d.ts +0 -5
  125. package/dist-server/service/chat-message/index.js +0 -12
  126. package/dist-server/service/chat-message/index.js.map +0 -1
  127. package/dist-server/service/chat-message/llm-history.d.ts +0 -46
  128. package/dist-server/service/chat-message/llm-history.js +0 -87
  129. package/dist-server/service/chat-message/llm-history.js.map +0 -1
  130. package/dist-server/service/chat-session/chat-session.d.ts +0 -62
  131. package/dist-server/service/chat-session/chat-session.js +0 -164
  132. package/dist-server/service/chat-session/chat-session.js.map +0 -1
  133. package/dist-server/service/chat-session/index.d.ts +0 -3
  134. package/dist-server/service/chat-session/index.js +0 -7
  135. package/dist-server/service/chat-session/index.js.map +0 -1
  136. package/dist-server/service/chat-session/session-activity-broadcast.d.ts +0 -30
  137. package/dist-server/service/chat-session/session-activity-broadcast.js +0 -34
  138. package/dist-server/service/chat-session/session-activity-broadcast.js.map +0 -1
  139. package/dist-server/service/chat-session/session-activity-publish.d.ts +0 -12
  140. package/dist-server/service/chat-session/session-activity-publish.js +0 -37
  141. package/dist-server/service/chat-session/session-activity-publish.js.map +0 -1
  142. package/dist-server/service/chat-session/session-activity-subscription.d.ts +0 -14
  143. package/dist-server/service/chat-session/session-activity-subscription.js +0 -87
  144. package/dist-server/service/chat-session/session-activity-subscription.js.map +0 -1
  145. package/dist-server/service/chat-session/session-anchor.d.ts +0 -12
  146. package/dist-server/service/chat-session/session-anchor.js +0 -20
  147. package/dist-server/service/chat-session/session-anchor.js.map +0 -1
  148. package/dist-server/service/chat-session/session-inbox.d.ts +0 -80
  149. package/dist-server/service/chat-session/session-inbox.js +0 -133
  150. package/dist-server/service/chat-session/session-inbox.js.map +0 -1
  151. package/dist-server/service/chat-session-participant/chat-session-participant.d.ts +0 -49
  152. package/dist-server/service/chat-session-participant/chat-session-participant.js +0 -141
  153. package/dist-server/service/chat-session-participant/chat-session-participant.js.map +0 -1
  154. package/dist-server/service/chat-session-participant/index.d.ts +0 -4
  155. package/dist-server/service/chat-session-participant/index.js +0 -10
  156. package/dist-server/service/chat-session-participant/index.js.map +0 -1
  157. package/dist-server/service/chat-session-participant/invite-notification.d.ts +0 -27
  158. package/dist-server/service/chat-session-participant/invite-notification.js +0 -30
  159. package/dist-server/service/chat-session-participant/invite-notification.js.map +0 -1
  160. package/dist-server/service/chat-session-participant/presence.d.ts +0 -4
  161. package/dist-server/service/chat-session-participant/presence.js +0 -22
  162. package/dist-server/service/chat-session-participant/presence.js.map +0 -1
  163. package/dist-server/service/chat-session-resolver.d.ts +0 -102
  164. package/dist-server/service/chat-session-resolver.js +0 -856
  165. package/dist-server/service/chat-session-resolver.js.map +0 -1
  166. package/dist-server/service/subscribe-auth.d.ts +0 -14
  167. package/dist-server/service/subscribe-auth.js +0 -33
  168. package/dist-server/service/subscribe-auth.js.map +0 -1
  169. package/server/service/chat-message/chat-message-broadcast.integration.test.ts +0 -73
  170. package/server/service/chat-message/chat-message-broadcast.test.ts +0 -40
  171. package/server/service/chat-message/chat-message-broadcast.ts +0 -27
  172. package/server/service/chat-message/chat-message-publish.ts +0 -22
  173. package/server/service/chat-message/chat-message-subscription.ts +0 -41
  174. package/server/service/chat-message/chat-message.ts +0 -195
  175. package/server/service/chat-message/fold-history.test.ts +0 -98
  176. package/server/service/chat-message/fold-history.ts +0 -77
  177. package/server/service/chat-message/history-summary.test.ts +0 -127
  178. package/server/service/chat-message/history-summary.ts +0 -100
  179. package/server/service/chat-message/index.ts +0 -12
  180. package/server/service/chat-message/llm-history.test.ts +0 -194
  181. package/server/service/chat-message/llm-history.ts +0 -163
  182. package/server/service/chat-session/chat-session.ts +0 -182
  183. package/server/service/chat-session/index.ts +0 -5
  184. package/server/service/chat-session/session-activity-broadcast.ts +0 -57
  185. package/server/service/chat-session/session-activity-publish.ts +0 -44
  186. package/server/service/chat-session/session-activity-subscription.ts +0 -67
  187. package/server/service/chat-session/session-anchor.ts +0 -35
  188. package/server/service/chat-session/session-inbox.test.ts +0 -185
  189. package/server/service/chat-session/session-inbox.ts +0 -161
  190. package/server/service/chat-session-participant/chat-session-participant.ts +0 -135
  191. package/server/service/chat-session-participant/index.ts +0 -6
  192. package/server/service/chat-session-participant/invite-notification.test.ts +0 -30
  193. package/server/service/chat-session-participant/invite-notification.ts +0 -48
  194. package/server/service/chat-session-participant/presence.test.ts +0 -39
  195. package/server/service/chat-session-participant/presence.ts +0 -21
  196. package/server/service/chat-session-resolver.ts +0 -779
  197. package/server/service/session-anchor.test.ts +0 -65
  198. package/server/service/subscribe-auth.test.ts +0 -57
  199. package/server/service/subscribe-auth.ts +0 -34
@@ -1,223 +0,0 @@
1
- import { __decorate, __metadata } from "tslib";
2
- /**
3
- * <ox-mention-popup> — Mention 후보 리스트 popup overlay.
4
- *
5
- * board-ai-chat 의 textarea 위에 absolute 로 띄움. plain `<textarea>` + popup 분리 패턴
6
- * (한국어 IME 함정 회피 — contenteditable 사용 안 함).
7
- *
8
- * 키보드 네비게이션은 호스트 (board-ai-chat) 가 textarea keydown 으로 처리하고
9
- * activeIndex 만 동기화. 마우스 클릭은 popup 자체에서 처리.
10
- *
11
- * Pure helper (extractMentionContext / filterMentionCandidates 등) 는
12
- * `mention-popup-helpers.ts` 에 분리 — 단위 테스트 가능.
13
- */
14
- import { LitElement, css, html } from 'lit';
15
- import { customElement, property } from 'lit/decorators.js';
16
- export { buildMentionCandidates, buildCatalogCandidates, buildSlashCandidates, buildUserCandidates, extractMentionContext, filterMentionCandidates, applyMentionSelection, resolveMentionToken } from './mention-popup-helpers.js';
17
- /** match type 라벨 — things-scene SearchOverlay 의 MATCH_TYPE_LABELS 와 동일. */
18
- const MATCH_TYPE_LABEL = {
19
- id: 'ID',
20
- name: 'Name',
21
- tag: 'Tag',
22
- type: 'Type',
23
- class: 'Class',
24
- text: 'Text',
25
- data: 'Data',
26
- property: 'Prop',
27
- description: 'Desc'
28
- };
29
- let OxMentionPopup = class OxMentionPopup extends LitElement {
30
- constructor() {
31
- super(...arguments);
32
- this.results = [];
33
- this.activeIndex = 0;
34
- /** filter cap 후 표시 안 된 추가 매칭 수 ("...and N more" 표기용) */
35
- this.overflow = 0;
36
- }
37
- static { this.styles = css `
38
- :host {
39
- display: block;
40
- position: absolute;
41
- z-index: 1000;
42
- background: var(--md-sys-color-surface, #ffffff);
43
- border: 1px solid var(--md-sys-color-outline-variant, #e2e8f0);
44
- border-radius: 6px;
45
- box-shadow: 0 6px 18px rgba(0, 0, 0, 0.10);
46
- max-height: 220px;
47
- overflow-y: auto;
48
- /* 폭은 호스트가 left/right 로 결정. */
49
- }
50
- .empty {
51
- padding: 8px 10px;
52
- color: var(--md-sys-color-outline, #94a3b8);
53
- font-size: 11px;
54
- }
55
- /* dense 한 단일 행 — scene Finder 톤. label / hint / type-chip inline. */
56
- .item {
57
- display: flex;
58
- align-items: center;
59
- gap: 6px;
60
- padding: 4px 8px;
61
- cursor: pointer;
62
- font-size: 11.5px;
63
- line-height: 1.4;
64
- color: var(--md-sys-color-on-surface, #0f172a);
65
- border-bottom: 1px solid var(--md-sys-color-outline-variant, #f1f5f9);
66
- }
67
- .item:last-child {
68
- border-bottom: 0;
69
- }
70
- .item:hover {
71
- background: var(--md-sys-color-surface-container, #f8fafc);
72
- }
73
- .item.active {
74
- background: var(--md-sys-color-primary-container, rgba(37, 99, 235, 0.10));
75
- }
76
- .match-badge {
77
- flex-shrink: 0;
78
- background: var(--md-sys-color-primary-container, rgba(37, 99, 235, 0.15));
79
- color: var(--md-sys-color-on-primary-container, #1e40af);
80
- padding: 0 5px;
81
- border-radius: 3px;
82
- font-size: 9px;
83
- font-weight: 600;
84
- letter-spacing: 0.04em;
85
- min-width: 32px;
86
- text-align: center;
87
- }
88
- /* badge 가 비어있을 때 (matchType=label) — 자리는 reserve 해서 모든 행 정렬 일치 */
89
- .match-badge.invisible {
90
- visibility: hidden;
91
- }
92
- .label {
93
- flex: 1;
94
- min-width: 0;
95
- font-weight: 500;
96
- overflow: hidden;
97
- text-overflow: ellipsis;
98
- white-space: nowrap;
99
- color: var(--md-sys-color-on-surface, #0f172a);
100
- }
101
- .hint {
102
- font-size: 10px;
103
- color: var(--md-sys-color-outline, #94a3b8);
104
- flex-shrink: 0;
105
- white-space: nowrap;
106
- max-width: 45%;
107
- overflow: hidden;
108
- text-overflow: ellipsis;
109
- }
110
- .type {
111
- flex-shrink: 0;
112
- background: var(--md-sys-color-surface-container, #f1f5f9);
113
- padding: 0 5px;
114
- border-radius: 3px;
115
- font-size: 9.5px;
116
- color: var(--md-sys-color-outline, #94a3b8);
117
- letter-spacing: 0.02em;
118
- }
119
- /* 상태 footer — 'N matches' 카운터 + cap 초과 안내 */
120
- .status {
121
- padding: 3px 8px;
122
- font-size: 9.5px;
123
- color: var(--md-sys-color-outline, #94a3b8);
124
- border-top: 1px solid var(--md-sys-color-outline-variant, #e2e8f0);
125
- background: var(--md-sys-color-surface-container-low, #fafbfc);
126
- display: flex;
127
- justify-content: space-between;
128
- gap: 8px;
129
- }
130
- .more {
131
- color: var(--md-sys-color-outline, #94a3b8);
132
- }
133
- `; }
134
- render() {
135
- if (this.results.length === 0) {
136
- return html `<div class="empty">매칭 없음</div>`;
137
- }
138
- const totalShown = this.results.length;
139
- const totalAll = totalShown + this.overflow;
140
- return html `
141
- ${this.results.map((r, i) => {
142
- // 행 layout:
143
- // [matchType-badge] [type-chip] [label] [secondary hint when 의미 있을 때]
144
- // - label = 항상 사람-친화적 1차 식별 (component=id, user=name, catalog=name 등)
145
- // - secondary hint = matchValue 가 label 과 다른 경우 (예: tag/text 매칭) 또는
146
- // user 의 email 같은 부가 정보. 없으면 생략.
147
- const matchType = r.matchType;
148
- const badgeText = matchType ? MATCH_TYPE_LABEL[matchType] ?? '' : '';
149
- const label = r.candidate.label;
150
- // matchValue 가 label 과 같으면 redundant 라 hint 안 함
151
- const matchHint = r.matchValue && r.matchValue !== label ? r.matchValue : '';
152
- // user 후보이고 hint 가 비어있으면 email 을 hint 로 (보조 식별)
153
- const fallbackHint = !matchHint && r.candidate.type === 'user' && r.candidate.email !== label
154
- ? r.candidate.email ?? ''
155
- : '';
156
- const hint = matchHint || fallbackHint;
157
- return html `
158
- <div
159
- class="item ${i === this.activeIndex ? 'active' : ''}"
160
- @mouseenter=${() => this._setActive(i)}
161
- @mousedown=${(e) => this._select(e, r.candidate)}>
162
- <span class="match-badge ${badgeText ? '' : 'invisible'}"
163
- >${badgeText || '·'}</span
164
- >
165
- <span class="type">${r.candidate.type}</span>
166
- <span class="label">${label}</span>
167
- ${hint ? html `<span class="hint">${hint}</span>` : ''}
168
- </div>
169
- `;
170
- })}
171
- <div class="status">
172
- <span>${totalShown} / ${totalAll} matches</span>
173
- ${this.overflow > 0
174
- ? html `<span class="more">+${this.overflow} more — narrow query</span>`
175
- : ''}
176
- </div>
177
- `;
178
- }
179
- _select(e, candidate) {
180
- e.preventDefault(); // textarea blur 방지
181
- this.dispatchEvent(new CustomEvent('mention-select', {
182
- detail: { candidate },
183
- bubbles: true,
184
- composed: true
185
- }));
186
- }
187
- /** 마우스 hover 로 active 이동 — host 가 받아 keyboard nav 와 동일하게 처리. */
188
- _setActive(index) {
189
- if (index === this.activeIndex)
190
- return;
191
- this.dispatchEvent(new CustomEvent('mention-active-change', {
192
- detail: { index },
193
- bubbles: true,
194
- composed: true
195
- }));
196
- }
197
- /** activeIndex 가 바뀌면 해당 항목을 view 로 스크롤 — popup 의 overflow-y:auto
198
- * 영역에서 키보드 네비 시 active 가 가려지지 않도록. */
199
- updated(changed) {
200
- if (changed.has('activeIndex') || changed.has('results')) {
201
- const items = this.renderRoot.querySelectorAll('.item');
202
- const active = items[this.activeIndex];
203
- active?.scrollIntoView({ block: 'nearest' });
204
- }
205
- }
206
- };
207
- __decorate([
208
- property({ type: Array }),
209
- __metadata("design:type", Array)
210
- ], OxMentionPopup.prototype, "results", void 0);
211
- __decorate([
212
- property({ type: Number }),
213
- __metadata("design:type", Object)
214
- ], OxMentionPopup.prototype, "activeIndex", void 0);
215
- __decorate([
216
- property({ type: Number }),
217
- __metadata("design:type", Object)
218
- ], OxMentionPopup.prototype, "overflow", void 0);
219
- OxMentionPopup = __decorate([
220
- customElement('ox-mention-popup')
221
- ], OxMentionPopup);
222
- export { OxMentionPopup };
223
- //# sourceMappingURL=mention-popup.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mention-popup.js","sourceRoot":"","sources":["../../../client/components/mention-popup.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * <ox-mention-popup> — Mention 후보 리스트 popup overlay.\n *\n * board-ai-chat 의 textarea 위에 absolute 로 띄움. plain `<textarea>` + popup 분리 패턴\n * (한국어 IME 함정 회피 — contenteditable 사용 안 함).\n *\n * 키보드 네비게이션은 호스트 (board-ai-chat) 가 textarea keydown 으로 처리하고\n * activeIndex 만 동기화. 마우스 클릭은 popup 자체에서 처리.\n *\n * Pure helper (extractMentionContext / filterMentionCandidates 등) 는\n * `mention-popup-helpers.ts` 에 분리 — 단위 테스트 가능.\n */\nimport { LitElement, css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport type { FilterResult, MentionCandidate } from './mention-popup-helpers.js'\n\nexport type {\n MentionCandidate,\n FilterResult\n} from './mention-popup-helpers.js'\nexport {\n buildMentionCandidates,\n buildCatalogCandidates,\n buildSlashCandidates,\n buildUserCandidates,\n extractMentionContext,\n filterMentionCandidates,\n applyMentionSelection,\n resolveMentionToken,\n type CatalogEntry,\n type SlashTemplate,\n type ResolveMentionTokenOptions\n} from './mention-popup-helpers.js'\n\n/** match type 라벨 — things-scene SearchOverlay 의 MATCH_TYPE_LABELS 와 동일. */\nconst MATCH_TYPE_LABEL: Record<string, string> = {\n id: 'ID',\n name: 'Name',\n tag: 'Tag',\n type: 'Type',\n class: 'Class',\n text: 'Text',\n data: 'Data',\n property: 'Prop',\n description: 'Desc'\n}\n\n@customElement('ox-mention-popup')\nexport class OxMentionPopup extends LitElement {\n @property({ type: Array }) results: FilterResult[] = []\n @property({ type: Number }) activeIndex = 0\n /** filter cap 후 표시 안 된 추가 매칭 수 (\"...and N more\" 표기용) */\n @property({ type: Number }) overflow = 0\n\n static styles = css`\n :host {\n display: block;\n position: absolute;\n z-index: 1000;\n background: var(--md-sys-color-surface, #ffffff);\n border: 1px solid var(--md-sys-color-outline-variant, #e2e8f0);\n border-radius: 6px;\n box-shadow: 0 6px 18px rgba(0, 0, 0, 0.10);\n max-height: 220px;\n overflow-y: auto;\n /* 폭은 호스트가 left/right 로 결정. */\n }\n .empty {\n padding: 8px 10px;\n color: var(--md-sys-color-outline, #94a3b8);\n font-size: 11px;\n }\n /* dense 한 단일 행 — scene Finder 톤. label / hint / type-chip inline. */\n .item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n cursor: pointer;\n font-size: 11.5px;\n line-height: 1.4;\n color: var(--md-sys-color-on-surface, #0f172a);\n border-bottom: 1px solid var(--md-sys-color-outline-variant, #f1f5f9);\n }\n .item:last-child {\n border-bottom: 0;\n }\n .item:hover {\n background: var(--md-sys-color-surface-container, #f8fafc);\n }\n .item.active {\n background: var(--md-sys-color-primary-container, rgba(37, 99, 235, 0.10));\n }\n .match-badge {\n flex-shrink: 0;\n background: var(--md-sys-color-primary-container, rgba(37, 99, 235, 0.15));\n color: var(--md-sys-color-on-primary-container, #1e40af);\n padding: 0 5px;\n border-radius: 3px;\n font-size: 9px;\n font-weight: 600;\n letter-spacing: 0.04em;\n min-width: 32px;\n text-align: center;\n }\n /* badge 가 비어있을 때 (matchType=label) — 자리는 reserve 해서 모든 행 정렬 일치 */\n .match-badge.invisible {\n visibility: hidden;\n }\n .label {\n flex: 1;\n min-width: 0;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--md-sys-color-on-surface, #0f172a);\n }\n .hint {\n font-size: 10px;\n color: var(--md-sys-color-outline, #94a3b8);\n flex-shrink: 0;\n white-space: nowrap;\n max-width: 45%;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .type {\n flex-shrink: 0;\n background: var(--md-sys-color-surface-container, #f1f5f9);\n padding: 0 5px;\n border-radius: 3px;\n font-size: 9.5px;\n color: var(--md-sys-color-outline, #94a3b8);\n letter-spacing: 0.02em;\n }\n /* 상태 footer — 'N matches' 카운터 + cap 초과 안내 */\n .status {\n padding: 3px 8px;\n font-size: 9.5px;\n color: var(--md-sys-color-outline, #94a3b8);\n border-top: 1px solid var(--md-sys-color-outline-variant, #e2e8f0);\n background: var(--md-sys-color-surface-container-low, #fafbfc);\n display: flex;\n justify-content: space-between;\n gap: 8px;\n }\n .more {\n color: var(--md-sys-color-outline, #94a3b8);\n }\n `\n\n render() {\n if (this.results.length === 0) {\n return html`<div class=\"empty\">매칭 없음</div>`\n }\n const totalShown = this.results.length\n const totalAll = totalShown + this.overflow\n return html`\n ${this.results.map((r, i) => {\n // 행 layout:\n // [matchType-badge] [type-chip] [label] [secondary hint when 의미 있을 때]\n // - label = 항상 사람-친화적 1차 식별 (component=id, user=name, catalog=name 등)\n // - secondary hint = matchValue 가 label 과 다른 경우 (예: tag/text 매칭) 또는\n // user 의 email 같은 부가 정보. 없으면 생략.\n const matchType = r.matchType\n const badgeText = matchType ? MATCH_TYPE_LABEL[matchType] ?? '' : ''\n const label = r.candidate.label\n // matchValue 가 label 과 같으면 redundant 라 hint 안 함\n const matchHint = r.matchValue && r.matchValue !== label ? r.matchValue : ''\n // user 후보이고 hint 가 비어있으면 email 을 hint 로 (보조 식별)\n const fallbackHint =\n !matchHint && r.candidate.type === 'user' && r.candidate.email !== label\n ? r.candidate.email ?? ''\n : ''\n const hint = matchHint || fallbackHint\n return html`\n <div\n class=\"item ${i === this.activeIndex ? 'active' : ''}\"\n @mouseenter=${() => this._setActive(i)}\n @mousedown=${(e: MouseEvent) => this._select(e, r.candidate)}>\n <span class=\"match-badge ${badgeText ? '' : 'invisible'}\"\n >${badgeText || '·'}</span\n >\n <span class=\"type\">${r.candidate.type}</span>\n <span class=\"label\">${label}</span>\n ${hint ? html`<span class=\"hint\">${hint}</span>` : ''}\n </div>\n `\n })}\n <div class=\"status\">\n <span>${totalShown} / ${totalAll} matches</span>\n ${this.overflow > 0\n ? html`<span class=\"more\">+${this.overflow} more — narrow query</span>`\n : ''}\n </div>\n `\n }\n\n private _select(e: MouseEvent, candidate: MentionCandidate) {\n e.preventDefault() // textarea blur 방지\n this.dispatchEvent(\n new CustomEvent('mention-select', {\n detail: { candidate },\n bubbles: true,\n composed: true\n })\n )\n }\n\n /** 마우스 hover 로 active 이동 — host 가 받아 keyboard nav 와 동일하게 처리. */\n private _setActive(index: number) {\n if (index === this.activeIndex) return\n this.dispatchEvent(\n new CustomEvent('mention-active-change', {\n detail: { index },\n bubbles: true,\n composed: true\n })\n )\n }\n\n /** activeIndex 가 바뀌면 해당 항목을 view 로 스크롤 — popup 의 overflow-y:auto\n * 영역에서 키보드 네비 시 active 가 가려지지 않도록. */\n protected updated(changed: Map<string, unknown>) {\n if (changed.has('activeIndex') || changed.has('results')) {\n const items = this.renderRoot.querySelectorAll('.item')\n const active = items[this.activeIndex] as HTMLElement | undefined\n active?.scrollIntoView({ block: 'nearest' })\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ox-mention-popup': OxMentionPopup\n }\n}\n"]}
@@ -1 +0,0 @@
1
- export {};