@things-factory/ai-assistant 10.1.81 → 10.1.87

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 (33) hide show
  1. package/client/components/assistant-dock.ts +46 -0
  2. package/client/components/assistant-session-manager.ts +7 -2
  3. package/client/utils/assistant-session-controller.ts +2 -0
  4. package/client/utils/assistant-session-transport.ts +2 -2
  5. package/dist-client/components/assistant-dock.d.ts +3 -0
  6. package/dist-client/components/assistant-dock.js +46 -0
  7. package/dist-client/components/assistant-dock.js.map +1 -1
  8. package/dist-client/components/assistant-session-manager.js +7 -2
  9. package/dist-client/components/assistant-session-manager.js.map +1 -1
  10. package/dist-client/tsconfig.tsbuildinfo +1 -1
  11. package/dist-client/utils/assistant-session-controller.d.ts +2 -0
  12. package/dist-client/utils/assistant-session-controller.js.map +1 -1
  13. package/dist-client/utils/assistant-session-transport.js +2 -2
  14. package/dist-client/utils/assistant-session-transport.js.map +1 -1
  15. package/dist-server/service/chat-session/chat-session.d.ts +5 -5
  16. package/dist-server/service/chat-session/chat-session.js.map +1 -1
  17. package/dist-server/service/chat-session/session-visibility.d.ts +8 -5
  18. package/dist-server/service/chat-session/session-visibility.js +9 -15
  19. package/dist-server/service/chat-session/session-visibility.js.map +1 -1
  20. package/dist-server/service/chat-session-resolver.js +1 -1
  21. package/dist-server/service/chat-session-resolver.js.map +1 -1
  22. package/dist-server/tsconfig.tsbuildinfo +1 -1
  23. package/package.json +2 -2
  24. package/server/service/chat-session/chat-session.ts +5 -5
  25. package/server/service/chat-session/session-visibility.test.ts +6 -6
  26. package/server/service/chat-session/session-visibility.ts +9 -15
  27. package/server/service/chat-session-resolver.ts +1 -1
  28. package/server/service/session-anchor.test.ts +2 -2
  29. package/translations/en.json +2 -1
  30. package/translations/ja.json +2 -1
  31. package/translations/ko.json +2 -1
  32. package/translations/ms.json +2 -1
  33. package/translations/zh.json +2 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/ai-assistant",
3
- "version": "10.1.81",
3
+ "version": "10.1.87",
4
4
  "main": "dist-server/index.js",
5
5
  "things-factory": true,
6
6
  "author": "heartyoh",
@@ -51,5 +51,5 @@
51
51
  "copyfiles": "^2.4.1",
52
52
  "rimraf": "^5.0.0"
53
53
  },
54
- "gitHead": "0c4f91d92c8214a9b2eca6690a7ed48bd2d828cc"
54
+ "gitHead": "dc552c2a7b7f97e3377a26c378ee15d3a1de612a"
55
55
  }
