@0xmaxma/claude-gateway 1.1.10 → 1.2.1

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 (65) hide show
  1. package/README.md +61 -1
  2. package/dist/agent/builtin-commands.d.ts +10 -0
  3. package/dist/agent/builtin-commands.d.ts.map +1 -0
  4. package/dist/agent/builtin-commands.js +38 -0
  5. package/dist/agent/builtin-commands.js.map +1 -0
  6. package/dist/agent/runner.d.ts +1 -4
  7. package/dist/agent/runner.d.ts.map +1 -1
  8. package/dist/agent/runner.js +25 -30
  9. package/dist/agent/runner.js.map +1 -1
  10. package/dist/agent/workspace-loader.d.ts.map +1 -1
  11. package/dist/agent/workspace-loader.js +9 -4
  12. package/dist/agent/workspace-loader.js.map +1 -1
  13. package/dist/api/apps-router.d.ts +7 -0
  14. package/dist/api/apps-router.d.ts.map +1 -0
  15. package/dist/api/apps-router.js +242 -0
  16. package/dist/api/apps-router.js.map +1 -0
  17. package/dist/api/gateway-router.d.ts +17 -1
  18. package/dist/api/gateway-router.d.ts.map +1 -1
  19. package/dist/api/gateway-router.js +171 -2
  20. package/dist/api/gateway-router.js.map +1 -1
  21. package/dist/api/router.js +2 -2
  22. package/dist/api/router.js.map +1 -1
  23. package/dist/apps/agent-manager.d.ts +76 -0
  24. package/dist/apps/agent-manager.d.ts.map +1 -0
  25. package/dist/apps/agent-manager.js +311 -0
  26. package/dist/apps/agent-manager.js.map +1 -0
  27. package/dist/apps/compose-generator.d.ts +108 -0
  28. package/dist/apps/compose-generator.d.ts.map +1 -0
  29. package/dist/apps/compose-generator.js +687 -0
  30. package/dist/apps/compose-generator.js.map +1 -0
  31. package/dist/apps/installer.d.ts +101 -0
  32. package/dist/apps/installer.d.ts.map +1 -0
  33. package/dist/apps/installer.js +898 -0
  34. package/dist/apps/installer.js.map +1 -0
  35. package/dist/apps/registry-client.d.ts +37 -0
  36. package/dist/apps/registry-client.d.ts.map +1 -0
  37. package/dist/apps/registry-client.js +106 -0
  38. package/dist/apps/registry-client.js.map +1 -0
  39. package/dist/apps/registry.d.ts +54 -0
  40. package/dist/apps/registry.d.ts.map +1 -0
  41. package/dist/apps/registry.js +182 -0
  42. package/dist/apps/registry.js.map +1 -0
  43. package/dist/apps/socket-server.d.ts +46 -0
  44. package/dist/apps/socket-server.d.ts.map +1 -0
  45. package/dist/apps/socket-server.js +297 -0
  46. package/dist/apps/socket-server.js.map +1 -0
  47. package/dist/config/watcher.d.ts.map +1 -1
  48. package/dist/config/watcher.js +35 -0
  49. package/dist/config/watcher.js.map +1 -1
  50. package/dist/index.js +145 -1
  51. package/dist/index.js.map +1 -1
  52. package/dist/session/process.d.ts.map +1 -1
  53. package/dist/session/process.js +47 -6
  54. package/dist/session/process.js.map +1 -1
  55. package/dist/types.d.ts +6 -0
  56. package/dist/types.d.ts.map +1 -1
  57. package/lib/pairing.ts +326 -0
  58. package/mcp/server.ts +2 -0
  59. package/mcp/tools/apps/client.ts +78 -0
  60. package/mcp/tools/apps/module.ts +211 -0
  61. package/mcp/tools/apps/skills/app-status/SKILL.md +48 -0
  62. package/mcp/tools/apps/skills/create-app-yaml/SKILL.md +94 -0
  63. package/mcp/tools/apps/skills/install-app/SKILL.md +102 -0
  64. package/mcp/tools/apps/skills/list-apps/SKILL.md +34 -0
  65. package/package.json +2 -1
