agent-messenger 2.37.0 → 2.37.2

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 (54) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dist/package.json +1 -1
  3. package/dist/src/platforms/kakaotalk/chat-classifier.d.ts +4 -4
  4. package/dist/src/platforms/kakaotalk/chat-classifier.d.ts.map +1 -1
  5. package/dist/src/platforms/kakaotalk/chat-classifier.js +7 -3
  6. package/dist/src/platforms/kakaotalk/chat-classifier.js.map +1 -1
  7. package/dist/src/platforms/kakaotalk/client.d.ts +12 -0
  8. package/dist/src/platforms/kakaotalk/client.d.ts.map +1 -1
  9. package/dist/src/platforms/kakaotalk/client.js +122 -14
  10. package/dist/src/platforms/kakaotalk/client.js.map +1 -1
  11. package/dist/src/platforms/kakaotalk/index.d.ts +1 -0
  12. package/dist/src/platforms/kakaotalk/index.d.ts.map +1 -1
  13. package/dist/src/platforms/kakaotalk/index.js.map +1 -1
  14. package/dist/src/platforms/kakaotalk/protocol/connection.d.ts.map +1 -1
  15. package/dist/src/platforms/kakaotalk/protocol/connection.js +13 -2
  16. package/dist/src/platforms/kakaotalk/protocol/connection.js.map +1 -1
  17. package/dist/src/platforms/kakaotalk/protocol/login-response.d.ts +1 -0
  18. package/dist/src/platforms/kakaotalk/protocol/login-response.d.ts.map +1 -1
  19. package/dist/src/platforms/kakaotalk/protocol/login-response.js +1 -1
  20. package/dist/src/platforms/kakaotalk/protocol/login-response.js.map +1 -1
  21. package/dist/src/platforms/kakaotalk/types.d.ts +4 -2
  22. package/dist/src/platforms/kakaotalk/types.d.ts.map +1 -1
  23. package/dist/src/platforms/kakaotalk/types.js +6 -1
  24. package/dist/src/platforms/kakaotalk/types.js.map +1 -1
  25. package/package.json +1 -1
  26. package/skills/agent-channeltalk/SKILL.md +1 -1
  27. package/skills/agent-channeltalkbot/SKILL.md +1 -1
  28. package/skills/agent-discord/SKILL.md +1 -1
  29. package/skills/agent-discordbot/SKILL.md +1 -1
  30. package/skills/agent-imessage/SKILL.md +1 -1
  31. package/skills/agent-instagram/SKILL.md +1 -1
  32. package/skills/agent-kakaotalk/SKILL.md +1 -1
  33. package/skills/agent-line/SKILL.md +1 -1
  34. package/skills/agent-slack/SKILL.md +1 -1
  35. package/skills/agent-slackbot/SKILL.md +1 -1
  36. package/skills/agent-teams/SKILL.md +1 -1
  37. package/skills/agent-telegram/SKILL.md +1 -1
  38. package/skills/agent-telegrambot/SKILL.md +1 -1
  39. package/skills/agent-webex/SKILL.md +1 -1
  40. package/skills/agent-webexbot/SKILL.md +1 -1
  41. package/skills/agent-wechatbot/SKILL.md +1 -1
  42. package/skills/agent-whatsapp/SKILL.md +1 -1
  43. package/skills/agent-whatsappbot/SKILL.md +1 -1
  44. package/src/platforms/kakaotalk/chat-classifier.test.ts +22 -0
  45. package/src/platforms/kakaotalk/chat-classifier.ts +7 -4
  46. package/src/platforms/kakaotalk/client.test.ts +638 -4
  47. package/src/platforms/kakaotalk/client.ts +156 -15
  48. package/src/platforms/kakaotalk/index.test.ts +27 -0
  49. package/src/platforms/kakaotalk/index.ts +5 -0
  50. package/src/platforms/kakaotalk/protocol/connection.test.ts +87 -0
  51. package/src/platforms/kakaotalk/protocol/connection.ts +15 -2
  52. package/src/platforms/kakaotalk/protocol/login-response.test.ts +13 -2
  53. package/src/platforms/kakaotalk/protocol/login-response.ts +1 -1
  54. package/src/platforms/kakaotalk/types.ts +10 -2
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-messenger",
3
- "version": "2.37.0",
3
+ "version": "2.37.2",
4
4
  "description": "Messaging platform interaction skills for AI agents. Interact with Slack, Discord, Microsoft Teams, Webex, Telegram, Telegram Bot, WhatsApp, LINE, iMessage, Instagram, KakaoTalk, and Channel Talk - send messages, read channels, manage reactions, upload files, and more through simple CLI interfaces.",
