@things-factory/board-ai 10.1.5 → 10.1.7

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 (204) 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 +39 -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 +37 -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 +7 -6
  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/translations/en.json +1 -62
  63. package/translations/ja.json +1 -61
  64. package/translations/ko.json +1 -62
  65. package/translations/ms.json +1 -61
  66. package/translations/zh.json +1 -61
  67. package/client/components/board-ai-chat.test.ts +0 -149
  68. package/client/components/board-ai-chat.ts +0 -3184
  69. package/client/components/chat-echo-dedup.test.ts +0 -230
  70. package/client/components/chat-echo-dedup.ts +0 -155
  71. package/client/components/chat-input-builder.ts +0 -69
  72. package/client/components/markdown.test.ts +0 -518
  73. package/client/components/markdown.ts +0 -508
  74. package/client/components/mention-popup-helpers.ts +0 -433
  75. package/client/components/mention-popup.test.ts +0 -588
  76. package/client/components/mention-popup.ts +0 -238
  77. package/client/utils/board-edit-patch.ts +0 -374
  78. package/dist-client/client/components/board-ai-chat.d.ts +0 -384
  79. package/dist-client/client/components/board-ai-chat.js +0 -3008
  80. package/dist-client/client/components/board-ai-chat.js.map +0 -1
  81. package/dist-client/client/components/board-ai-chat.test.d.ts +0 -1
  82. package/dist-client/client/components/board-ai-chat.test.js +0 -138
  83. package/dist-client/client/components/board-ai-chat.test.js.map +0 -1
  84. package/dist-client/client/components/chat-echo-dedup.d.ts +0 -54
  85. package/dist-client/client/components/chat-echo-dedup.js +0 -115
  86. package/dist-client/client/components/chat-echo-dedup.js.map +0 -1
  87. package/dist-client/client/components/chat-echo-dedup.test.d.ts +0 -1
  88. package/dist-client/client/components/chat-echo-dedup.test.js +0 -203
  89. package/dist-client/client/components/chat-echo-dedup.test.js.map +0 -1
  90. package/dist-client/client/components/chat-input-builder.d.ts +0 -55
  91. package/dist-client/client/components/chat-input-builder.js +0 -32
  92. package/dist-client/client/components/chat-input-builder.js.map +0 -1
  93. package/dist-client/client/components/markdown.d.ts +0 -60
  94. package/dist-client/client/components/markdown.js +0 -422
  95. package/dist-client/client/components/markdown.js.map +0 -1
  96. package/dist-client/client/components/markdown.test.d.ts +0 -1
  97. package/dist-client/client/components/markdown.test.js +0 -418
  98. package/dist-client/client/components/markdown.test.js.map +0 -1
  99. package/dist-client/client/components/mention-popup-helpers.d.ts +0 -165
  100. package/dist-client/client/components/mention-popup-helpers.js +0 -330
  101. package/dist-client/client/components/mention-popup-helpers.js.map +0 -1
  102. package/dist-client/client/components/mention-popup.d.ts +0 -35
  103. package/dist-client/client/components/mention-popup.js +0 -223
  104. package/dist-client/client/components/mention-popup.js.map +0 -1
  105. package/dist-client/client/components/mention-popup.test.d.ts +0 -1
  106. package/dist-client/client/components/mention-popup.test.js +0 -474
  107. package/dist-client/client/components/mention-popup.test.js.map +0 -1
  108. package/dist-client/client/utils/board-edit-patch.d.ts +0 -157
  109. package/dist-client/client/utils/board-edit-patch.js +0 -284
  110. package/dist-client/client/utils/board-edit-patch.js.map +0 -1
  111. package/dist-server/service/chat-message/chat-message-broadcast.d.ts +0 -13
  112. package/dist-server/service/chat-message/chat-message-broadcast.js +0 -13
  113. package/dist-server/service/chat-message/chat-message-broadcast.js.map +0 -1
  114. package/dist-server/service/chat-message/chat-message-publish.d.ts +0 -6
  115. package/dist-server/service/chat-message/chat-message-publish.js +0 -27
  116. package/dist-server/service/chat-message/chat-message-publish.js.map +0 -1
  117. package/dist-server/service/chat-message/chat-message-subscription.d.ts +0 -8
  118. package/dist-server/service/chat-message/chat-message-subscription.js +0 -53
  119. package/dist-server/service/chat-message/chat-message-subscription.js.map +0 -1
  120. package/dist-server/service/chat-message/chat-message.d.ts +0 -68
  121. package/dist-server/service/chat-message/chat-message.js +0 -172
  122. package/dist-server/service/chat-message/chat-message.js.map +0 -1
  123. package/dist-server/service/chat-message/fold-history.d.ts +0 -43
  124. package/dist-server/service/chat-message/fold-history.js +0 -33
  125. package/dist-server/service/chat-message/fold-history.js.map +0 -1
  126. package/dist-server/service/chat-message/history-summary.d.ts +0 -43
  127. package/dist-server/service/chat-message/history-summary.js +0 -77
  128. package/dist-server/service/chat-message/history-summary.js.map +0 -1
  129. package/dist-server/service/chat-message/index.d.ts +0 -5
  130. package/dist-server/service/chat-message/index.js +0 -12
  131. package/dist-server/service/chat-message/index.js.map +0 -1
  132. package/dist-server/service/chat-message/llm-history.d.ts +0 -46
  133. package/dist-server/service/chat-message/llm-history.js +0 -87
  134. package/dist-server/service/chat-message/llm-history.js.map +0 -1
  135. package/dist-server/service/chat-session/chat-session.d.ts +0 -62
  136. package/dist-server/service/chat-session/chat-session.js +0 -164
  137. package/dist-server/service/chat-session/chat-session.js.map +0 -1
  138. package/dist-server/service/chat-session/index.d.ts +0 -3
  139. package/dist-server/service/chat-session/index.js +0 -7
  140. package/dist-server/service/chat-session/index.js.map +0 -1
  141. package/dist-server/service/chat-session/session-activity-broadcast.d.ts +0 -30
  142. package/dist-server/service/chat-session/session-activity-broadcast.js +0 -34
  143. package/dist-server/service/chat-session/session-activity-broadcast.js.map +0 -1
  144. package/dist-server/service/chat-session/session-activity-publish.d.ts +0 -12
  145. package/dist-server/service/chat-session/session-activity-publish.js +0 -37
  146. package/dist-server/service/chat-session/session-activity-publish.js.map +0 -1
  147. package/dist-server/service/chat-session/session-activity-subscription.d.ts +0 -14
  148. package/dist-server/service/chat-session/session-activity-subscription.js +0 -87
  149. package/dist-server/service/chat-session/session-activity-subscription.js.map +0 -1
  150. package/dist-server/service/chat-session/session-anchor.d.ts +0 -12
  151. package/dist-server/service/chat-session/session-anchor.js +0 -20
  152. package/dist-server/service/chat-session/session-anchor.js.map +0 -1
  153. package/dist-server/service/chat-session/session-inbox.d.ts +0 -80
  154. package/dist-server/service/chat-session/session-inbox.js +0 -133
  155. package/dist-server/service/chat-session/session-inbox.js.map +0 -1
  156. package/dist-server/service/chat-session-participant/chat-session-participant.d.ts +0 -49
  157. package/dist-server/service/chat-session-participant/chat-session-participant.js +0 -141
  158. package/dist-server/service/chat-session-participant/chat-session-participant.js.map +0 -1
  159. package/dist-server/service/chat-session-participant/index.d.ts +0 -4
  160. package/dist-server/service/chat-session-participant/index.js +0 -10
  161. package/dist-server/service/chat-session-participant/index.js.map +0 -1
  162. package/dist-server/service/chat-session-participant/invite-notification.d.ts +0 -27
  163. package/dist-server/service/chat-session-participant/invite-notification.js +0 -30
  164. package/dist-server/service/chat-session-participant/invite-notification.js.map +0 -1
  165. package/dist-server/service/chat-session-participant/presence.d.ts +0 -4
  166. package/dist-server/service/chat-session-participant/presence.js +0 -22
  167. package/dist-server/service/chat-session-participant/presence.js.map +0 -1
  168. package/dist-server/service/chat-session-resolver.d.ts +0 -102
  169. package/dist-server/service/chat-session-resolver.js +0 -856
  170. package/dist-server/service/chat-session-resolver.js.map +0 -1
  171. package/dist-server/service/subscribe-auth.d.ts +0 -14
  172. package/dist-server/service/subscribe-auth.js +0 -33
  173. package/dist-server/service/subscribe-auth.js.map +0 -1
  174. package/server/service/chat-message/chat-message-broadcast.integration.test.ts +0 -73
  175. package/server/service/chat-message/chat-message-broadcast.test.ts +0 -40
  176. package/server/service/chat-message/chat-message-broadcast.ts +0 -27
  177. package/server/service/chat-message/chat-message-publish.ts +0 -22
  178. package/server/service/chat-message/chat-message-subscription.ts +0 -41
  179. package/server/service/chat-message/chat-message.ts +0 -195
  180. package/server/service/chat-message/fold-history.test.ts +0 -98
  181. package/server/service/chat-message/fold-history.ts +0 -77
  182. package/server/service/chat-message/history-summary.test.ts +0 -127
  183. package/server/service/chat-message/history-summary.ts +0 -100
  184. package/server/service/chat-message/index.ts +0 -12
  185. package/server/service/chat-message/llm-history.test.ts +0 -194
  186. package/server/service/chat-message/llm-history.ts +0 -163
  187. package/server/service/chat-session/chat-session.ts +0 -182
  188. package/server/service/chat-session/index.ts +0 -5
  189. package/server/service/chat-session/session-activity-broadcast.ts +0 -57
  190. package/server/service/chat-session/session-activity-publish.ts +0 -44
  191. package/server/service/chat-session/session-activity-subscription.ts +0 -67
  192. package/server/service/chat-session/session-anchor.ts +0 -35
  193. package/server/service/chat-session/session-inbox.test.ts +0 -185
  194. package/server/service/chat-session/session-inbox.ts +0 -161
  195. package/server/service/chat-session-participant/chat-session-participant.ts +0 -135
  196. package/server/service/chat-session-participant/index.ts +0 -6
  197. package/server/service/chat-session-participant/invite-notification.test.ts +0 -30
  198. package/server/service/chat-session-participant/invite-notification.ts +0 -48
  199. package/server/service/chat-session-participant/presence.test.ts +0 -39
  200. package/server/service/chat-session-participant/presence.ts +0 -21
  201. package/server/service/chat-session-resolver.ts +0 -779
  202. package/server/service/session-anchor.test.ts +0 -65
  203. package/server/service/subscribe-auth.test.ts +0 -57
  204. package/server/service/subscribe-auth.ts +0 -34