package/README.md CHANGED
@@ -26,6 +26,7 @@ A self-hosted multi-agent gateway for Claude Code. Connect Claude agents to Tele
26
26
  - **Config auto-migration** — automatic schema migration when config format changes
27
27
  - **Access control** — allowlist, open, or pairing-based Telegram access policies
28
28
  - **HTTP API** — REST API with key-based auth for external integrations
29
+ - **App Store** — install, update, and host Docker-compose apps on the gateway; apps get a reverse proxy at `/app/:name/:portName/*`, optional Unix socket bridge for host scripts, and optional AI agent injection
29
30
  - **Self-update API** — check for newer versions of `claude-gateway` and `claude-code` and trigger an update via a single API call; no SSH or shell access needed
30
31
  - **Session persistence** — conversation history saved and restored across restarts
31
32
 
@@ -62,6 +63,10 @@ cat > ~/.claude-gateway/.env << 'EOF'
62
63
  # HTTP port (default: 10850)
63
64
  # PORT=10850
64
65
 
66
+ # Bind address (default: 0.0.0.0 — all interfaces)
67
+ # Set to 127.0.0.1 if a host-network reverse proxy (e.g. Traefik) is used
68
+ # GATEWAY_BIND=127.0.0.1
69
+
65
70
  # Path to gateway config (default: ~/.claude-gateway/config.json)
66
71
  # GATEWAY_CONFIG=~/.claude-gateway/config.json
67
72
  EOF
@@ -414,6 +419,15 @@ Pass API key via `X-Api-Key: <key>` or `Authorization: Bearer <key>` header.
414
419
  | `POST` | `/api/v1/agents/wizard/:wizardId/channel` | Verify bot token and generate pairing code (admin) |
415
420
  | `POST` | `/api/v1/agents/wizard/:wizardId/channel/verify` | Poll for pairing code confirmation (admin) |
416
421
  | `POST` | `/api/v1/agents/wizard/:wizardId/complete` | Skip channel and finalise wizard (admin) |
422
+ | `GET` | `/api/v1/apps/registry` | Browse community app registry (admin key) |
423
+ | `POST` | `/api/v1/apps/install` | Install app from registry, GitHub, or local path → `jobId` (admin) |
424
+ | `GET` | `/api/v1/apps/jobs/:jobId` | Poll install/update job status and logs |
425
+ | `GET` | `/api/v1/apps` | List installed apps |
426
+ | `GET` | `/api/v1/apps/:name` | Get app info |
427
+ | `DELETE` | `/api/v1/apps/:name` | Uninstall app (admin) |
428
+ | `POST` | `/api/v1/apps/:name/start\|stop\|restart` | Start/stop/restart app containers (admin) |
429
+ | `POST` | `/api/v1/apps/:name/update` | Blue-green update with auto-rollback → `jobId` (admin) |
430
+ | `GET` | `/app/:name/:portName/*` | Reverse proxy to installed app (no auth) |
417
431
 
418
432
  **Wizard API** — create agents programmatically with the same flow as the interactive `make create-agent` terminal wizard. The wizard generates workspace files via Claude, writes them on confirm, and optionally pairs a Telegram/Discord bot. State is in-memory with a 30-minute TTL; nothing is written until `/confirm`. See [API.md](./API.md) for the full wizard flow.
419
433
 
@@ -421,6 +435,52 @@ See **[API.md](./API.md)** for full reference with request/response schemas and
421
435
 
422
436
  ---
423
437
 