5
5
  "author": {
6
6
  "name": "agent-messenger",
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-messenger",
3
- "version": "2.37.0",
3
+ "version": "2.37.2",
4
4
  "description": "Multi-platform messaging CLI for AI agents (Slack, Discord, Teams, Webex, Telegram, Telegram Bot, WhatsApp, LINE, iMessage, Instagram, KakaoTalk, Channel Talk)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,4 +1,4 @@
1
- import type { KakaoChat, KakaoOpenChatType } from './types.js';
1
+ import { type KakaoChat, type KakaoOpenChatType } from './types.js';
2
2
  export type KakaoChatKind = 'dm' | 'group' | 'open' | 'unknown';
3
3
  export declare function isOpenKakaoChatType(type: unknown): type is KakaoOpenChatType;
4
4
  /**
@@ -11,9 +11,9 @@ export declare function isOpenKakaoChatType(type: unknown): type is KakaoOpenCha
11
11
  * NOT "simplify" this back to a pure type-code mapping without verifying
12
12
  * against a real KakaoTalk session.
13
13
  *
14
- * `'unknown'` is reserved for future protocol drift; the current heuristic
15
- * never returns it, but it is part of the union so consumers can handle
16
- * the case defensively.
14
+ * `'unknown'` is reserved for future string protocol drift so consumers fail
15
+ * closed instead of silently classifying an unrecognized server value by
16
+ * member count.
17
17
  */
18
18
  export declare function classifyKakaoChat(chat: Pick<KakaoChat, 'type' | 'active_members'>): KakaoChatKind;
19
19
  //# sourceMappingURL=chat-classifier.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-classifier.d.ts","sourceRoot":"","sources":["../../../../src/platforms/kakaotalk/chat-classifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAE3D,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;AAO/D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,iBAAiB,CAE5E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAAC,GAAG,aAAa,CAMjG"}
1
+ {"version":3,"file":"chat-classifier.d.ts","sourceRoot":"","sources":["../../../../src/platforms/kakaotalk/chat-classifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAE5F,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;AAO/D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,iBAAiB,CAE5E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAAC,GAAG,aAAa,CASjG"}
@@ -1,3 +1,4 @@
1
+ import { isKnownKakaoChatStringType } from './types.js';
1
2
  // OpenChat-family `type` values observed on the wire. Login/chat-list data
2
3
  // uses numeric codes while CHATINFO may return the protocol string tags
3
4
  // `OM` / `OD`; both forms must share this single classification owner.
@@ -15,13 +16,16 @@ export function isOpenKakaoChatType(type) {
15
16
  * NOT "simplify" this back to a pure type-code mapping without verifying
16
17
  * against a real KakaoTalk session.
17
18
  *
18
- * `'unknown'` is reserved for future protocol drift; the current heuristic
19
- * never returns it, but it is part of the union so consumers can handle
20
- * the case defensively.
19
+ * `'unknown'` is reserved for future string protocol drift so consumers fail
20
+ * closed instead of silently classifying an unrecognized server value by
21
+ * member count.
21
22
  */
22
23
  export function classifyKakaoChat(chat) {
23
24
  if (isOpenKakaoChatType(chat.type))
24
25
  return 'open';
26
+ if (typeof chat.type === 'string' && !isKnownKakaoChatStringType(chat.type)) {
27
+ return 'unknown';
28
+ }
25
29
  // active_members counts the logged-in user, so a 1:1 DM is exactly 2
26
30
  // (self + one other) and a "lone" room with only self is 1.
27
31
  if (chat.active_members <= 2)
@@ -1 +1 @@
1
- {"version":3,"file":"chat-classifier.js","sourceRoot":"","sources":["../../../../src/platforms/kakaotalk/chat-classifier.ts"],"names":[],"mappings":"AAIA,2EAA2E;AAC3E,wEAAwE;AACxE,uEAAuE;AACvE,MAAM,eAAe,GAAmC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;AAEhG,MAAM,UAAU,mBAAmB,CAAC,IAAa;IAC/C,OAAO,eAAe,CAAC,GAAG,CAAC,IAAyB,CAAC,CAAA;AACvD,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAgD;IAChF,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,MAAM,CAAA;IACjD,qEAAqE;IACrE,4DAA4D;IAC5D,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IACzC,OAAO,OAAO,CAAA;AAChB,CAAC"}
1
+ {"version":3,"file":"chat-classifier.js","sourceRoot":"","sources":["../../../../src/platforms/kakaotalk/chat-classifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAA0C,MAAM,SAAS,CAAA;AAI5F,2EAA2E;AAC3E,wEAAwE;AACxE,uEAAuE;AACvE,MAAM,eAAe,GAAmC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;AAEhG,MAAM,UAAU,mBAAmB,CAAC,IAAa;IAC/C,OAAO,eAAe,CAAC,GAAG,CAAC,IAAyB,CAAC,CAAA;AACvD,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAgD;IAChF,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,MAAM,CAAA;IACjD,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5E,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,qEAAqE;IACrE,4DAA4D;IAC5D,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IACzC,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -13,12 +13,21 @@ export type KakaoSessionEvent = {
13
13
  };
14
14
  export type KakaoPushHandler = (packet: LocoPacket) => void;
15
15
  export type KakaoSessionEventHandler = (event: KakaoSessionEvent) => void;
16
+ export type KakaoTalkResponseFailureKind = 'provider_rejection' | 'transient_or_unknown';
17
+ export type KakaoTalkResponseStatusSource = 'packet' | 'body';
18
+ export type KakaoTalkGetChatFailureReason = 'provider_rejection' | 'synthetic_connection_close' | 'chat_info_absent' | 'transport_or_unknown';
16
19
  export declare class KakaoTalkError extends Error {
17
20
  code: string;
18
21
  readonly serverStatus?: number;
22
+ readonly responseFailureKind?: KakaoTalkResponseFailureKind;
23
+ readonly responseStatusSource?: KakaoTalkResponseStatusSource;
24
+ readonly getChatFailureReason?: KakaoTalkGetChatFailureReason;
19
25
  constructor(message: string, code: string, options?: {
20
26
  cause?: unknown;
21
27
  serverStatus?: number;
28
+ responseFailureKind?: KakaoTalkResponseFailureKind;
29
+ responseStatusSource?: KakaoTalkResponseStatusSource;
30
+ getChatFailureReason?: KakaoTalkGetChatFailureReason;
22
31
  });
23
32
  }
24
33
  export declare class KakaoTalkClient {
@@ -66,6 +75,9 @@ export declare class KakaoTalkClient {
66
75
  * Unlike `getChats()`, this does not depend on the login-time snapshot or
67
76
  * LCHATLIST pagination, so a room first observed from a live push can be
68
77
  * resolved without interpreting protocol fields outside this SDK.
78
+ * The returned chat type preserves numeric values and non-empty protocol
79
+ * strings, including DirectChat, MultiChat, PlusChat, MemoChat, OM, and OD;
80
+ * unknown non-empty strings are preserved for forward compatibility.
69
81
  */
70
82
  getChat(chatId: string): Promise<KakaoChat>;
71
83
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/platforms/kakaotalk/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/platforms/kakaotalk/client.ts"],"names":[],"mappings":"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"}
@@ -9,17 +9,36 @@ import { isOpenKakaoChatType } from './chat-classifier.js';
9
9
  import { detectImageDimensions } from './image-meta.js';
10
10
  import { sha1Hex } from './media-upload.js';
11
11
  import { LANG, PC_OS_NAME, getLocoDeviceConfig } from './protocol/config.js';
12
+ import { isSyntheticConnectionClose } from './protocol/login-response.js';
12
13
  import { uploadMediaToLoco, uploadMultiMediaEntry } from './protocol/media-uploader.js';
13
14
  import { LocoSession } from './protocol/session.js';
14
15
  import { KAKAO_MESSAGE_TYPE, } from './types.js';
15
16
  export class KakaoTalkError extends Error {
16
17
  code;
17
18
  serverStatus;
19
+ responseFailureKind;
20
+ responseStatusSource;
21
+ getChatFailureReason;
18
22
  constructor(message, code, options) {
19
23
  super(message, options);
20
24
  this.name = 'KakaoTalkError';
21
25
  this.code = code;
22
26
  this.serverStatus = options?.serverStatus;
27
+ this.responseFailureKind = options?.responseFailureKind;
28
+ this.responseStatusSource = options?.responseStatusSource;
29
+ this.getChatFailureReason = options?.getChatFailureReason;
30
+ }
31
+ }
32
+ class LocoResponseError extends Error {
33
+ serverStatus;
34
+ responseFailureKind;
35
+ responseStatusSource;
36
+ constructor(message, responseFailureKind, options) {
37
+ super(message);
38
+ this.name = 'LocoResponseError';
39
+ this.serverStatus = options?.serverStatus;
40
+ this.responseFailureKind = responseFailureKind;
41
+ this.responseStatusSource = options?.responseStatusSource;
23
42
  }
24
43
  }
25
44
  class MemberNameCache {
@@ -76,6 +95,19 @@ function bsonToLong(v) {
76
95
  }
77
96
  return undefined;
78
97
  }
98
+ // LCHATLIST cursor fields (lastTokenId/lastChatId) arrive as plain numbers when the
99
+ // value fits in a safe integer, because bson promotes them, and as { low, high }
100
+ // otherwise. bsonToLong only accepts the object form, so a numeric cursor became
101
+ // undefined and getChatList() re-requested the first page until MAX_PAGES.
102
+ // Kept separate from bsonToLong on purpose: its other callers (log ids, open link
103
+ // ids) rely on a numeric 0 staying absent rather than becoming a Long.
104
+ function cursorToLong(v) {
105
+ if (typeof v === 'number' && Number.isSafeInteger(v))
106
+ return Long.fromNumber(v);
107
+ if (typeof v === 'bigint')
108
+ return Long.fromBigInt(v);
109
+ return bsonToLong(v);
110
+ }
79
111
  function longToString(v) {
80
112
  if (v && typeof v === 'object' && 'high' in v && 'low' in v) {
81
113
  const { high, low } = v;
@@ -142,7 +174,7 @@ function formatChat(chat, title, nameCache) {
142
174
  const chatId = longToString(chat.c);
143
175
  return {
144
176
  chat_id: chatId,
145
- type: chat.t,
177
+ type: requiredChatType(chat.t),
146
178
  display_name: displayName,
147
179
  title,
148
180
  active_members: chat.a,
@@ -185,7 +217,7 @@ function requiredNonNegativeInteger(value, field) {
185
217
  return value;
186
218
  }
187
219
  function requiredChatType(value) {
188
- if (typeof value === 'string' && isOpenKakaoChatType(value)) {
220
+ if (typeof value === 'string' && value.length > 0) {
189
221
  return value;
190
222
  }
191
223
  return requiredNonNegativeInteger(value, 'type');
@@ -267,11 +299,39 @@ function collectChats(chatDatas, into, seen) {
267
299
  }
268
300
  }
269
301
  }
270
- function wrapError(error, code) {
271
- if (error instanceof KakaoTalkError)
272
- return error;
302
+ function wrapError(error, code, options) {
303
+ if (error instanceof KakaoTalkError) {
304
+ const responseFailureKind = error.responseFailureKind ?? (options?.classifyResponseFailure ? 'transient_or_unknown' : undefined);
305
+ const getChatFailureReason = error.getChatFailureReason ?? (options?.classifyGetChatFailure ? 'transport_or_unknown' : undefined);
306
+ if (responseFailureKind === error.responseFailureKind && getChatFailureReason === error.getChatFailureReason) {
307
+ return error;
308
+ }
309
+ return new KakaoTalkError(error.message, error.code, {
310
+ cause: error.cause ?? error,
311
+ serverStatus: error.serverStatus,
312
+ responseFailureKind,
313
+ responseStatusSource: error.responseStatusSource,
314
+ getChatFailureReason,
315
+ });
316
+ }
273
317
  const message = error instanceof Error ? error.message : String(error);
274
- return new KakaoTalkError(message, code, { cause: error });
318
+ return new KakaoTalkError(message, code, {
319
+ cause: error,
320
+ serverStatus: error instanceof LocoResponseError ? error.serverStatus : undefined,
321
+ responseStatusSource: error instanceof LocoResponseError ? error.responseStatusSource : undefined,
322
+ responseFailureKind: error instanceof LocoResponseError
323
+ ? error.responseFailureKind
324
+ : options?.classifyResponseFailure
325
+ ? 'transient_or_unknown'
326
+ : undefined,
327
+ getChatFailureReason: options?.classifyGetChatFailure
328
+ ? error instanceof LocoResponseError && error.responseFailureKind === 'provider_rejection'
329
+ ? 'provider_rejection'
330
+ : error instanceof LocoResponseError && error.responseStatusSource === 'packet' && error.serverStatus === -1
331
+ ? 'synthetic_connection_close'
332
+ : 'transport_or_unknown'
333
+ : undefined,
334
+ });
275
335
  }
276
336
  function isLoginResponseError(error) {
277
337
  if (!(error instanceof Error))
@@ -393,12 +453,27 @@ function isNonZeroLong(v) {
393
453
  // caller-visible error channel (e.g. GETMEM/MEMBER return `[]` for both empty rooms and dead
394
454
  // sockets). Throwing here lets executeWithReconnect detect session death and reconnect.
395
455
  function assertLocoOk(response, command) {
456
+ if (typeof response.statusCode !== 'number' || !Number.isFinite(response.statusCode)) {
457
+ throw new LocoResponseError(`${command} failed: response status unavailable`, 'transient_or_unknown');
458
+ }
459
+ if (isSyntheticConnectionClose(response)) {
460
+ throw new LocoResponseError(`${command} failed: connection closed`, 'transient_or_unknown', {
461
+ serverStatus: response.statusCode,
462
+ responseStatusSource: 'packet',
463
+ });
464
+ }
396
465
  if (response.statusCode !== 0) {
397
- throw new Error(`${command} failed: statusCode=${response.statusCode}`);
466
+ throw new LocoResponseError(`${command} failed: statusCode=${response.statusCode}`, 'provider_rejection', {
467
+ serverStatus: response.statusCode,
468
+ responseStatusSource: 'packet',
469
+ });
398
470
  }
399
471
  const bodyStatus = response.body.status;
400
472
  if (typeof bodyStatus === 'number' && bodyStatus !== 0) {
401
- throw new Error(`${command} failed: body.status=${bodyStatus}`);
473
+ throw new LocoResponseError(`${command} failed: body.status=${bodyStatus}`, 'provider_rejection', {
474
+ serverStatus: bodyStatus,
475
+ responseStatusSource: 'body',
476
+ });
402
477
  }
403
478
  }
404
479
  function formatMember(member) {
@@ -767,6 +842,7 @@ export class KakaoTalkClient {
767
842
  if (options?.all || options?.search || snapshotEmpty) {
768
843
  let cursor = loginResult;
769
844
  let pages = 0;
845
+ const requireCompleteList = options?.all === true;
770
846
  while (pages < MAX_PAGES) {
771
847
  // Trust eof only when the snapshot had data. When the snapshot was empty
772
848
  // (new device), ignore eof for the first iteration so we always attempt
@@ -775,17 +851,29 @@ export class KakaoTalkClient {
775
851
  break;
776
852
  if (cursor.eof && snapshotEmpty && pages > 0)
777
853
  break;
778
- const lastTokenId = bsonToLong(cursor.lastTokenId);
779
- const lastChatId = bsonToLong(cursor.lastChatId);
854
+ const lastTokenId = cursorToLong(cursor.lastTokenId);
855
+ const lastChatId = cursorToLong(cursor.lastChatId);
780
856
  const response = await session.getChatList(lastTokenId, lastChatId);
857
+ if (requireCompleteList)
858
+ assertLocoOk(response, 'LCHATLIST');
781
859
  const body = response.body;
860
+ if (requireCompleteList && !Array.isArray(body.chatDatas)) {
861
+ throw new Error('LCHATLIST pagination incomplete: chatDatas unavailable');
862
+ }
782
863
  const chatDatas = (body.chatDatas ?? []);
783
- if (chatDatas.length === 0)
864
+ cursor = body;
865
+ pages++;
866
+ if (chatDatas.length === 0) {
867
+ if (requireCompleteList && body.eof !== true) {
868
+ throw new Error('LCHATLIST pagination incomplete: empty non-EOF page');
869
+ }
784
870
  break;
871
+ }
785
872
  collectChats(chatDatas, allChats, seenChatIds);
786
873
  this.nameCache.ingest(chatDatas);
787
- cursor = body;
788
- pages++;
874
+ }
875
+ if (requireCompleteList && cursor.eof !== true) {
876
+ throw new Error(`LCHATLIST pagination incomplete after ${pages} pages`);
789
877
  }
790
878
  }
791
879
  allChats.sort((a, b) => (b.o ?? 0) - (a.o ?? 0));
@@ -809,6 +897,9 @@ export class KakaoTalkClient {
809
897
  * Unlike `getChats()`, this does not depend on the login-time snapshot or
810
898
  * LCHATLIST pagination, so a room first observed from a live push can be
811
899
  * resolved without interpreting protocol fields outside this SDK.
900
+ * The returned chat type preserves numeric values and non-empty protocol
901
+ * strings, including DirectChat, MultiChat, PlusChat, MemoChat, OM, and OD;
902
+ * unknown non-empty strings are preserved for forward compatibility.
812
903
  */
813
904
  async getChat(chatId) {
814
905
  const parsedChatId = parseChatId(chatId);
@@ -818,6 +909,20 @@ export class KakaoTalkClient {
818
909
  const response = await session.getChannelInfo(parsedChatId);
819
910
  assertLocoOk(response, 'CHATINFO');
820
911
  const body = response.body;
912
+ const chatInfo = body.chatInfo;
913
+ const isLeftChatInfo = chatInfo !== null &&
914
+ typeof chatInfo === 'object' &&
915
+ !Array.isArray(chatInfo) &&
916
+ chatInfo.left === true;
917
+ if (isLeftChatInfo) {
918
+ extractChannelInfo(body, normalizedChatId);
919
+ }
920
+ if (chatInfo === undefined || chatInfo === null || isLeftChatInfo) {
921
+ throw new KakaoTalkError('CHATINFO response missing chatInfo', 'get_chat_failed', {
922
+ responseFailureKind: 'transient_or_unknown',
923
+ getChatFailureReason: 'chat_info_absent',
924
+ });
925
+ }
821
926
  const chat = channelInfoToChatData(body, normalizedChatId);
822
927
  this.nameCache.ingest([chat]);
823
928
  let title = extractTitle(body);
@@ -836,7 +941,10 @@ export class KakaoTalkClient {
836
941
  return formatChat(chat, title, this.nameCache);
837
942
  }
838
943
  catch (error) {
839
- throw wrapError(error, 'get_chat_failed');
944
+ throw wrapError(error, 'get_chat_failed', {
945
+ classifyResponseFailure: true,
946
+ classifyGetChatFailure: true,
947
+ });
840
948
  }
841
949
  });
842
950
  }