@@ -1,47 +1,28 @@
1
1
  /*
2
2
  * 접지 검사 — 이 대화면의 답이 **모델이 실제로 받은 것** 안에서 말했는지.
3
3
  *
4
- * ── 왜 board-ai 에 필요한가 ─────────────────────────────────────────────────
5
- * 협의 도크(operato-twin)는 board-ai 위에 서 있고, 여기서 사람들이 운영 상태를 묻는다.
6
- * 헤더 경로(twin-ai)에는 접지 가드가 있었지만 도크 경로에는 없었다 — 같은 질문에 대해
7
- * 한쪽은 검증되고 한쪽은 검증되지 않는 상태였다. 판정 규칙은 공용 모듈이 소유하고
8
- * (`@things-factory/ai-client-base` 의 grounding), 이 파일은 **무엇을 근거로 볼 것인가**만 정한다.
4
+ * ── 이 파일에 무엇이 남았나 (2026-09-10) ────────────────────────────────────
5
+ * 판정 규칙은 처음부터 `@things-factory/ai-client-base` 에 있었고, **근거집합의 모양**은 여기
6
+ * 있었다. 그래서 보드가 없는 제품은 규칙만 있고 쓸 길이 없었다 — 접지 검사를 하려면 보드
7
+ * 편집기를 지나야 했다. 자리는 있고 길이 없는 쪽이다.
9
8
  *
10
- * ── 근거집합의 정의 ─────────────────────────────────────────────────────────
11
- * 모델이 이 턴에 받은 전부다. 하나라도 빼면 정상 답이 경고를 받는다(오탐):
12
- * · systemPrompt — 생성 가능한 컴포넌트 타입 목록 등. 여기 있는 이름을 말하는 건 정상이다.
13
- * · boardContext — 현재 보드 요약(컴포넌트 id·이름). 보드를 두고 말하는 근거.
14
- * · messages — 사용자·이력 텍스트. 사용자가 말한 식별자를 되받는 건 정상이다.
15
- * · toolResults — 도구가 돌려준 원문(압축 전). 운영 상태 답의 유일한 사실 근거.
9
+ * 그 모양(`GroundingSources` · `buildGroundedCorpus`)을 공용 패키지로 옮겼다. 칸 하나가
10
+ * 바뀌었다: `boardContext` → `hostContext`. 근거는 보드일 수도, 공장 현황일 수도, 저작 중인
11
+ * 자산일 수도 있고, 그것을 아는 것은 호스트뿐이다.
12
+ *
13
+ * **베끼지 않고 옮겼다** — 같은 글이 두 곳에 있으면 한쪽만 고쳐진다. 여기 남은 것은 이 패키지의
14
+ * 소비처(9개 앱이 이 패키지를 지난다)가 이름을 그대로 쓰게 하는 재수출 하나다.
16
15
  *
17
16
  * ── 사정거리 ────────────────────────────────────────────────────────────────
18
17
  * 식별자만 본다. "지게차들이 바쁘게 움직인다" 처럼 **식별자 없이 지어낸 서술**은 잡지 못한다 —
19
18
  * 그건 도구를 부르지 않고 답한 경우이고, 도구 호출을 강제하는 별도 레버의 몫이다.
19
+ *
20
+ * 그리고 식별자 관례가 **소문자**다(`ID_TOKEN`). 대문자 식별자를 쓰는 제품(plant 의 `WO-…`,
21
+ * 트윈의 `TAG-FUNC-…`)에는 이 가드가 닿지 않는다 — 공용 패키지 쪽 판단이 필요한 별 건이다.
20
22
  */