438
+ ## App Store
439
+
440
+ Install Docker-compose apps on the gateway. Apps get a reverse-proxied HTTP endpoint, an optional Unix socket bridge for executing host scripts, and optional AI agent injection.
441
+
442
+ **Quick install from registry:**
443
+
444
+ ```bash
445
+ curl -X POST http://localhost:10850/api/v1/apps/install \
446
+ -H "X-Api-Key: <admin-key>" \
447
+ -H "Content-Type: application/json" \
448
+ -d '{"registry_app": "getpod-manager", "env_vars": {"API_KEY": "<secret>"}}'
449
+ ```
450
+
451
+ **Poll until done:**
452
+
453
+ ```bash
454
+ curl http://localhost:10850/api/v1/apps/jobs/<jobId> -H "X-Api-Key: <key>" | jq .status
455
+ ```
456
+
457
+ **App is then live at** `/app/getpod-manager/<portName>/`.
458
+
459
+ Apps can also be installed from a GitHub URL (`github_url` + `commit`) or a local path (`local_path`) for development. Updates use a **blue-green swap with automatic rollback** — the old containers stay intact until the new version passes its healthcheck.
460
+
461
+ **Reverse proxy configuration:**
462
+
463
+ The gateway proxies `/app/:name/:portName/*` to the app containers. Two env vars control how the gateway reaches them:
464
+
465
+ | Env var | Default | Description |
466
+ |---------|---------|-------------|
467
+ | `GATEWAY_BIND` | `0.0.0.0` | Gateway HTTP listen address. Must be `0.0.0.0` (default) when a **containerized** reverse proxy (Caddy, nginx in Docker) needs to reach the gateway. Set to `127.0.0.1` only if using a **host-network** proxy (Traefik on host) — loopback is not reachable across container boundaries. |
468
+ | `DOCKER_HOST` | _(system default)_ | Docker socket/TCP address. When set to `tcp://host:port` (e.g. DinD), the gateway automatically uses the host extracted from `DOCKER_HOST` to proxy to app containers instead of `127.0.0.1`. |
469
+
470
+ Example Caddyfile for apps behind Caddy in Docker:
471
+
472
+ ```caddy
473
+ handle /app* {
474
+ reverse_proxy dev-server:10850
475
+ }
476
+ ```
477
+
478
+ (`handle`, not `handle_path` — preserve the `/app` prefix so the gateway's router can match it.)
479
+
480
+ See **[API.md — App Store section](./API.md#app-store-api)** for the full reference including `app.yaml` schema, `gateway_api` host-script bridge, and agent injection.
481
+
482
+ ---
483
+
424
484
  ## File Structure
425
485
 
426
486
  ### Project
@@ -779,7 +839,7 @@ Once paired, the following bot commands are available in a private chat:
779
839
 
780
840
  ## Monitoring
781
841
 
782
- The gateway runs an HTTP server on port 10850 (set `PORT` env var to change):
842
+ The gateway runs an HTTP server on port 10850 (set `PORT` env var to change, `GATEWAY_BIND` to set the bind address):
783
843
 
784
844
  | Endpoint | Description |
785
845
  |----------|-------------|
@@ -0,0 +1,10 @@
1
+ export type CommandChannel = 'telegram' | 'discord' | 'api';
2
+ interface CommandDef {
3
+ channels: CommandChannel[];
4
+ /** word-boundary check: true (default) = /^\/cmd\b/, false = /^\/cmd(\s|$)/ */
5
+ wordBoundary?: boolean;
6
+ }
7
+ export declare const BUILTIN_COMMANDS: Record<string, CommandDef>;
8
+ export declare function isBuiltinCommand(content: string, channel: CommandChannel): boolean;
9
+ export {};
10
+ //# sourceMappingURL=builtin-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtin-commands.d.ts","sourceRoot":"","sources":["../../src/agent/builtin-commands.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,SAAS,GAAG,KAAK,CAAC;AAE5D,UAAU,UAAU;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,+EAA+E;IAC/E,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAcvD,CAAC;AAsBF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAElF"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BUILTIN_COMMANDS = void 0;
4
+ exports.isBuiltinCommand = isBuiltinCommand;
5
+ exports.BUILTIN_COMMANDS = {
6
+ session: { channels: ['telegram', 'discord', 'api'] },
7
+ sessions: { channels: ['telegram', 'discord', 'api'] },
8
+ new: { channels: ['telegram', 'discord'], wordBoundary: false },
9
+ rename: { channels: ['telegram'], wordBoundary: false },
10
+ clear: { channels: ['telegram', 'api'] },
11
+ compact: { channels: ['telegram', 'api'] },
12
+ stop: { channels: ['telegram', 'api'], wordBoundary: false },
13
+ model: { channels: ['telegram', 'discord', 'api'] },
14
+ models: { channels: ['telegram'] },
15
+ restart: { channels: ['telegram', 'api'], wordBoundary: false },
16
+ start: { channels: ['telegram'] },
17
+ help: { channels: ['telegram'] },
18
+ status: { channels: ['telegram'] },
19
+ };
20
+ const _cache = new Map();
21
+ function buildRegex(channel) {
22
+ const parts = Object.entries(exports.BUILTIN_COMMANDS)
23
+ .filter(([, def]) => def.channels.includes(channel))
24
+ .map(([cmd, def]) => def.wordBoundary === false ? `^\/${cmd}(\\s|$)` : `^\/${cmd}\\b`);
25
+ return new RegExp(parts.join('|'));
26
+ }
27
+ function getRegex(channel) {
28
+ let re = _cache.get(channel);
29
+ if (!re) {
30
+ re = buildRegex(channel);
31
+ _cache.set(channel, re);
32
+ }
33
+ return re;
34
+ }
35
+ function isBuiltinCommand(content, channel) {
36
+ return getRegex(channel).test(content.trim());
37
+ }
38
+ //# sourceMappingURL=builtin-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtin-commands.js","sourceRoot":"","sources":["../../src/agent/builtin-commands.ts"],"names":[],"mappings":";;;AA4CA,4CAEC;AAtCY,QAAA,gBAAgB,GAA+B;IAC1D,OAAO,EAAG,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE;IACtD,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE;IACtD,GAAG,EAAO,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE;IACpE,MAAM,EAAI,EAAE,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE;IACzD,KAAK,EAAK,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE;IAC3C,OAAO,EAAG,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE;IAC3C,IAAI,EAAM,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE;IAChE,KAAK,EAAK,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE;IACtD,MAAM,EAAI,EAAE,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE;IACpC,OAAO,EAAG,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE;IAChE,KAAK,EAAK,EAAE,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE;IACpC,IAAI,EAAM,EAAE,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE;IACpC,MAAM,EAAI,EAAE,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE;CACrC,CAAC;AAEF,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;AAEjD,SAAS,UAAU,CAAC,OAAuB;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,wBAAgB,CAAC;SAC3C,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SACnD,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAClB,GAAG,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CACjE,CAAC;IACJ,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,QAAQ,CAAC,OAAuB;IACvC,IAAI,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QACzB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAgB,gBAAgB,CAAC,OAAe,EAAE,OAAuB;IACvE,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAChD,CAAC"}
@@ -59,10 +59,7 @@ export declare class AgentRunner extends EventEmitter {
59
59
  private static buildChannelXml;
60
60
  private getOrSpawnSession;
61
61
  private spawnSession;
62
- /**
63
- * Returns true if the message content is a session management command.
64
- */
65
- private isSessionCommand;
62
+ static isApiBuiltinCommand(content: string): boolean;
66
63
  /**
67
64
  * Dispatch a session management command to the appropriate handler.
68
65
  */
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"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"}
@@ -47,6 +47,7 @@ const receiver_1 = require("../telegram/receiver");
47
47
  const receiver_2 = require("../discord/receiver");
48
48
  const markdown_1 = require("../telegram/markdown");
49
49
  const skills_1 = require("../skills");
50
+ const builtin_commands_1 = require("./builtin-commands");
50
51
  const db_1 = require("../history/db");
51
52
  const media_store_1 = require("../history/media-store");
52
53
  const cleanup_1 = require("../history/cleanup");
@@ -96,7 +97,7 @@ function buildApiSystemNote(allowTools, imagePaths) {
96
97
  if (imagePaths?.length) {
97
98
  imageNote = ` The user attached ${imagePaths.length} image(s). Read them with the Read tool:\n${imagePaths.map(p => `- ${p}`).join('\n')}`;
98
99
  }
99
- return `[SYSTEM: This is an API request. ${memoryOverride} ${toolNote}${imageNote}]\n`;
100
+ return `<api-context>This is an API request. ${memoryOverride} ${toolNote}${imageNote}</api-context>\n`;
100
101
  }
101
102
  class AgentRunner extends events_1.EventEmitter {
102
103
  imageSize(chatId) { return this.imageSizePerChat.get(chatId) ?? 0; }
@@ -186,9 +187,9 @@ class AgentRunner extends events_1.EventEmitter {
186
187
  // Set channel early so all handlers (including session commands) have it
187
188
  const channelSource = (meta['source'] === 'discord' ? 'discord' : 'telegram');
188
189
  this.channelSourceMap.set(chatId, channelSource);
189
- // Check if this is a session management command
190
+ // Check if this is a built-in channel command
190
191
  const trimmedContent = content.trim();
191
- if (this.isSessionCommand(trimmedContent)) {
192
+ if ((0, builtin_commands_1.isBuiltinCommand)(trimmedContent, channelSource)) {
192
193
  this.handleSessionCommand(chatId, trimmedContent)
193
194
  .then(() => this.writeTypingDone(chatId))
194
195
  .catch((err) => {
@@ -802,11 +803,8 @@ class AgentRunner extends events_1.EventEmitter {
802
803
  });
803
804
  return proc;
804
805
  }
805
- /**
806
- * Returns true if the message content is a session management command.
807
- */
808
- isSessionCommand(content) {
809
- return /^\/sessions?\b|^\/new(\s|$)|^\/clear\b|^\/compact\b|^\/rename(\s|$)|^\/stop(\s|$)/.test(content);
806
+ static isApiBuiltinCommand(content) {
807
+ return (0, builtin_commands_1.isBuiltinCommand)(content, 'api');
810
808
  }
811
809
  /**
812
810
  * Dispatch a session management command to the appropriate handler.
@@ -1247,9 +1245,8 @@ class AgentRunner extends events_1.EventEmitter {
1247
1245
  const err = Object.assign(new Error(`Session ${sessionId} already has a pending request`), { code: 'CONFLICT' });
1248
1246
  throw err;
1249
1247
  }
1250
- // Register session in api-{chatId} index.json on first use
1251
- const internalChatIdForSession = `api-${chatId}`;
1252
- await this.sessionStore.ensureApiSession(this.agentConfig.id, internalChatIdForSession, sessionId).catch((err) => {
1248
+ // Register session in api-{chatId} index.json on first use (store adds channel prefix internally)
1249
+ await this.sessionStore.ensureApiSession(this.agentConfig.id, chatId, sessionId).catch((err) => {
1253
1250
  this.logger.warn('Failed to register API session in index', { agentId: this.agentConfig.id, chatId, sessionId, error: err.message });
1254
1251
  });
1255
1252
  // Use model from request body if provided, otherwise use agent default
@@ -1409,9 +1406,8 @@ class AgentRunner extends events_1.EventEmitter {
1409
1406
  const err = Object.assign(new Error(`Session ${sessionId} already has a pending request`), { code: 'CONFLICT' });
1410
1407
  throw err;
1411
1408
  }
1412
- // Register session in api-{chatId} index.json on first use
1413
- const internalChatIdStream = `api-${chatId}`;
1414
- await this.sessionStore.ensureApiSession(this.agentConfig.id, internalChatIdStream, sessionId).catch((err) => {
1409
+ // Register session in api-{chatId} index.json on first use (store adds channel prefix internally)
1410
+ await this.sessionStore.ensureApiSession(this.agentConfig.id, chatId, sessionId).catch((err) => {
1415
1411
  this.logger.warn('Failed to register API session in index', { agentId: this.agentConfig.id, chatId, sessionId, error: err.message });
1416
1412
  });
1417
1413
  // Use model from request body if provided, otherwise use agent default
@@ -1624,7 +1620,8 @@ class AgentRunner extends events_1.EventEmitter {
1624
1620
  }
1625
1621
  async executeApiCommand(sessionId, chatId, command) {
1626
1622
  const agentId = this.agentConfig.id;
1627
- const internalChatId = `api-${chatId}`;
1623
+ const storeChatId = chatId; // sessionStore adds channel prefix internally
1624
+ const dbChatId = `api-${chatId}`; // historyDb uses full channel-chatId key
1628
1625
  if (command === '/model') {
1629
1626
  return { model: this.agentConfig.claude.model };
1630
1627
  }
@@ -1638,7 +1635,7 @@ class AgentRunner extends events_1.EventEmitter {
1638
1635
  return { restarting: true };
1639
1636
  }
1640
1637
  if (command === '/session') {
1641
- const index = await this.sessionStore.listSessions(agentId, internalChatId, 'api').catch(() => null);
1638
+ const index = await this.sessionStore.listSessions(agentId, storeChatId, 'api').catch(() => null);
1642
1639
  const meta = index?.sessions.find((s) => s.id === sessionId);
1643
1640
  const effectiveModel = this.agentConfig.claude.model;
1644
1641
  if (!meta)
@@ -1658,15 +1655,15 @@ class AgentRunner extends events_1.EventEmitter {
1658
1655
  }
1659
1656
  if (command === '/clear') {
1660
1657
  const ch = 'api';
1661
- await this.sessionStore.clearTelegramSessionHistory(agentId, internalChatId, sessionId, ch);
1662
- await this.sessionStore.updateSessionMeta(agentId, internalChatId, sessionId, {
1658
+ await this.sessionStore.clearTelegramSessionHistory(agentId, storeChatId, sessionId, ch);
1659
+ await this.sessionStore.updateSessionMeta(agentId, storeChatId, sessionId, {
1663
1660
  totalTokensUsed: 0,
1664
1661
  lastInputTokens: 0,
1665
1662
  archivedCount: 0,
1666
1663
  loadedAtSpawn: undefined,
1667
1664
  messageCountAtSpawn: undefined,
1668
1665
  }, ch);
1669
- const mediaPaths = this.historyDb.clearSession(internalChatId, sessionId);
1666
+ const mediaPaths = this.historyDb.clearSession(dbChatId, sessionId);
1670
1667
  media_store_1.MediaStore.deleteMediaFiles(this.agentsBaseDir, agentId, mediaPaths);
1671
1668
  this.restartProcess(sessionId).catch(() => { });
1672
1669
  return { success: true };
@@ -1678,8 +1675,8 @@ class AgentRunner extends events_1.EventEmitter {
1678
1675
  const modelConfig = availableModels.find((m) => m.id === compactEffectiveModel);
1679
1676
  const contextWindow = modelConfig?.contextWindow ?? 200000;
1680
1677
  const compactor = new compactor_1.SessionCompactor(this.sessionStore);
1681
- const result = await compactor.compact(agentId, internalChatId, sessionId, compactEffectiveModel, contextWindow, ch);
1682
- await this.sessionStore.updateSessionMeta(agentId, internalChatId, sessionId, {
1678
+ const result = await compactor.compact(agentId, storeChatId, sessionId, compactEffectiveModel, contextWindow, ch);
1679
+ await this.sessionStore.updateSessionMeta(agentId, storeChatId, sessionId, {
1683
1680
  loadedAtSpawn: undefined,
1684
1681
  archivedCount: undefined,
1685
1682
  messageCountAtSpawn: undefined,
@@ -1703,7 +1700,7 @@ class AgentRunner extends events_1.EventEmitter {
1703
1700
  }
1704
1701
  }
1705
1702
  async listApiSessions(chatId) {
1706
- return this.sessionStore.listSessions(this.agentConfig.id, `api-${chatId}`, 'api');
1703
+ return this.sessionStore.listSessions(this.agentConfig.id, chatId, 'api');
1707
1704
  }
1708
1705
  async createApiSession(chatId, prompt, name) {
1709
1706
  let sessionName = name;
@@ -1720,10 +1717,10 @@ class AgentRunner extends events_1.EventEmitter {
1720
1717
  sessionName = undefined;
1721
1718
  }
1722
1719
  }
1723
- return this.sessionStore.createTelegramSession(this.agentConfig.id, `api-${chatId}`, sessionName, 'api');
1720
+ return this.sessionStore.createTelegramSession(this.agentConfig.id, chatId, sessionName, 'api');
1724
1721
  }
1725
1722
  async getApiSessionInfo(chatId, sessionId) {
1726
- const index = await this.sessionStore.listSessions(this.agentConfig.id, `api-${chatId}`, 'api').catch(() => null);
1723
+ const index = await this.sessionStore.listSessions(this.agentConfig.id, chatId, 'api').catch(() => null);
1727
1724
  const meta = index?.sessions.find((s) => s.id === sessionId);
1728
1725
  if (!meta)
1729
1726
  return null;
@@ -1743,25 +1740,23 @@ class AgentRunner extends events_1.EventEmitter {
1743
1740
  }
1744
1741
  async updateApiSession(chatId, sessionId, updates) {
1745
1742
  if (updates.sessionName) {
1746
- const internalChatId = `api-${chatId}`;
1747
1743
  // Ensure session exists in the file index (may be missing for older sessions stored only in SQLite)
1748
- await this.sessionStore.ensureApiSession(this.agentConfig.id, internalChatId, sessionId).catch((err) => {
1744
+ await this.sessionStore.ensureApiSession(this.agentConfig.id, chatId, sessionId).catch((err) => {
1749
1745
  this.logger.warn('Failed to register API session in index', { agentId: this.agentConfig.id, chatId, sessionId, error: err.message });
1750
1746
  });
1751
- await this.sessionStore.updateSessionMeta(this.agentConfig.id, internalChatId, sessionId, { name: updates.sessionName }, 'api');
1747
+ await this.sessionStore.updateSessionMeta(this.agentConfig.id, chatId, sessionId, { name: updates.sessionName }, 'api');
1752
1748
  }
1753
1749
  return { sessionId, ...(updates.sessionName ? { sessionName: updates.sessionName } : {}) };
1754
1750
  }
1755
1751
  async deleteApiSession(chatId, sessionId) {
1756
- const internalChatId = `api-${chatId}`;
1757
- await this.sessionStore.deleteTelegramSession(this.agentConfig.id, internalChatId, sessionId, 'api').catch((err) => {
1752
+ await this.sessionStore.deleteTelegramSession(this.agentConfig.id, chatId, sessionId, 'api').catch((err) => {
1758
1753
  // Legacy sessions (stored only in SQLite, no file index entry) are treated as already deleted
1759
1754
  if (err instanceof store_1.SessionNotInIndexError)
1760
1755
  return;
1761
1756
  throw err;
1762
1757
  });
1763
1758
  // Purge from SQLite so the session no longer appears in listSessions()
1764
- const mediaPaths = this.historyDb.clearSession(internalChatId, sessionId);
1759
+ const mediaPaths = this.historyDb.clearSession(`api-${chatId}`, sessionId);
1765
1760
  media_store_1.MediaStore.deleteMediaFiles(this.agentsBaseDir, this.agentConfig.id, mediaPaths);
1766
1761
  }
1767
1762
  /**