@@ -146,12 +146,12 @@ export class ChatSession {
146
146
  * `open` 도메인 안이면 누구나 들어와 읽고 말한다. 초대 절차는 없다.
147
147
  * `private` 참여자만 읽는다.
148
148
  *
149
- * 앵커가 있는 세션(space · board · station)은 공유된 무엇을 놓고 하는 이야기이므로 `open` 으로
150
- * 시작한다. 앵커가 없는 세션과 **옮겨 적어 만든 세션**은 `private` 으로 시작한다 — 가벼운 질문을
151
- * 승격하면서 앞선 대화가 새 세션에 옮겨 적히는데(`appendSessionTurns`), 그것이 공개로 태어나면
152
- * 사적으로 오간 원문이 소급해서 공개된다.
149
+ * 새 세션은 **모두** `private` 으로 시작한다(2026-09-30 — `initialVisibility`). 앵커는 무엇에 대한
150
+ * 이야기인지를 말할 뿐 누구에게 보이는지를 정하지 않는다. 칸의 기본값 `open` 은 칸이 서기 전의 옛 행을
151
+ * 그날까지의 규칙대로 읽기 위한 것이고, 새 행은 늘 값을 적는다.
153
152
  *
154
- * owner 가 양방향으로 바꿀 수 있다. 공개로 바꾸기 전에 화면이 한 줄을 먼저 보인다.
153
+ * owner 가 양방향으로 바꿀 수 있다. 공개로 바꾸기 전에 화면이 한 줄을 먼저 보이고, 공개 대화는 도크가
154
+ * 다르게 그린다.
155
155
  *
156
156
  * open 이어도 답 행의 문 판정(ADR-0073 판정 1)은 그대로다 — 방에 들어온 것과 값을 읽는 것은 다르다.
157
157
  */
@@ -6,10 +6,10 @@
6
6
  import { initialVisibility, mayReadSession } from './session-visibility'
7
7
 
8
8
  describe('session visibility', () => {
9
- it('앵커가 있는 대화는 공개로 시작한다 — 공유된 대상을 놓고 하는 이야기다', () => {
10
- expect(initialVisibility({ anchorType: 'space' })).toBe('open')
11
- expect(initialVisibility({ anchorType: 'board' })).toBe('open')
12
- expect(initialVisibility({ anchorType: 'station' })).toBe('open')
9
+ it('★ 앵커가 있어도 비공개로 시작한다 — 앵커는 무엇에 대한 이야기인지이지 누구에게 보이는지가 아니다', () => {
10
+ for (const anchorType of ['space', 'board', 'station', 'application', 'domain', 'subject', 'figure', 'instance']) {
11
+ expect(initialVisibility({ anchorType })).toBe('private')
12
+ }
13
13
  })
14
14
 
15
15
  it('★ 옮겨 적어 만든 대화는 비공개로 시작한다 — 원문이 소급 공개되지 않는다', () => {
@@ -46,8 +46,8 @@ describe("'none' is not an anchor", () => {
46
46
  expect(initialVisibility({ anchorType: 'none' })).toBe('private')
47
47
  })
48
48
 
49
- it('대상이 있는 대화는 그대로 공개다', () => {
50
- expect(initialVisibility({ anchorType: 'space' })).toBe('open')
49
+ it('대상이 있는 대화도 비공개다', () => {
50
+ expect(initialVisibility({ anchorType: 'space' })).toBe('private')
51
51
  })
52
52
  })
53
53
 
@@ -9,23 +9,17 @@ export type SessionVisibility = 'open' | 'private'
9
9
  export const SESSION_VISIBILITIES: readonly SessionVisibility[] = ['open', 'private']
10
10
 
11
11
  /**
12
- * 이렇게 만들어진 세션은 무엇으로 시작하나.
12
+ * 이렇게 만들어진 세션은 무엇으로 시작하나 — **언제나 비공개.**
13
13
  *
14
- * 앵커가 있으면 공유된 대상을 놓고 하는 이야기다 — 공개. 앵커가 없거나 앞선 대화를 옮겨 적어 만든
15
- * 것이면 비공개. `copyOf` 가 있다는 것은 다른 대화의 원문이 이 안에 들어왔다는 뜻이고, 그 원문은
16
- * 자기가 있던 자리의 규칙으로 쓰였다.
14
+ * ── 앵커가 있으면 공개로 태어나던 것을 거둔 이유 (2026-09-30, 제품 오너) ──
15
+ * operato-office 의 대화는 앱 행(`application`)에 매달린다. 그래서 원장 · 급여를 묻는 경영자의 질문이 도메인
16
+ * 안 모든 직원에게 열린 방으로 태어났다. 목록은 그것을 「사업장 공개」 한 줄로만 말해서 공개와 비공개가 한눈에
17
+ * 갈리지 않았다. 앵커는 「무엇에 대한 이야기인가」이지 「누구에게 보이나」가 아니다.
18
+ *
19
+ * 공개는 owner 가 고른다(`setSessionVisibility`) — 화면이 여는 순간 되묻고, 공개 대화는 도크가 다르게 그린다.
17
20
  */
18
- export function initialVisibility(session: { anchorType?: string | null; copyOf?: string | null }): SessionVisibility {
19
- if (session.copyOf) return 'private'
20
-
21
- /*
22
- * `'none'` 은 **앵커가 아니다.** 저장되는 앵커 종류 목록에 그 글자가 들어 있어서(`session-anchor.ts`
23
- * — 대상이 없다는 것도 행에 적어야 하므로), 「값이 있으면 앵커가 있다」로 읽으면 대상 없는 개인 질문이
24
- * 공개 방으로 태어난다. ADR-0073 결정 2 가 그것을 `private` 로 못박았다 — 「앵커 없는 세션(`twin.none`
25
- * 같은 개인 질문)」.
26
- */
27
- const anchored = !!session.anchorType && session.anchorType !== 'none'
28
- return anchored ? 'open' : 'private'
21
+ export function initialVisibility(_session: { anchorType?: string | null; copyOf?: string | null } = {}): SessionVisibility {
22
+ return 'private'
29
23
  }
30
24
 
31
25
  /** 이 사람이 이 대화를 읽을 수 있나. open 이면 도메인 안 누구나, private 이면 참여자만. */
@@ -658,7 +658,7 @@ export class ChatSessionResolver {
658
658
  const session = await repo.save({
659
659
  domain,
660
660
  ...anchorColumns(anchorType, anchorId),
661
- /* 앵커가 있는 대화는 공개로 태어난다 — ADR-0073 판정 2. */
661
+ /* 새 대화는 비공개로 태어난다 — 공개는 owner 가 고른다(ADR-0073 결정 2, 2026-09-30 고침). */
662
662
  visibility: initialVisibility({ anchorType }),
663
663
  creator: user,
664
664
  updater: user
@@ -192,7 +192,7 @@ describe('the subject anchor', () => {
192
192
  expect(anchorColumns('application', 'operato-figure').anchorId).toBe('operato-figure')
193
193
  })
194
194
 
195
- it('★ a subject conversation is born open — an anchored conversation is about a shared thing (ADR-0073 decision 2)', () => {
196
- expect(initialVisibility({ anchorType: 'subject' })).toBe('open')
195
+ it('★ a subject conversation is born private — opening it is the owner\'s choice (ADR-0073 decision 2, 2026-09-30)', () => {
196
+ expect(initialVisibility({ anchorType: 'subject' })).toBe('private')
197
197
  })
198
198
  })
@@ -196,5 +196,6 @@
196
196
  "ai-assistant.session.filter-open": "Public",
197
197
  "ai-assistant.session.filter-private": "Private",
198
198
  "ai-assistant.session.filter-unread": "Unread",
199
- "ai-assistant.dock.ask-needs-conversation": "the question was not sent."
199
+ "ai-assistant.dock.ask-needs-conversation": "the question was not sent.",
200
+ "ai-assistant.dock.audience-open-band": "Public conversation - everyone in this domain can read and write here."
200
201
  }
@@ -196,5 +196,6 @@
196
196
  "ai-assistant.session.filter-open": "公開",
197
197
  "ai-assistant.session.filter-private": "非公開",
198
198
  "ai-assistant.session.filter-unread": "未読",
199
- "ai-assistant.dock.ask-needs-conversation": "質問は送信されませんでした。"
199
+ "ai-assistant.dock.ask-needs-conversation": "質問は送信されませんでした。",
200
+ "ai-assistant.dock.audience-open-band": "公開会話 — この事業所の誰でも読み書きできます。"
200
201
  }
@@ -196,5 +196,6 @@
196
196
  "ai-assistant.session.filter-open": "공개",
197
197
  "ai-assistant.session.filter-private": "비공개",
198
198
  "ai-assistant.session.filter-unread": "안 읽음",
199
- "ai-assistant.dock.ask-needs-conversation": "질문을 보내지 않았습니다."
199
+ "ai-assistant.dock.ask-needs-conversation": "질문을 보내지 않았습니다.",
200
+ "ai-assistant.dock.audience-open-band": "공개 대화 — 이 사업장의 누구나 읽고 쓸 수 있습니다."
200
201
  }
@@ -196,5 +196,6 @@
196
196
  "ai-assistant.session.filter-open": "Awam",
197
197
  "ai-assistant.session.filter-private": "Peribadi",
198
198
  "ai-assistant.session.filter-unread": "Belum dibaca",
199
- "ai-assistant.dock.ask-needs-conversation": "soalan tidak dihantar."
199
+ "ai-assistant.dock.ask-needs-conversation": "soalan tidak dihantar.",
200
+ "ai-assistant.dock.audience-open-band": "Perbualan awam - sesiapa dalam domain ini boleh membaca dan menulis di sini."
200
201
  }
@@ -196,5 +196,6 @@
196
196
  "ai-assistant.session.filter-open": "公开",
197
197
  "ai-assistant.session.filter-private": "私密",
198
198
  "ai-assistant.session.filter-unread": "未读",
199
- "ai-assistant.dock.ask-needs-conversation": "问题未发送。"
199
+ "ai-assistant.dock.ask-needs-conversation": "问题未发送。",
200
+ "ai-assistant.dock.audience-open-band": "公开对话 — 本工作区的任何人都可以阅读和发言。"
200
201
  }