21
- import { groundingWarnings } from '@things-factory/ai-client-base'
23
+ import { buildGroundedCorpus, groundingWarnings, type GroundingSources } from '@things-factory/ai-client-base'
22
24
 
23
- export interface GroundingSources {
24
- /** 시스템 프롬프트(타입 목록·규칙). */
25
- systemPrompt?: string
26
- /** 보드 상태 요약 등 대화 앞에 붙인 문맥. */
27
- boardContext?: string
28
- /** 사용자·어시스턴트 이력 텍스트. */
29
- messages?: string[]
30
- /** tool_result 로 회신된 원문(시간순). */
31
- toolResults?: string[]
32
- }
33
-
34
- /** 근거집합을 한 덩어리 문자열로. (id 토큰 대조만 하므로 구분자는 개행으로 충분하다.) */
35
- export function buildGroundedCorpus(sources: GroundingSources): string {
36
- return [
37
- sources.systemPrompt ?? '',
38
- sources.boardContext ?? '',
39
- ...(sources.messages ?? []),
40
- ...(sources.toolResults ?? [])
41
- ]
42
- .filter(Boolean)
43
- .join('\n')
44
- }
25
+ export { buildGroundedCorpus, type GroundingSources }
45
26
 
46
27
  /**
47
28
  * 답이 근거 밖의 식별자를 지목했으면 그 목록. 비면 접지 정상.
@@ -1,11 +1,17 @@
1
+ /*
2
+ * 대화 기계는 **`@things-factory/ai-assistant` 로 나갔다** (2026-09-10).
3
+ *
4
+ * 세션·메시지·참가자·인박스·구독은 보드가 없는 제품에도 뜻이 있다. 여기 남은 것은 보드 저작이다.
5
+ * 아래 재수출은 이 패키지를 지나는 소비처(아홉 앱)가 이름을 그대로 쓰게 한다 — 베낀 것이 아니라
6
+ * 가리키는 것이다.
7
+ *
8
+ * 자르는 선과 이유는 `things-factory/docs/design/ai-modules.md`.
9
+ */
10
+ export * from '@things-factory/ai-assistant'
11
+
1
12
  import { BoardAIChatResolver } from './board-ai-resolver.js'
2
- import { ChatSessionResolver } from './chat-session-resolver.js'
3
- import { MySessionActivitySubscription } from './chat-session/session-activity-subscription.js'
13
+ import { BoardSessionResolver } from './board-session-resolver.js'
4
14
  import { BoardPatchSubscription } from './patch-entry/board-patch-subscription.js'
5
- import { BoardChatMessageSubscription } from './chat-message/chat-message-subscription.js'
6
- import { entities as ChatSessionEntities } from './chat-session/index.js'
7
- import { entities as ChatMessageEntities } from './chat-message/index.js'
8
- import { entities as ChatSessionParticipantEntities } from './chat-session-participant/index.js'
9
15
  import { entities as PatchEntryEntities } from './patch-entry/index.js'
10
16
 
11
17
  export * from './types.js'
@@ -15,28 +21,16 @@ export * from './prefab-registry.js'
15
21
  export * from './mention-resolver.js'
