korbus-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +251 -0
  3. package/dist/bus/gateway.d.ts +11 -0
  4. package/dist/bus/gateway.d.ts.map +1 -0
  5. package/dist/bus/gateway.js +36 -0
  6. package/dist/bus/gateway.js.map +1 -0
  7. package/dist/bus/gyeonggi.d.ts +9 -0
  8. package/dist/bus/gyeonggi.d.ts.map +1 -0
  9. package/dist/bus/gyeonggi.js +69 -0
  10. package/dist/bus/gyeonggi.js.map +1 -0
  11. package/dist/bus/seoul.d.ts +9 -0
  12. package/dist/bus/seoul.d.ts.map +1 -0
  13. package/dist/bus/seoul.js +72 -0
  14. package/dist/bus/seoul.js.map +1 -0
  15. package/dist/db.d.ts +55 -0
  16. package/dist/db.d.ts.map +1 -0
  17. package/dist/db.js +409 -0
  18. package/dist/db.js.map +1 -0
  19. package/dist/errors.d.ts +21 -0
  20. package/dist/errors.d.ts.map +1 -0
  21. package/dist/errors.js +71 -0
  22. package/dist/errors.js.map +1 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +55 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/notifier/console.d.ts +3 -0
  28. package/dist/notifier/console.d.ts.map +1 -0
  29. package/dist/notifier/console.js +4 -0
  30. package/dist/notifier/console.js.map +1 -0
  31. package/dist/notifier/dispatcher.d.ts +11 -0
  32. package/dist/notifier/dispatcher.d.ts.map +1 -0
  33. package/dist/notifier/dispatcher.js +28 -0
  34. package/dist/notifier/dispatcher.js.map +1 -0
  35. package/dist/notifier/telegram.d.ts +3 -0
  36. package/dist/notifier/telegram.d.ts.map +1 -0
  37. package/dist/notifier/telegram.js +14 -0
  38. package/dist/notifier/telegram.js.map +1 -0
  39. package/dist/notifier/webhook.d.ts +3 -0
  40. package/dist/notifier/webhook.d.ts.map +1 -0
  41. package/dist/notifier/webhook.js +6 -0
  42. package/dist/notifier/webhook.js.map +1 -0
  43. package/dist/openclaw/dispatcher.d.ts +10 -0
  44. package/dist/openclaw/dispatcher.d.ts.map +1 -0
  45. package/dist/openclaw/dispatcher.js +50 -0
  46. package/dist/openclaw/dispatcher.js.map +1 -0
  47. package/dist/openclaw/index.d.ts +21 -0
  48. package/dist/openclaw/index.d.ts.map +1 -0
  49. package/dist/openclaw/index.js +39 -0
  50. package/dist/openclaw/index.js.map +1 -0
  51. package/dist/openclaw/service.d.ts +11 -0
  52. package/dist/openclaw/service.d.ts.map +1 -0
  53. package/dist/openclaw/service.js +28 -0
  54. package/dist/openclaw/service.js.map +1 -0
  55. package/dist/openclaw/tools.d.ts +27 -0
  56. package/dist/openclaw/tools.d.ts.map +1 -0
  57. package/dist/openclaw/tools.js +318 -0
  58. package/dist/openclaw/tools.js.map +1 -0
  59. package/dist/scheduler.d.ts +15 -0
  60. package/dist/scheduler.d.ts.map +1 -0
  61. package/dist/scheduler.js +106 -0
  62. package/dist/scheduler.js.map +1 -0
  63. package/dist/tools/alarm.d.ts +3 -0
  64. package/dist/tools/alarm.d.ts.map +1 -0
  65. package/dist/tools/alarm.js +118 -0
  66. package/dist/tools/alarm.js.map +1 -0
  67. package/dist/tools/arrival.d.ts +4 -0
  68. package/dist/tools/arrival.d.ts.map +1 -0
  69. package/dist/tools/arrival.js +37 -0
  70. package/dist/tools/arrival.js.map +1 -0
  71. package/dist/tools/helpers.d.ts +14 -0
  72. package/dist/tools/helpers.d.ts.map +1 -0
  73. package/dist/tools/helpers.js +14 -0
  74. package/dist/tools/helpers.js.map +1 -0
  75. package/dist/tools/poll.d.ts +4 -0
  76. package/dist/tools/poll.d.ts.map +1 -0
  77. package/dist/tools/poll.js +17 -0
  78. package/dist/tools/poll.js.map +1 -0
  79. package/dist/tools/search.d.ts +4 -0
  80. package/dist/tools/search.d.ts.map +1 -0
  81. package/dist/tools/search.js +26 -0
  82. package/dist/tools/search.js.map +1 -0
  83. package/dist/types.d.ts +117 -0
  84. package/dist/types.d.ts.map +1 -0
  85. package/dist/types.js +16 -0
  86. package/dist/types.js.map +1 -0
  87. package/package.json +73 -0
  88. package/prisma/migrations/20260303085107_init/migration.sql +62 -0
  89. package/prisma/migrations/20260303120821_add_once_alarm_fields/migration.sql +22 -0
  90. package/prisma/migrations/migration_lock.toml +3 -0
  91. package/prisma/schema.prisma +72 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/notifier/dispatcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAM7C,MAAM,UAAU,gBAAgB,CAAC,MAAsC;IACrE,MAAM,gBAAgB,GAAG,MAAM,EAAE,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC;IAE1F,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO;YAC7B,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC/B,WAAW,CAAC,OAAO,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YAED,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;gBAC/C,IAAI,CAAC,GAAG,CAAC,GAAG;oBAAE,OAAO;gBACrB,MAAM,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBACpC,OAAO;YACT,CAAC;YAED,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;gBAC/C,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,gBAAgB;oBAAE,OAAO;gBAC7C,MAAM,YAAY,CAAC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { NotificationPayload } from '../types.js';