16
22
  export * from './catalog-resolver.js'
17
23
  export * from './board-ai-resolver.js'
18
- export * from './chat-session-resolver.js'
19
- /* 세션 앵커 순수 로직 — 호스트가 앵커 종류를 참조할 수 있게 공개(리졸버는 데코레이터 때문에 무거움). */
20
- export * from './chat-session/session-anchor.js'
21
- export * from './chat-session/index.js'
22
- export * from './chat-message/index.js'
23
- export * from './chat-session-participant/index.js'
24
24
  export * from './patch-entry/index.js'
25
25
 
26
- export const entities = [
27
- ...ChatSessionEntities,
28
- ...ChatMessageEntities,
29
- ...ChatSessionParticipantEntities,
30
- ...PatchEntryEntities
31
- ]
26
+ /* 세션 계열 엔티티는 `ai-assistant` 가 낸다 — 프레임워크가 의존을 타고 재귀로 모은다. */
27
+ export const entities = [...PatchEntryEntities]
32
28
 
33
29
  export const schema = {
34
30
  resolverClasses: [
35
31
  BoardAIChatResolver,
36
- ChatSessionResolver,
32
+ /* 보드에 매인 op 여섯 — 중립 세션 op 과 갈랐다(2026-09-10). */
33
+ BoardSessionResolver,
37
34
  BoardPatchSubscription,
38
- BoardChatMessageSubscription,
39
- /* 내가 참여한 모든 세션의 활동 — 창을 닫아 둔 표면이 배지·목록을 갱신할 수 있게. */
40
- MySessionActivitySubscription
41
35
  ]
42
36
  }
@@ -12,7 +12,7 @@ import { filter, pipe } from 'graphql-yoga'
12
12
  import { pubsub } from '@things-factory/shell'
13
13
  import { PatchEntry } from './patch-entry.js'
14
14
  import { BOARD_PATCH_TOPIC, boardPatchFilter, type BoardPatchPayload } from './board-patch-broadcast.js'
15
- import { assertDomainSubscribeAllowed } from '../subscribe-auth.js'
15
+ import { assertDomainSubscribeAllowed } from '@things-factory/ai-assistant'
16
16
 
17
17
  export { BOARD_PATCH_TOPIC, boardPatchFilter } from './board-patch-broadcast.js'
18
18
  export type { BoardPatchPayload } from './board-patch-broadcast.js'
@@ -23,7 +23,7 @@ import { GraphQLJSON } from 'graphql-scalars'
23
23
 
24
24
  import { config } from '@things-factory/env'
25
25
 
26
- import { ChatSession } from '../chat-session/chat-session.js'
26
+ import { ChatSession } from '@things-factory/ai-assistant'
27
27
 
28
28
  const ORMCONFIG = config.get('ormconfig', {})
29
29
  const DATABASE_TYPE = ORMCONFIG.type