2
+ export declare function sendTelegram(botToken: string, chatId: string, payload: NotificationPayload): Promise<void>;
3
+ //# sourceMappingURL=telegram.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram.d.ts","sourceRoot":"","sources":["../../src/notifier/telegram.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAYvD,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAKf"}
@@ -0,0 +1,14 @@
1
+ import axios from 'axios';
2
+ const client = axios.create({ timeout: 10000 });
3
+ function formatMessage(payload) {
4
+ return (`Bus ${payload.routeName} → ${payload.stationName}\n` +
5
+ `${payload.arrivalMsg} (${payload.arrivalSec}s)\n` +
6
+ `Vehicle: ${payload.vehicleId}`);
7
+ }
8
+ export async function sendTelegram(botToken, chatId, payload) {
9
+ await client.post(`https://api.telegram.org/bot${botToken}/sendMessage`, {
10
+ chat_id: chatId,
11
+ text: formatMessage(payload),
12
+ });
13
+ }
14
+ //# sourceMappingURL=telegram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../src/notifier/telegram.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AAEhD,SAAS,aAAa,CAAC,OAA4B;IACjD,OAAO,CACL,OAAO,OAAO,CAAC,SAAS,MAAM,OAAO,CAAC,WAAW,IAAI;QACrD,GAAG,OAAO,CAAC,UAAU,KAAK,OAAO,CAAC,UAAU,MAAM;QAClD,YAAY,OAAO,CAAC,SAAS,EAAE,CAChC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAAgB,EAChB,MAAc,EACd,OAA4B;IAE5B,MAAM,MAAM,CAAC,IAAI,CAAC,+BAA+B,QAAQ,cAAc,EAAE;QACvE,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC;KAC7B,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { NotificationPayload } from '../types.js';
2
+ export declare function sendWebhook(url: string, payload: NotificationPayload): Promise<void>;
3
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/notifier/webhook.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAIvD,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1F"}
@@ -0,0 +1,6 @@
1
+ import axios from 'axios';
2
+ const client = axios.create({ timeout: 10000 });
3
+ export async function sendWebhook(url, payload) {
4
+ await client.post(url, payload);
5
+ }
6
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/notifier/webhook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,OAA4B;IACzE,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Dispatcher } from '../notifier/dispatcher.js';
2
+ export interface OpenClawRuntimeApi {
3
+ logger: {
4
+ info(msg: string): void;
5
+ warn(msg: string): void;
6
+ error(msg: string): void;
7
+ };
8
+ }
9
+ export declare function createOpenClawDispatcher(api: OpenClawRuntimeApi): Dispatcher;
10
+ //# sourceMappingURL=dispatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/openclaw/dispatcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAS5D,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE;QAAE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CACxF;AAwBD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,GAAG,UAAU,CAgC5E"}
@@ -0,0 +1,50 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ const execFileAsync = promisify(execFile);
4
+ // ---------------------------------------------------------------------------
5
+ // Helpers
6
+ // ---------------------------------------------------------------------------
7
+ function formatMessage(p) {
8
+ return `🚌 ${p.routeName} → ${p.stationName}\n${p.arrivalMsg}`;
9
+ }
10
+ /** Extract recipient ID from a channel config JSON string. */
11
+ function parseTarget(configJson) {
12
+ try {
13
+ const cfg = JSON.parse(configJson || '{}');
14
+ return cfg.to ?? cfg.chatId ?? cfg.channelId ?? undefined;
15
+ }
16
+ catch {
17
+ return undefined;
18
+ }
19
+ }
20
+ // ---------------------------------------------------------------------------
21
+ // Dispatcher
22
+ // ---------------------------------------------------------------------------
23
+ export function createOpenClawDispatcher(api) {
24
+ return {
25
+ async dispatch(channel, payload) {
26
+ const text = formatMessage(payload);
27
+ if (channel.type === 'CONSOLE') {
28
+ api.logger.info(`[KorBus] ${text}`);
29
+ return;
30
+ }
31
+ const target = parseTarget(channel.config);
32
+ if (!target) {
33
+ api.logger.warn(`[KorBus] No target for channel ${channel.type}, skipping dispatch`);
34
+ return;
35
+ }
36
+ try {
37
+ await execFileAsync('openclaw', [
38
+ 'message', 'send',
39
+ '--channel', channel.type.toLowerCase(),
40
+ '--target', target,
41
+ '--message', `[KorBus 알림] ${text}`,
42
+ ]);
43
+ }
44
+ catch (err) {
45
+ api.logger.error(`[KorBus] dispatch failed (${channel.type}): ${err instanceof Error ? err.message : String(err)}`);
46
+ }
47
+ },
48
+ };
49
+ }
50
+ //# sourceMappingURL=dispatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/openclaw/dispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAItC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAU1C,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,SAAS,aAAa,CAAC,CAAsB;IAC3C,OAAO,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;AACjE,CAAC;AAED,8DAA8D;AAC9D,SAAS,WAAW,CAAC,UAAkB;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC;QAC3C,OAAO,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,SAAS,IAAI,SAAS,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,MAAM,UAAU,wBAAwB,CAAC,GAAuB;IAC9D,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO;YAC7B,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;YAEpC,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC/B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;gBACpC,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,kCAAkC,OAAO,CAAC,IAAI,qBAAqB,CACpE,CAAC;gBACF,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,aAAa,CAAC,UAAU,EAAE;oBAC9B,SAAS,EAAE,MAAM;oBACjB,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE;oBACvC,UAAU,EAAE,MAAM;oBAClB,WAAW,EAAE,eAAe,IAAI,EAAE;iBACnC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,MAAM,CAAC,KAAK,CACd,6BAA6B,OAAO,CAAC,IAAI,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAClG,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { type OpenClawRuntimeApi } from './dispatcher.js';
2
+ interface PluginAPI extends OpenClawRuntimeApi {
3
+ pluginConfig: Record<string, unknown>;
4
+ stateDir: string;
5
+ registerTool(tool: unknown, options?: {
6
+ optional?: boolean;
7
+ }): void;
8
+ registerService(service: {
9
+ id: string;
10
+ start?: () => void | Promise<void>;
11
+ stop?: () => void | Promise<void>;
12
+ }): void;
13
+ }
14
+ declare const plugin: {
15
+ id: string;
16
+ name: string;
17
+ description: string;
18
+ register(api: PluginAPI): void;
19
+ };
20
+ export default plugin;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/openclaw/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAA4B,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAIpF,UAAU,SAAU,SAAQ,kBAAkB;IAC5C,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACpE,eAAe,CAAC,OAAO,EAAE;QACvB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KACnC,GAAG,IAAI,CAAC;CACV;AAuBD,QAAA,MAAM,MAAM;;;;kBAMI,SAAS;CAmBxB,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -0,0 +1,39 @@
1
+ import path from 'node:path';
2
+ import { createBusGateway } from '../bus/gateway.js';
3
+ import { createOpenClawDispatcher } from './dispatcher.js';
4
+ import { registerKorbusTools } from './tools.js';
5
+ import { createKorbusService } from './service.js';
6
+ function readConfig(api) {
7
+ const cfg = api.pluginConfig ?? {};
8
+ const apiKey = cfg.apiKey ||
9
+ process.env.KORBUS_DATA_API_KEY ||
10
+ '';
11
+ const seoulApiKey = apiKey;
12
+ const gyeonggiApiKey = apiKey;
13
+ const stateDir = api.stateDir || path.join(process.env.HOME || '/tmp', '.openclaw');
14
+ const databasePath = cfg.databasePath ||
15
+ path.join(stateDir, 'korbus.db');
16
+ const databaseUrl = `file:${databasePath}`;
17
+ const pollEnabled = cfg.pollEnabled ?? true;
18
+ return { seoulApiKey, gyeonggiApiKey, databaseUrl, pollEnabled };
19
+ }
20
+ const plugin = {
21
+ id: 'korbus-mcp',
22
+ name: 'KorBus',
23
+ description: 'Korean bus arrival info, alarms, and notifications for Seoul and Gyeonggi',
24
+ register(api) {
25
+ const config = readConfig(api);
26
+ const gateway = createBusGateway({
27
+ seoulApiKey: config.seoulApiKey,
28
+ gyeonggiApiKey: config.gyeonggiApiKey,
29
+ });
30
+ const dispatcher = createOpenClawDispatcher(api);
31
+ registerKorbusTools(api, { gateway, dispatcher });
32
+ api.registerService(createKorbusService({ gateway, dispatcher }, {
33
+ pollEnabled: config.pollEnabled,
34
+ databaseUrl: config.databaseUrl,
35
+ }));
36
+ },
37
+ };
38
+ export default plugin;
39
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/openclaw/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,wBAAwB,EAA2B,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAanD,SAAS,UAAU,CAAC,GAAc;IAChC,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;IAEnC,MAAM,MAAM,GACT,GAAG,CAAC,MAAiB;QACtB,OAAO,CAAC,GAAG,CAAC,mBAAmB;QAC/B,EAAE,CAAC;IACL,MAAM,WAAW,GAAG,MAAM,CAAC;IAC3B,MAAM,cAAc,GAAG,MAAM,CAAC;IAE9B,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,WAAW,CAAC,CAAC;IACpF,MAAM,YAAY,GACf,GAAG,CAAC,YAAuB;QAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACnC,MAAM,WAAW,GAAG,QAAQ,YAAY,EAAE,CAAC;IAE3C,MAAM,WAAW,GAAI,GAAG,CAAC,WAAuB,IAAI,IAAI,CAAC;IAEzD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,MAAM,GAAG;IACb,EAAE,EAAE,YAAY;IAChB,IAAI,EAAE,QAAQ;IACd,WAAW,EACT,2EAA2E;IAE7E,QAAQ,CAAC,GAAc;QACrB,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAE/B,MAAM,OAAO,GAAG,gBAAgB,CAAC;YAC/B,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,cAAc,EAAE,MAAM,CAAC,cAAc;SACtC,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;QAEjD,mBAAmB,CAAC,GAAU,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;QAEzD,GAAG,CAAC,eAAe,CACjB,mBAAmB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE;YAC3C,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,WAAW,EAAE,MAAM,CAAC,WAAW;SAChC,CAAC,CACH,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type PollDeps } from '../scheduler.js';
2
+ export interface KorbusServiceConfig {
3
+ pollEnabled: boolean;
4
+ databaseUrl?: string;
5
+ }
6
+ export declare function createKorbusService(deps: PollDeps, config: KorbusServiceConfig): {
7
+ id: string;
8
+ start(): Promise<void>;
9
+ stop(): Promise<void>;
10
+ };
11
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/openclaw/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,mBAAmB;;;;EA6B5B"}
@@ -0,0 +1,28 @@
1
+ import { initDb, closeDb } from '../db.js';
2
+ import { startScheduler } from '../scheduler.js';
3
+ export function createKorbusService(deps, config) {
4
+ let stopScheduler = null;
5
+ return {
6
+ id: 'korbus',
7
+ async start() {
8
+ if (config.databaseUrl) {
9
+ process.env.DATABASE_URL = config.databaseUrl;
10
+ }
11
+ await initDb();
12
+ console.error('[korbus] database initialized');
13
+ if (config.pollEnabled) {
14
+ stopScheduler = startScheduler(deps);
15
+ console.error('[korbus] scheduler started');
16
+ }
17
+ },
18
+ async stop() {
19
+ if (stopScheduler) {
20
+ stopScheduler();
21
+ stopScheduler = null;
22
+ }
23
+ await closeDb();
24
+ console.error('[korbus] stopped');
25
+ },
26
+ };
27
+ }
28
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/openclaw/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAiB,MAAM,iBAAiB,CAAC;AAOhE,MAAM,UAAU,mBAAmB,CACjC,IAAc,EACd,MAA2B;IAE3B,IAAI,aAAa,GAAwB,IAAI,CAAC;IAE9C,OAAO;QACL,EAAE,EAAE,QAAQ;QAEZ,KAAK,CAAC,KAAK;YACT,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,MAAM,CAAC,WAAW,CAAC;YAChD,CAAC;YACD,MAAM,MAAM,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;YAE/C,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACvB,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;gBACrC,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QAED,KAAK,CAAC,IAAI;YACR,IAAI,aAAa,EAAE,CAAC;gBAClB,aAAa,EAAE,CAAC;gBAChB,aAAa,GAAG,IAAI,CAAC;YACvB,CAAC;YACD,MAAM,OAAO,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { type TSchema } from '@sinclair/typebox';
2
+ import type { BusGateway } from '../bus/gateway.js';
3
+ import type { Dispatcher } from '../notifier/dispatcher.js';
4
+ interface ToolResult {
5
+ content: {
6
+ type: 'text';
7
+ text: string;
8
+ }[];
9
+ }
10
+ interface ToolDefinition {
11
+ name: string;
12
+ description: string;
13
+ parameters: TSchema;
14
+ execute: (toolCallId: string, params: Record<string, unknown>, signal?: AbortSignal) => Promise<ToolResult>;
15
+ }
16
+ interface PluginAPI {
17
+ registerTool(tool: ToolDefinition, options?: {
18
+ optional?: boolean;
19
+ }): void;
20
+ }
21
+ export interface ToolDeps {
22
+ gateway: BusGateway;
23
+ dispatcher: Dispatcher;
24
+ }
25
+ export declare function registerKorbusTools(api: PluginAPI, deps: ToolDeps): void;
26
+ export {};
27
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/openclaw/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAoB5D,UAAU,UAAU;IAClB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3C;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,CACP,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,CAAC,EAAE,WAAW,KACjB,OAAO,CAAC,UAAU,CAAC,CAAC;CAC1B;AAED,UAAU,SAAS;IACjB,YAAY,CACV,IAAI,EAAE,cAAc,EACpB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAC/B,IAAI,CAAC;CACT;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,UAAU,CAAC;CACxB;AAiED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAiTxE"}
@@ -0,0 +1,318 @@
1
+ import { Type } from '@sinclair/typebox';
2
+ import { upsertStations, upsertRoutes, findStationById, listAlarms, createAlarm, createOnceAlarm, findAlarm, updateAlarm, deleteAlarm, } from '../db.js';
3
+ import { pollActiveAlarms } from '../scheduler.js';
4
+ import { CoreError, toCoreError } from '../errors.js';
5
+ // ---------------------------------------------------------------------------
6
+ // Helpers
7
+ // ---------------------------------------------------------------------------
8
+ function textResult(data) {
9
+ return {
10
+ content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
11
+ };
12
+ }
13
+ function errorResult(error) {
14
+ const coreError = toCoreError(error);
15
+ return {
16
+ content: [{ type: 'text', text: JSON.stringify(coreError.toJSON(), null, 2) }],
17
+ };
18
+ }
19
+ // ---------------------------------------------------------------------------
20
+ // Shared schemas
21
+ // ---------------------------------------------------------------------------
22
+ const DayOfWeekEnum = Type.Unsafe({
23
+ type: 'string',
24
+ enum: ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'],
25
+ });
26
+ const ScheduleSchema = Type.Object({
27
+ dayOfWeek: Type.Array(DayOfWeekEnum),
28
+ startTime: Type.String({ pattern: '^\\d{2}:\\d{2}$' }),
29
+ endTime: Type.String({ pattern: '^\\d{2}:\\d{2}$' }),
30
+ });
31
+ const ChannelSchema = Type.Union([
32
+ Type.Object({
33
+ type: Type.Literal('CONSOLE'),
34
+ config: Type.Optional(Type.Object({}, { additionalProperties: false })),
35
+ }),
36
+ Type.Object({
37
+ type: Type.Literal('WEBHOOK'),
38
+ config: Type.Object({ url: Type.String({ format: 'uri' }) }),
39
+ }),
40
+ Type.Object({
41
+ type: Type.Literal('TELEGRAM'),
42
+ config: Type.Optional(Type.Object({ chatId: Type.String({ minLength: 1 }) })),
43
+ }),
44
+ Type.Object({
45
+ type: Type.Literal('DISCORD'),
46
+ config: Type.Optional(Type.Object({ channelId: Type.String({ minLength: 1 }) })),
47
+ }),
48
+ Type.Object({
49
+ type: Type.Literal('SLACK'),
50
+ config: Type.Optional(Type.Object({ channelId: Type.String({ minLength: 1 }) })),
51
+ }),
52
+ Type.Object({
53
+ type: Type.Literal('SIGNAL'),
54
+ config: Type.Optional(Type.Object({ to: Type.String({ minLength: 1 }) })),
55
+ }),
56
+ ]);
57
+ // ---------------------------------------------------------------------------
58
+ // Tool registration
59
+ // ---------------------------------------------------------------------------
60
+ export function registerKorbusTools(api, deps) {
61
+ // ── search_stations ──
62
+ api.registerTool({
63
+ name: 'korbus_search_stations',
64
+ description: 'Search bus stations by name (Seoul + Gyeonggi) and cache results',
65
+ parameters: Type.Object({
66
+ query: Type.String({ minLength: 1, description: 'Station name to search' }),
67
+ }),
68
+ async execute(_id, params) {
69
+ try {
70
+ const stations = await deps.gateway.searchStations(params.query.trim());
71
+ const saved = await upsertStations(stations);
72
+ return textResult(saved);
73
+ }
74
+ catch (error) {
75
+ return errorResult(error);
76
+ }
77
+ },
78
+ }, { optional: true });
79
+ // ── search_routes ──
80
+ api.registerTool({
81
+ name: 'korbus_search_routes',
82
+ description: 'Search bus routes by name/number (Seoul + Gyeonggi) and cache results',
83
+ parameters: Type.Object({
84
+ query: Type.String({ minLength: 1, description: 'Route name/number to search' }),
85
+ }),
86
+ async execute(_id, params) {
87
+ try {
88
+ const routes = await deps.gateway.searchRoutes(params.query.trim());
89
+ const saved = await upsertRoutes(routes);
90
+ return textResult(saved);
91
+ }
92
+ catch (error) {
93
+ return errorResult(error);
94
+ }
95
+ },
96
+ }, { optional: true });
97
+ // ── get_arrivals ──
98
+ api.registerTool({
99
+ name: 'korbus_get_arrivals',
100
+ description: 'Get real-time bus arrival info for a station (optionally filtered by route)',
101
+ parameters: Type.Object({
102
+ station_id: Type.String({
103
+ minLength: 1,
104
+ description: 'Station ID (from korbus_search_stations)',
105
+ }),
106
+ route_id: Type.Optional(Type.String({ description: 'Route ID to filter (from korbus_search_routes)' })),
107
+ }),
108
+ async execute(_id, params) {
109
+ try {
110
+ const stationRef = await findStationById(params.station_id);
111
+ if (!stationRef) {
112
+ throw new CoreError({
113
+ code: 'NOT_FOUND',
114
+ message: `Station not found: ${params.station_id}. Use korbus_search_stations first.`,
115
+ retryable: false,
116
+ });
117
+ }
118
+ const arrivals = await deps.gateway.getArrivals(stationRef, params.route_id);
119
+ // Auto-cache routes discovered via arrivals
120
+ const seen = new Set();
121
+ const routes = arrivals.flatMap((a) => {
122
+ if (seen.has(a.routeId))
123
+ return [];
124
+ seen.add(a.routeId);
125
+ return [{ id: a.routeId, name: a.routeName, region: stationRef.region }];
126
+ });
127
+ if (routes.length)
128
+ await upsertRoutes(routes);
129
+ return textResult(arrivals);
130
+ }
131
+ catch (error) {
132
+ return errorResult(error);
133
+ }
134
+ },
135
+ }, { optional: true });
136
+ // ── list_alarms ──
137
+ api.registerTool({
138
+ name: 'korbus_list_alarms',
139
+ description: 'List all registered bus alarms',
140
+ parameters: Type.Object({}),
141
+ async execute() {
142
+ try {
143
+ const alarms = await listAlarms();
144
+ return textResult(alarms);
145
+ }
146
+ catch (error) {
147
+ return errorResult(error);
148
+ }
149
+ },
150
+ }, { optional: true });
151
+ // ── create_alarm ──
152
+ api.registerTool({
153
+ name: 'korbus_create_alarm',
154
+ description: 'Create a recurring bus arrival alarm (notifications delivered via OpenClaw)',
155
+ parameters: Type.Object({
156
+ station_id: Type.String({ minLength: 1, description: 'Station ID' }),
157
+ route_id: Type.String({ minLength: 1, description: 'Route ID' }),
158
+ label: Type.Optional(Type.String({ description: 'Label for this alarm' })),
159
+ alert_minutes: Type.Integer({
160
+ minimum: 1,
161
+ maximum: 30,
162
+ description: 'Alert when bus is within N minutes',
163
+ }),
164
+ schedules: Type.Array(ScheduleSchema, { description: 'When to monitor' }),
165
+ channel: Type.String({
166
+ description: 'Notification channel (e.g. telegram, discord, slack). Use the current conversation channel if not specified by user.',
167
+ }),
168
+ to: Type.String({
169
+ description: 'Recipient ID (e.g. chat ID, channel ID). Use the current conversation target if not specified by user.',
170
+ }),
171
+ }),
172
+ async execute(_id, params) {
173
+ try {
174
+ const alarm = await createAlarm({
175
+ stationId: params.station_id,
176
+ routeId: params.route_id,
177
+ label: params.label,
178
+ alertMinutes: params.alert_minutes,
179
+ schedules: params.schedules,
180
+ channels: [{ type: params.channel, config: { to: params.to } }],
181
+ });
182
+ return textResult(alarm);
183
+ }
184
+ catch (error) {
185
+ return errorResult(error);
186
+ }
187
+ },
188
+ }, { optional: true });
189
+ // ── create_once_alarm ──
190
+ api.registerTool({
191
+ name: 'korbus_create_once_alarm',
192
+ description: 'Create a one-time bus arrival alarm that fires once then expires (notifications delivered via OpenClaw)',
193
+ parameters: Type.Object({
194
+ station_id: Type.String({ minLength: 1, description: 'Station ID' }),
195
+ route_id: Type.String({ minLength: 1, description: 'Route ID' }),
196
+ label: Type.Optional(Type.String({ description: 'Label for this alarm' })),
197
+ alert_minutes: Type.Integer({
198
+ minimum: 1,
199
+ maximum: 30,
200
+ description: 'Alert when bus is within N minutes',
201
+ }),
202
+ active_until: Type.Optional(Type.String({
203
+ description: 'Monitor until this time (HH:mm or ISO datetime). Omit to monitor indefinitely until fired.',
204
+ })),
205
+ channel: Type.String({
206
+ description: 'Notification channel (e.g. telegram, discord, slack). Use the current conversation channel if not specified by user.',
207
+ }),
208
+ to: Type.String({
209
+ description: 'Recipient ID (e.g. chat ID, channel ID). Use the current conversation target if not specified by user.',
210
+ }),
211
+ }),
212
+ async execute(_id, params) {
213
+ try {
214
+ const alarm = await createOnceAlarm({
215
+ stationId: params.station_id,
216
+ routeId: params.route_id,
217
+ label: params.label,
218
+ alertMinutes: params.alert_minutes,
219
+ activeUntil: params.active_until,
220
+ channels: [{ type: params.channel, config: { to: params.to } }],
221
+ });
222
+ return textResult(alarm);
223
+ }
224
+ catch (error) {
225
+ return errorResult(error);
226
+ }
227
+ },
228
+ }, { optional: true });
229
+ // ── update_alarm ──
230
+ api.registerTool({
231
+ name: 'korbus_update_alarm',
232
+ description: 'Update an existing bus alarm',
233
+ parameters: Type.Object({
234
+ alarm_id: Type.String({ minLength: 1, description: 'Alarm ID to update' }),
235
+ patch: Type.Object({
236
+ label: Type.Optional(Type.String()),
237
+ alertMinutes: Type.Optional(Type.Integer({ minimum: 1, maximum: 30 })),
238
+ enabled: Type.Optional(Type.Boolean()),
239
+ schedules: Type.Optional(Type.Array(ScheduleSchema)),
240
+ channels: Type.Optional(Type.Array(ChannelSchema)),
241
+ }),
242
+ }),
243
+ async execute(_id, params) {
244
+ try {
245
+ const alarmId = params.alarm_id;
246
+ const existing = await findAlarm(alarmId);
247
+ if (!existing) {
248
+ throw new CoreError({
249
+ code: 'NOT_FOUND',
250
+ message: `Alarm not found: ${alarmId}`,
251
+ retryable: false,
252
+ });
253
+ }
254
+ const updated = await updateAlarm(alarmId, params.patch);
255
+ return textResult(updated);
256
+ }
257
+ catch (error) {
258
+ return errorResult(error);
259
+ }
260
+ },
261
+ }, { optional: true });
262
+ // ── delete_alarm ──
263
+ api.registerTool({
264
+ name: 'korbus_delete_alarm',
265
+ description: 'Delete a bus alarm (confirm=true required)',
266
+ parameters: Type.Object({
267
+ alarm_id: Type.String({ minLength: 1, description: 'Alarm ID to delete' }),
268
+ confirm: Type.Boolean({ description: 'Must be true to confirm deletion' }),
269
+ }),
270
+ async execute(_id, params) {
271
+ try {
272
+ if (!params.confirm) {
273
+ throw new CoreError({
274
+ code: 'VALIDATION_ERROR',
275
+ message: 'confirm=true is required to delete an alarm',
276
+ retryable: false,
277
+ });
278
+ }
279
+ const alarmId = params.alarm_id;
280
+ const existing = await findAlarm(alarmId);
281
+ if (!existing) {
282
+ throw new CoreError({
283
+ code: 'NOT_FOUND',
284
+ message: `Alarm not found: ${alarmId}`,
285
+ retryable: false,
286
+ });
287
+ }
288
+ await deleteAlarm(alarmId);
289
+ return textResult({ deleted: true, alarm_id: alarmId });
290
+ }
291
+ catch (error) {
292
+ return errorResult(error);
293
+ }
294
+ },
295
+ }, { optional: true });
296
+ // ── poll_now ──
297
+ api.registerTool({
298
+ name: 'korbus_poll_now',
299
+ description: 'Run immediate polling for active alarms (checks arrivals and sends notifications)',
300
+ parameters: Type.Object({
301
+ dry_run: Type.Optional(Type.Boolean({
302
+ description: 'If true, check but do not send notifications',
303
+ })),
304
+ }),
305
+ async execute(_id, params) {
306
+ try {
307
+ const result = await pollActiveAlarms(deps, {
308
+ dryRun: params.dry_run,
309
+ });
310
+ return textResult(result);
311
+ }
312
+ catch (error) {
313
+ return errorResult(error);
314
+ }
315
+ },
316
+ }, { optional: true });
317
+ }
318
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/openclaw/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { BusGateway } from './bus/gateway.js';
2
+ import type { Dispatcher } from './notifier/dispatcher.js';
3
+ import type { PollResult } from './types.js';
4
+ export interface PollDeps {
5
+ gateway: BusGateway;
6
+ dispatcher: Dispatcher;
7
+ }
8
+ interface PollOptions {
9
+ now?: Date;
10
+ dryRun?: boolean;
11
+ }
12
+ export declare function pollActiveAlarms(deps: PollDeps, options?: PollOptions): Promise<PollResult>;
13
+ export declare function startScheduler(deps: PollDeps): () => void;
14
+ export {};
15
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAsB,UAAU,EAAsB,MAAM,YAAY,CAAC;AAErF,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,UAAU,WAAW;IACnB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,QAAQ,EACd,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,UAAU,CAAC,CA+FrB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,IAAI,CA2BzD"}