@@ -36,7 +36,8 @@ export class PatchEntry {
36
36
  @Field(type => ID, { nullable: true })
37
37
  readonly id?: string
38
38
 
39
- @ManyToOne(type => ChatSession, session => session.patches, { onDelete: 'CASCADE' })
39
+ /* 역방향(`ChatSession.patches`)을 두지 않는다 — 세션은 중립이고 보드 패치를 몰라야 한다. */
40
+ @ManyToOne(type => ChatSession, { onDelete: 'CASCADE' })
40
41
  session?: ChatSession
41
42
 
42
43
  @RelationId((patch: PatchEntry) => patch.session)
@@ -62,6 +62,7 @@ function toolResultsSeen(seen: any[][]): any[] {
62
62
  /* 외부 도메인 패키지를 흉내낸 카테고리 — read 는 **async**(DB 조회 대역), write 는 op 생성. */
63
63
  const CATEGORY: ToolCategory = {
64
64
  name: 'test-domain',
65
+ guidance: '- fixture guidance for test-domain',
65
66
  specs: [
66
67
  {
67
68
  kind: 'read',
@@ -27,6 +27,7 @@ import {
27
27
  /* 두 개의 가짜 외부 카테고리 — 하나는 보드 저작 계열, 하나는 운영 계열. */
28
28
  const AUTHORING: ToolCategory = {
29
29
  name: 'test-authoring',
30
+ guidance: '- fixture guidance for test-authoring',
30
31
  specs: [
31
32
  {
32
33
  kind: 'write',
@@ -39,6 +40,7 @@ const AUTHORING: ToolCategory = {
39
40
  }
40
41
  const OPS: ToolCategory = {
41
42
  name: 'test-ops',
43
+ guidance: '- fixture guidance for test-ops',
42
44
  specs: [
43
45
  {
44
46
  kind: 'read',
@@ -9,10 +9,9 @@
9
9
  */
10
10
  import type { BoardComponent, BoardModel } from '@things-factory/board-import'
11
11
 
12
- export interface LLMMessage {
13
- role: 'user' | 'assistant'
14
- content: string
15
- }
12
+ /* 대화 한 줄은 도메인을 모른다 — 정의는 `@things-factory/ai-assistant` 에 있다(2026-09-10). */
13
+ import type { LLMMessage } from '@things-factory/ai-assistant'
14
+ export type { LLMMessage }
16
15
 
17
16
  export interface ChatOptions {
18
17
  /**
@@ -1,64 +1,3 @@
1
1
  {
2
- "board-ai.label.ai": "operato",
3
- "board-ai.label.participant": "participant",
4
- "board-ai.label.create": "Create",
5
- "board-ai.label.edit": "Edit",
6
- "board-ai.label.style": "Style",
7
- "board-ai.label.korean-supported": "Korean / English",
8
- "board-ai.label.multi-command": "Batch commands",
9
- "board-ai.label.review-able": "Reviewable",
10
-
11
- "board-ai.text.empty-title": "Design a board together with AI",
12
- "board-ai.text.empty-subtitle": "Describe in natural language and AI will create, edit, and style the board. Click an example below to begin.",
13
- "board-ai.text.empty-footer-notice": "AI responses are previewed on the board and can be reverted before final apply.",
14
- "board-ai.text.input-placeholder": "Describe what you want — # component · @ catalog · / template autocomplete",
15
- "board-ai.text.triggers-heading": "Or jump in with autocomplete",
16
- "board-ai.text.trigger-component-tooltip": "Mention a component on the board",
17
- "board-ai.text.trigger-user-tooltip": "Mention a domain teammate",
18
- "board-ai.text.trigger-insert-tooltip": "Insert prefab / palette / layout / command template",
19
- "board-ai.text.send-tooltip": "Send (Enter)",
20
- "board-ai.text.show-examples-tooltip": "Show common command examples",
21
- "board-ai.text.applied-changes": "Applied.",
22
- "board-ai.text.reverted": "Reverted",
23
- "board-ai.text.failed-to-load-history": "Failed to load history",
24
- "board-ai.text.empty-response": "Empty response.",
25
-
26
- "board-ai.example.create-monitoring-dashboard": "Monitoring dashboard with 3 gauges (utilization, temperature, pressure) and a 24-hour line chart",
27
- "board-ai.example.create-welcome-screen": "Welcome screen with a large 'OPERATO' title, a clock, and a subtitle",
28
- "board-ai.example.edit-align-distribute": "Center-align the selected components and distribute evenly",
29
- "board-ai.example.edit-resize-board": "Resize the board to 1920x1080 and center the components",
30
- "board-ai.example.style-dark-mode": "Dark mode — deep navy background, white text, teal accents",
31
- "board-ai.example.style-rounded-shadow": "Round all shape corners and add a soft card shadow",
32
-
33
- "board-ai.button.new-chat": "New chat",
34
- "board-ai.label.trigger-component": "Component",
35
- "board-ai.label.trigger-user": "User",
36
- "board-ai.label.trigger-insert": "Insert",
37
- "board-ai.button.examples": "Examples",
38
- "board-ai.button.close": "Close",
39
- "board-ai.button.revert": "Revert",
40
- "board-ai.button.retry": "Retry",
41
- "board-ai.button.copy": "Copy",
42
- "board-ai.button.regenerate": "Regenerate",
43
- "board-ai.button.edit": "Edit",
44
-
45
- "board-ai.text.copied": "Copied",
46
- "board-ai.text.mention-not-found": "#{token} not found",
47
- "board-ai.text.session-tab-label": "Session {n}",
48
- "board-ai.text.tools-used": "Tools used",
49
- "board-ai.text.tool-turn": "decision {n}",
50
- "board-ai.text.tool-rejected-count": "rejected {count}",
51
- "board-ai.text.tool-folded-count": "folded {count}",
52
- "board-ai.text.outcome-ok": "read",
53
- "board-ai.text.outcome-rejected": "rejected",
54
- "board-ai.text.outcome-queued": "to apply",
55
- "board-ai.text.outcome-proposed": "proposed",
56
- "board-ai.text.outcome-folded": "duplicate",
57
- "board-ai.text.outcome-error": "error",
58
- "board-ai.text.ungrounded-mention": "Mentions an unverified target — not present in the actual data:",
59
- "board-ai.text.toggle-system-note": "click to expand",
60
- "board-ai.button.run-proposal": "run",
61
- "board-ai.text.proposal-sent": "execution requested",
62
- "board-ai.text.history-folded": "this conversation grew long — the earlier {count} messages were left out. a new conversation is better for a different topic.",
63
- "board-ai.text.history-folded-summarized": "this conversation grew long — the earlier {count} messages were folded into a summary. a new conversation is better for a different topic."
2
+ "board-ai.text.preview-before-apply": "AI responses are previewed on the board and can be reverted before final apply."
64
3
  }
@@ -1,63 +1,3 @@
1
1
  {
2
- "board-ai.label.ai": "operato",
3
- "board-ai.label.create": "作成",
4
- "board-ai.label.edit": "編集",
5
- "board-ai.label.style": "スタイル",
6
- "board-ai.label.korean-supported": "多言語対応",
7
- "board-ai.label.multi-command": "複数命令",
8
- "board-ai.label.review-able": "レビュー可能",
9
-
10
- "board-ai.text.empty-title": "AI と一緒にボードを作成しましょう",
11
- "board-ai.text.empty-subtitle": "自然言語で指示すると AI がボードを作成・編集・スタイリングします。下の例をクリックして始めてください。",
12
- "board-ai.text.empty-footer-notice": "AI の応答は適用前にプレビューで確認でき、元に戻すこともできます。",
13
- "board-ai.text.input-placeholder": "自然言語で指示してください (Shift+Enter で改行、Enter で送信)",
14
- "board-ai.text.triggers-heading": "または自動補完で素早く開始",
15
- "board-ai.text.trigger-component-tooltip": "ボードのコンポーネントをメンション",
16
- "board-ai.text.trigger-user-tooltip": "ドメイン内のメンバーをメンション",
17
- "board-ai.text.trigger-insert-tooltip": "プリファブ / パレット / レイアウト / 命令テンプレートを挿入",
18
- "board-ai.text.send-tooltip": "送信 (Enter)",
19
- "board-ai.text.show-examples-tooltip": "よく使う指示の例を表示",
20
- "board-ai.text.applied-changes": "変更しました。",
21
- "board-ai.text.reverted": "戻しました",
22
- "board-ai.text.failed-to-load-history": "履歴の読み込みに失敗",
23
- "board-ai.text.empty-response": "応答が空です。",
24
-
25
- "board-ai.example.create-monitoring-dashboard": "稼働率・温度・圧力の 3 ゲージと 24 時間のラインチャートで監視ダッシュボード",
26
- "board-ai.example.create-welcome-screen": "大きな「OPERATO」タイトルと時計、サブタイトルでウェルカム画面",
27
- "board-ai.example.edit-align-distribute": "選択したコンポーネントを中央揃えし均等配置",
28
- "board-ai.example.edit-resize-board": "ボードを 1920x1080 にしてコンポーネントを中央寄せ",
29
- "board-ai.example.style-dark-mode": "ダークモード — 濃紺の背景、白文字、ティール アクセント",
30
- "board-ai.example.style-rounded-shadow": "すべての図形を角丸にしてカード風の柔らかい影を追加",
31
-
32
- "board-ai.button.new-chat": "新しいチャット",
33
- "board-ai.label.trigger-component": "コンポーネント",
34
- "board-ai.label.trigger-user": "ユーザー",
35
- "board-ai.label.trigger-insert": "挿入",
36
- "board-ai.button.examples": "例",
37
- "board-ai.button.close": "閉じる",
38
- "board-ai.button.revert": "元に戻す",
39
- "board-ai.button.retry": "再試行",
40
- "board-ai.button.copy": "コピー",
41
- "board-ai.button.regenerate": "再生成",
42
- "board-ai.button.edit": "編集",
43
-
44
- "board-ai.text.copied": "コピーしました",
45
- "board-ai.text.mention-not-found": "#{token} が見つかりません",
46
- "board-ai.text.session-tab-label": "セッション {n}",
47
- "board-ai.text.tools-used": "使用したツール",
48
- "board-ai.text.tool-turn": "{n} 回目の判断",
49
- "board-ai.text.tool-rejected-count": "却下 {count}",
50
- "board-ai.text.tool-folded-count": "重複 {count}",
51
- "board-ai.text.outcome-ok": "照会",
52
- "board-ai.text.outcome-rejected": "却下",
53
- "board-ai.text.outcome-queued": "適用予定",
54
- "board-ai.text.outcome-proposed": "提案",
55
- "board-ai.text.outcome-folded": "重複",
56
- "board-ai.text.outcome-error": "エラー",
57
- "board-ai.text.ungrounded-mention": "確認できない対象に言及しています — 実データにありません:",
58
- "board-ai.text.toggle-system-note": "クリックで展開",
59
- "board-ai.button.run-proposal": "実行",
60
- "board-ai.text.proposal-sent": "実行を依頼しました",
61
- "board-ai.text.history-folded": "会話が長くなり、前半の {count} 件は省略されました。別の話題なら新しい会話のほうが適しています。",
62
- "board-ai.text.history-folded-summarized": "会話が長くなり、前半の {count} 件は要約にまとめられました。別の話題なら新しい会話のほうが適しています。"
2
+ "board-ai.text.preview-before-apply": "AI の応答は適用前にプレビューで確認でき、元に戻すこともできます。"
63
3
  }
@@ -1,64 +1,3 @@
1
1
  {
2
- "board-ai.label.ai": "operato",
3
- "board-ai.label.participant": "참여자",
4
- "board-ai.label.create": "생성",
5
- "board-ai.label.edit": "편집",
6
- "board-ai.label.style": "스타일",
7
- "board-ai.label.korean-supported": "한국어 자유",
8
- "board-ai.label.multi-command": "다중 명령",
9
- "board-ai.label.review-able": "검수 가능",
10
-
11
- "board-ai.text.empty-title": "AI 와 함께 보드를 만들어보세요",
12
- "board-ai.text.empty-subtitle": "자연어로 명령하시면 AI 가 보드를 생성·편집·스타일링합니다. 아래 예시를 클릭해 시작해보세요.",
13
- "board-ai.text.empty-footer-notice": "AI 응답은 항상 보드에 적용 전 미리보기로 확인 가능합니다.",
14
- "board-ai.text.input-placeholder": "자연어 명령 — # 컴포넌트 · @ 카탈로그 · / 템플릿 자동완성",
15
- "board-ai.text.triggers-heading": "또는 자동완성으로 빠르게 시작",
16
- "board-ai.text.trigger-component-tooltip": "보드의 컴포넌트를 검색해 멘션",
17
- "board-ai.text.trigger-user-tooltip": "도메인 동료를 멘션",
18
- "board-ai.text.trigger-insert-tooltip": "프리팹 / 팔레트 / 레이아웃 / 명령 템플릿 삽입",
19
- "board-ai.text.send-tooltip": "전송 (Enter)",
20
- "board-ai.text.show-examples-tooltip": "자주 쓰는 명령 예시 보기",
21
- "board-ai.text.applied-changes": "변경했습니다.",
22
- "board-ai.text.reverted": "되돌려짐",
23
- "board-ai.text.failed-to-load-history": "이력 로드 실패",
24
- "board-ai.text.empty-response": "응답이 비어있습니다.",
25
- "board-ai.text.tools-used": "도구 사용",
26
- "board-ai.text.tool-turn": "{n}번째 판단",
27
- "board-ai.text.tool-rejected-count": "거절 {count}",
28
- "board-ai.text.tool-folded-count": "접힘 {count}",
29
- "board-ai.text.outcome-ok": "조회",
30
- "board-ai.text.outcome-rejected": "거절",
31
- "board-ai.text.outcome-queued": "적용 예정",
32
- "board-ai.text.outcome-proposed": "제안",
33
- "board-ai.text.outcome-folded": "중복 접힘",
34
- "board-ai.text.outcome-error": "오류",
35
- "board-ai.text.ungrounded-mention": "확인되지 않은 대상을 언급했습니다 — 실제 데이터에 없습니다:",
36
- "board-ai.text.toggle-system-note": "눌러서 펼치기",
37
- "board-ai.button.run-proposal": "실행",
38
- "board-ai.text.proposal-sent": "실행 요청됨",
39
- "board-ai.text.history-folded": "대화가 길어져 앞부분 {count}개가 생략되었습니다. 다른 주제라면 새 대화가 낫습니다.",
40
- "board-ai.text.history-folded-summarized": "대화가 길어져 앞부분 {count}개가 요약으로 접혔습니다. 다른 주제라면 새 대화가 낫습니다.",
41
-
42
- "board-ai.example.create-monitoring-dashboard": "가동률·온도·압력 3개 게이지와 24시간 라인 차트로 모니터링 대시보드",
43
- "board-ai.example.create-welcome-screen": "큰 'OPERATO' 제목과 시계, 부제로 환영 화면",
44
- "board-ai.example.edit-align-distribute": "선택한 컴포넌트들을 가운데 정렬하고 일정 간격으로 분산",
45
- "board-ai.example.edit-resize-board": "보드 크기를 1920x1080 으로 변경하고 컴포넌트 중앙 정렬",
46
- "board-ai.example.style-dark-mode": "다크 모드 — 짙은 남색 배경, 흰색 텍스트, 청록 강조",
47
- "board-ai.example.style-rounded-shadow": "모든 도형 모서리 둥글게 + 카드형 옅은 그림자",
48
-
49
- "board-ai.button.new-chat": "새 대화",
50
- "board-ai.label.trigger-component": "컴포넌트",
51
- "board-ai.label.trigger-user": "사용자",
52
- "board-ai.label.trigger-insert": "삽입",
53
- "board-ai.button.examples": "예시",
54
- "board-ai.button.close": "닫기",
55
- "board-ai.button.revert": "되돌리기",
56
- "board-ai.button.retry": "다시 시도",
57
- "board-ai.button.copy": "복사",
58
- "board-ai.button.regenerate": "재생성",
59
- "board-ai.button.edit": "편집",
60
-
61
- "board-ai.text.copied": "복사됨",
62
- "board-ai.text.mention-not-found": "#{token} 을(를) 찾을 수 없습니다",
63
- "board-ai.text.session-tab-label": "세션 {n}"
2
+ "board-ai.text.preview-before-apply": "AI 응답은 항상 보드에 적용 전 미리보기로 확인 가능합니다."
64
3
  }
@@ -1,63 +1,3 @@
1
1
  {
2
- "board-ai.label.ai": "operato",
3
- "board-ai.label.create": "Cipta",
4
- "board-ai.label.edit": "Edit",
5
- "board-ai.label.style": "Gaya",
6
- "board-ai.label.korean-supported": "Pelbagai bahasa",
7
- "board-ai.label.multi-command": "Arahan kumpulan",
8
- "board-ai.label.review-able": "Boleh disemak",
9
-
10
- "board-ai.text.empty-title": "Reka papan bersama AI",
11
- "board-ai.text.empty-subtitle": "Terangkan dalam bahasa biasa dan AI akan mencipta, mengedit dan menggayakan papan. Klik contoh di bawah untuk bermula.",
12
- "board-ai.text.empty-footer-notice": "Respons AI dipratonton sebelum diterapkan dan boleh dibatalkan.",
13
- "board-ai.text.input-placeholder": "Terangkan dalam bahasa biasa (Shift+Enter baris baharu, Enter hantar)",
14
- "board-ai.text.triggers-heading": "Atau mula pantas dengan auto-lengkap",
15
- "board-ai.text.trigger-component-tooltip": "Sebut komponen pada papan",
16
- "board-ai.text.trigger-user-tooltip": "Sebut rakan domain",
17
- "board-ai.text.trigger-insert-tooltip": "Sisip prefab / palet / susun atur / templat arahan",
18
- "board-ai.text.send-tooltip": "Hantar (Enter)",
19
- "board-ai.text.show-examples-tooltip": "Tunjuk contoh arahan biasa",
20
- "board-ai.text.applied-changes": "Diterapkan.",
21
- "board-ai.text.reverted": "Dibatalkan",
22
- "board-ai.text.failed-to-load-history": "Gagal memuatkan sejarah",
23
- "board-ai.text.empty-response": "Respons kosong.",
24
-
25
- "board-ai.example.create-monitoring-dashboard": "Papan pemantauan dengan 3 tolok (penggunaan, suhu, tekanan) dan carta garis 24 jam",
26
- "board-ai.example.create-welcome-screen": "Skrin selamat datang dengan tajuk besar 'OPERATO', jam dan sari kata",
27
- "board-ai.example.edit-align-distribute": "Jajarkan komponen terpilih ke tengah dan agih sama rata",
28
- "board-ai.example.edit-resize-board": "Ubah saiz papan kepada 1920x1080 dan tengahkan komponen",
29
- "board-ai.example.style-dark-mode": "Mod gelap — latar biru tua, teks putih, aksen teal",
30
- "board-ai.example.style-rounded-shadow": "Bulatkan sudut semua bentuk + bayang kad lembut",
31
-
32
- "board-ai.button.new-chat": "Sembang baharu",
33
- "board-ai.label.trigger-component": "Komponen",
34
- "board-ai.label.trigger-user": "Pengguna",
35
- "board-ai.label.trigger-insert": "Sisip",
36
- "board-ai.button.examples": "Contoh",
37
- "board-ai.button.close": "Tutup",
38
- "board-ai.button.revert": "Batalkan",
39
- "board-ai.button.retry": "Cuba lagi",
40
- "board-ai.button.copy": "Salin",
41
- "board-ai.button.regenerate": "Jana semula",
42
- "board-ai.button.edit": "Edit",
43
-
44
- "board-ai.text.copied": "Disalin",
45
- "board-ai.text.mention-not-found": "#{token} tidak dijumpai",
46
- "board-ai.text.session-tab-label": "Sesi {n}",
47
- "board-ai.text.tools-used": "Alat yang digunakan",
48
- "board-ai.text.tool-turn": "keputusan {n}",
49
- "board-ai.text.tool-rejected-count": "ditolak {count}",
50
- "board-ai.text.tool-folded-count": "pendua {count}",
51
- "board-ai.text.outcome-ok": "baca",
52
- "board-ai.text.outcome-rejected": "ditolak",
53
- "board-ai.text.outcome-queued": "akan digunakan",
54
- "board-ai.text.outcome-proposed": "dicadangkan",
55
- "board-ai.text.outcome-folded": "pendua",
56
- "board-ai.text.outcome-error": "ralat",
57
- "board-ai.text.ungrounded-mention": "Menyebut sasaran yang tidak disahkan — tiada dalam data sebenar:",
58
- "board-ai.text.toggle-system-note": "klik untuk kembangkan",
59
- "board-ai.button.run-proposal": "jalankan",
60
- "board-ai.text.proposal-sent": "pelaksanaan diminta",
61
- "board-ai.text.history-folded": "perbualan ini menjadi panjang — {count} mesej terawal ditinggalkan. perbualan baharu lebih sesuai untuk topik lain.",
62
- "board-ai.text.history-folded-summarized": "perbualan ini menjadi panjang — {count} mesej terawal diringkaskan. perbualan baharu lebih sesuai untuk topik lain."
2
+ "board-ai.text.preview-before-apply": "Respons AI dipratonton sebelum diterapkan dan boleh dibatalkan."
63
3
  }
@@ -1,63 +1,3 @@
1
1
  {
2
- "board-ai.label.ai": "operato",
3
- "board-ai.label.create": "创建",
4
- "board-ai.label.edit": "编辑",
5
- "board-ai.label.style": "样式",
6
- "board-ai.label.korean-supported": "多语言",
7
- "board-ai.label.multi-command": "批量命令",
8
- "board-ai.label.review-able": "可审核",
9
-
10
- "board-ai.text.empty-title": "与 AI 一起设计看板",
11
- "board-ai.text.empty-subtitle": "用自然语言描述,AI 将创建、编辑和样式化看板。点击下方示例开始。",
12
- "board-ai.text.empty-footer-notice": "AI 的响应在应用前会先预览,并可以撤销。",
13
- "board-ai.text.input-placeholder": "用自然语言描述 (Shift+Enter 换行, Enter 发送)",
14
- "board-ai.text.triggers-heading": "或用自动完成快速开始",
15
- "board-ai.text.trigger-component-tooltip": "提及看板上的组件",
16
- "board-ai.text.trigger-user-tooltip": "提及域内同事",
17
- "board-ai.text.trigger-insert-tooltip": "插入预制 / 调色板 / 布局 / 命令模板",
18
- "board-ai.text.send-tooltip": "发送 (Enter)",
19
- "board-ai.text.show-examples-tooltip": "显示常用命令示例",
20
- "board-ai.text.applied-changes": "已应用。",
21
- "board-ai.text.reverted": "已撤销",
22
- "board-ai.text.failed-to-load-history": "加载历史失败",
23
- "board-ai.text.empty-response": "响应为空。",
24
-
25
- "board-ai.example.create-monitoring-dashboard": "用稼动率、温度、压力 3 个仪表 + 24 小时折线图制作监控看板",
26
- "board-ai.example.create-welcome-screen": "用大号 'OPERATO' 标题、时钟、副标题做欢迎画面",
27
- "board-ai.example.edit-align-distribute": "将所选组件居中对齐并均匀分布",
28
- "board-ai.example.edit-resize-board": "看板调整为 1920x1080 并将组件居中",
29
- "board-ai.example.style-dark-mode": "深色模式 — 深蓝背景、白色文字、青色强调",
30
- "board-ai.example.style-rounded-shadow": "所有图形圆角 + 柔和卡片阴影",
31
-
32
- "board-ai.button.new-chat": "新对话",
33
- "board-ai.label.trigger-component": "组件",
34
- "board-ai.label.trigger-user": "用户",
35
- "board-ai.label.trigger-insert": "插入",
36
- "board-ai.button.examples": "示例",
37
- "board-ai.button.close": "关闭",
38
- "board-ai.button.revert": "撤销",
39
- "board-ai.button.retry": "重试",
40
- "board-ai.button.copy": "复制",
41
- "board-ai.button.regenerate": "重新生成",
42
- "board-ai.button.edit": "编辑",
43
-
44
- "board-ai.text.copied": "已复制",
45
- "board-ai.text.mention-not-found": "未找到 #{token}",
46
- "board-ai.text.session-tab-label": "会话 {n}",
47
- "board-ai.text.tools-used": "使用的工具",
48
- "board-ai.text.tool-turn": "第 {n} 次判断",
49
- "board-ai.text.tool-rejected-count": "拒绝 {count}",
50
- "board-ai.text.tool-folded-count": "折叠 {count}",
51
- "board-ai.text.outcome-ok": "查询",
52
- "board-ai.text.outcome-rejected": "拒绝",
53
- "board-ai.text.outcome-queued": "待应用",
54
- "board-ai.text.outcome-proposed": "提案",
55
- "board-ai.text.outcome-folded": "重复",
56
- "board-ai.text.outcome-error": "错误",
57
- "board-ai.text.ungrounded-mention": "提到了未经确认的对象 — 实际数据中不存在:",
58
- "board-ai.text.toggle-system-note": "点击展开",
59
- "board-ai.button.run-proposal": "执行",
60
- "board-ai.text.proposal-sent": "已请求执行",
61
- "board-ai.text.history-folded": "对话变长,前面 {count} 条已省略。若是另一个话题,新建对话更合适。",
62
- "board-ai.text.history-folded-summarized": "对话变长,前面 {count} 条已折叠为摘要。若是另一个话题,新建对话更合适。"
2
+ "board-ai.text.preview-before-apply": "AI 的响应在应用前会先预览,并可以撤销。"
63
3
  }