@openacp/cli 2026.328.2 → 2026.330.3

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 (86) hide show
  1. package/dist/{adapter-HGJENQCN.js → adapter-AWSI4GML.js} +4 -4
  2. package/dist/api-server-5VNYFWJE.js +7 -0
  3. package/dist/{api-server-WFB5K6FP.js → api-server-JLBDKCU4.js} +2 -2
  4. package/dist/{chunk-5TCXYDLR.js → chunk-237WYH6H.js} +26 -3
  5. package/dist/chunk-237WYH6H.js.map +1 -0
  6. package/dist/{chunk-E2SLHZAC.js → chunk-2HEFALTZ.js} +6 -6
  7. package/dist/{chunk-I53NEV3S.js → chunk-5WGVYX3C.js} +13 -3
  8. package/dist/chunk-5WGVYX3C.js.map +1 -0
  9. package/dist/{chunk-IXMIC4GQ.js → chunk-BTJHGSLM.js} +2 -2
  10. package/dist/{chunk-43JVXFYP.js → chunk-GEOXPGCO.js} +2 -2
  11. package/dist/{chunk-JUFN4XMB.js → chunk-KDU3ZEWT.js} +2 -2
  12. package/dist/{chunk-QWP76EBW.js → chunk-MITTQMGZ.js} +16 -9
  13. package/dist/chunk-MITTQMGZ.js.map +1 -0
  14. package/dist/{chunk-QBEQJFGL.js → chunk-MPGEHTGE.js} +3 -3
  15. package/dist/{chunk-4B6PCWQP.js → chunk-PA6MNBG4.js} +6 -2
  16. package/dist/chunk-PA6MNBG4.js.map +1 -0
  17. package/dist/{chunk-VD3QSMVY.js → chunk-QWVHCTCA.js} +2 -2
  18. package/dist/{chunk-NT6FYV27.js → chunk-TMVTSWVH.js} +2 -2
  19. package/dist/{chunk-6VR4GWOO.js → chunk-UCIZM5SW.js} +247 -70
  20. package/dist/chunk-UCIZM5SW.js.map +1 -0
  21. package/dist/chunk-UWH7KIAA.js +701 -0
  22. package/dist/chunk-UWH7KIAA.js.map +1 -0
  23. package/dist/{chunk-JOMDPFQ2.js → chunk-W4LK6WJP.js} +29 -4
  24. package/dist/chunk-W4LK6WJP.js.map +1 -0
  25. package/dist/{chunk-RXMWJHWH.js → chunk-XBZIHNKV.js} +733 -221
  26. package/dist/chunk-XBZIHNKV.js.map +1 -0
  27. package/dist/cli.js +63 -68
  28. package/dist/cli.js.map +1 -1
  29. package/dist/config-KN6NKKPF.js +20 -0
  30. package/dist/{config-editor-OU6PUY66.js → config-editor-76RVZS4B.js} +3 -3
  31. package/dist/context-NXXW62NJ.js +9 -0
  32. package/dist/{core-plugins-R2EVZAJV.js → core-plugins-BPZY7SEB.js} +9 -9
  33. package/dist/{daemon-DTA6KYYY.js → daemon-XFEMMJSZ.js} +3 -3
  34. package/dist/doctor-AV6AUO22.js +9 -0
  35. package/dist/index.d.ts +110 -44
  36. package/dist/index.js +8 -8
  37. package/dist/{main-RRSX5SRL.js → main-VEJCG5PY.js} +38 -30
  38. package/dist/main-VEJCG5PY.js.map +1 -0
  39. package/dist/{plugin-installer-5XHORMLS.js → plugin-installer-VSTYZSXC.js} +2 -2
  40. package/dist/{setup-OI6A3OXW.js → setup-DISPNDEK.js} +4 -5
  41. package/dist/setup-DISPNDEK.js.map +1 -0
  42. package/dist/speech-SG62JYIF.js +9 -0
  43. package/dist/telegram-L3YM6SQJ.js +7 -0
  44. package/dist/tunnel-HWJ27WDH.js +7 -0
  45. package/dist/{tunnel-service-I2NFUX3V.js → tunnel-service-ZMO4THKE.js} +88 -8
  46. package/dist/tunnel-service-ZMO4THKE.js.map +1 -0
  47. package/package.json +1 -1
  48. package/dist/api-server-DSUW637I.js +0 -7
  49. package/dist/chunk-4B6PCWQP.js.map +0 -1
  50. package/dist/chunk-5TCXYDLR.js.map +0 -1
  51. package/dist/chunk-6VR4GWOO.js.map +0 -1
  52. package/dist/chunk-I53NEV3S.js.map +0 -1
  53. package/dist/chunk-JOMDPFQ2.js.map +0 -1
  54. package/dist/chunk-QWP76EBW.js.map +0 -1
  55. package/dist/chunk-RXMWJHWH.js.map +0 -1
  56. package/dist/chunk-ZHGPZBS4.js +0 -49
  57. package/dist/chunk-ZHGPZBS4.js.map +0 -1
  58. package/dist/config-UCAFCS5W.js +0 -14
  59. package/dist/context-7MPU7RL5.js +0 -9
  60. package/dist/doctor-D723IB2I.js +0 -9
  61. package/dist/main-RRSX5SRL.js.map +0 -1
  62. package/dist/setup-OI6A3OXW.js.map +0 -1
  63. package/dist/speech-GB7PHVQZ.js +0 -9
  64. package/dist/telegram-UVIAXADE.js +0 -7
  65. package/dist/tunnel-4WNFC7GO.js +0 -7
  66. package/dist/tunnel-service-I2NFUX3V.js.map +0 -1
  67. /package/dist/{adapter-HGJENQCN.js.map → adapter-AWSI4GML.js.map} +0 -0
  68. /package/dist/{api-server-DSUW637I.js.map → api-server-5VNYFWJE.js.map} +0 -0
  69. /package/dist/{api-server-WFB5K6FP.js.map → api-server-JLBDKCU4.js.map} +0 -0
  70. /package/dist/{chunk-E2SLHZAC.js.map → chunk-2HEFALTZ.js.map} +0 -0
  71. /package/dist/{chunk-IXMIC4GQ.js.map → chunk-BTJHGSLM.js.map} +0 -0
  72. /package/dist/{chunk-43JVXFYP.js.map → chunk-GEOXPGCO.js.map} +0 -0
  73. /package/dist/{chunk-JUFN4XMB.js.map → chunk-KDU3ZEWT.js.map} +0 -0
  74. /package/dist/{chunk-QBEQJFGL.js.map → chunk-MPGEHTGE.js.map} +0 -0
  75. /package/dist/{chunk-VD3QSMVY.js.map → chunk-QWVHCTCA.js.map} +0 -0
  76. /package/dist/{chunk-NT6FYV27.js.map → chunk-TMVTSWVH.js.map} +0 -0
  77. /package/dist/{config-UCAFCS5W.js.map → config-KN6NKKPF.js.map} +0 -0
  78. /package/dist/{config-editor-OU6PUY66.js.map → config-editor-76RVZS4B.js.map} +0 -0
  79. /package/dist/{context-7MPU7RL5.js.map → context-NXXW62NJ.js.map} +0 -0
  80. /package/dist/{core-plugins-R2EVZAJV.js.map → core-plugins-BPZY7SEB.js.map} +0 -0
  81. /package/dist/{daemon-DTA6KYYY.js.map → daemon-XFEMMJSZ.js.map} +0 -0
  82. /package/dist/{doctor-D723IB2I.js.map → doctor-AV6AUO22.js.map} +0 -0
  83. /package/dist/{plugin-installer-5XHORMLS.js.map → plugin-installer-VSTYZSXC.js.map} +0 -0
  84. /package/dist/{speech-GB7PHVQZ.js.map → speech-SG62JYIF.js.map} +0 -0
  85. /package/dist/{telegram-UVIAXADE.js.map → telegram-L3YM6SQJ.js.map} +0 -0
  86. /package/dist/{tunnel-4WNFC7GO.js.map → tunnel-HWJ27WDH.js.map} +0 -0
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  TelegramAdapter
3
- } from "./chunk-RXMWJHWH.js";
3
+ } from "./chunk-XBZIHNKV.js";
4
4
  import "./chunk-AFKX424Q.js";
5
- import "./chunk-43JVXFYP.js";
5
+ import "./chunk-GEOXPGCO.js";
6
6
  import "./chunk-APS6UEFU.js";
7
7
  import "./chunk-5HKQCYOI.js";
8
- import "./chunk-JOMDPFQ2.js";
8
+ import "./chunk-W4LK6WJP.js";
9
9
  import "./chunk-R6KZYF7D.js";
10
10
  export {
11
11
  TelegramAdapter
12
12
  };
13
- //# sourceMappingURL=adapter-HGJENQCN.js.map
13
+ //# sourceMappingURL=adapter-AWSI4GML.js.map
@@ -0,0 +1,7 @@
1
+ import {
2
+ api_server_default
3
+ } from "./chunk-KDU3ZEWT.js";
4
+ export {
5
+ api_server_default as default
6
+ };
7
+ //# sourceMappingURL=api-server-5VNYFWJE.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  ApiServer
3
- } from "./chunk-IXMIC4GQ.js";
3
+ } from "./chunk-BTJHGSLM.js";
4
4
  import "./chunk-FNRSWA2K.js";
5
5
  import "./chunk-ZSLHHQPQ.js";
6
6
  import "./chunk-R6KZYF7D.js";
7
7
  export {
8
8
  ApiServer
9
9
  };
10
- //# sourceMappingURL=api-server-WFB5K6FP.js.map
10
+ //# sourceMappingURL=api-server-JLBDKCU4.js.map
@@ -146,11 +146,34 @@ function createTelegramPlugin() {
146
146
  ctx.log.info("Telegram disabled (missing botToken or chatId)");
147
147
  return;
148
148
  }
149
- const { TelegramAdapter } = await import("./adapter-HGJENQCN.js");
150
- adapter = new TelegramAdapter(ctx.core, {
149
+ const core = ctx.core;
150
+ const settingsManager = core.lifecycleManager?.settingsManager;
151
+ if ((config.notificationTopicId == null || config.assistantTopicId == null) && settingsManager) {
152
+ const mainCfg = core.configManager.get();
153
+ const legacy = mainCfg?.channels?.telegram;
154
+ const migrated = {};
155
+ if (legacy?.notificationTopicId != null && config.notificationTopicId == null) {
156
+ config.notificationTopicId = legacy.notificationTopicId;
157
+ migrated.notificationTopicId = legacy.notificationTopicId;
158
+ }
159
+ if (legacy?.assistantTopicId != null && config.assistantTopicId == null) {
160
+ config.assistantTopicId = legacy.assistantTopicId;
161
+ migrated.assistantTopicId = legacy.assistantTopicId;
162
+ }
163
+ if (Object.keys(migrated).length > 0) {
164
+ await settingsManager.updatePluginSettings(ctx.pluginName, migrated);
165
+ ctx.log.info("Migrated topic IDs from main config to plugin settings");
166
+ }
167
+ }
168
+ const { TelegramAdapter } = await import("./adapter-AWSI4GML.js");
169
+ adapter = new TelegramAdapter(core, {
151
170
  ...config,
152
171
  enabled: true,
153
172
  maxMessageLength: 4096
173
+ }, async (updates) => {
174
+ if (settingsManager) {
175
+ await settingsManager.updatePluginSettings(ctx.pluginName, updates);
176
+ }
154
177
  });
155
178
  ctx.registerService("adapter:telegram", adapter);
156
179
  ctx.log.info("Telegram adapter registered");
@@ -209,4 +232,4 @@ var telegram_default = createTelegramPlugin();
209
232
  export {
210
233
  telegram_default
211
234
  };
212
- //# sourceMappingURL=chunk-5TCXYDLR.js.map
235
+ //# sourceMappingURL=chunk-237WYH6H.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plugins/telegram/index.ts"],"sourcesContent":["import type { OpenACPPlugin, InstallContext } from '../../core/plugin/types.js'\nimport type { OpenACPCore } from '../../core/core.js'\nimport type { TelegramChannelConfig } from './types.js'\n\nfunction createTelegramPlugin(): OpenACPPlugin {\n let adapter: { stop(): Promise<void> } | null = null\n\n return {\n name: '@openacp/telegram',\n version: '1.0.0',\n description: 'Telegram adapter with forum topics',\n essential: true,\n pluginDependencies: {\n '@openacp/security': '^1.0.0',\n '@openacp/notifications': '^1.0.0',\n },\n optionalPluginDependencies: {\n '@openacp/speech': '^1.0.0',\n },\n permissions: ['services:register', 'kernel:access', 'events:read'],\n\n async install(ctx: InstallContext) {\n const { terminal, settings, legacyConfig } = ctx\n\n // Migrate from legacy config if present\n if (legacyConfig) {\n const tg = legacyConfig.channels as Record<string, unknown> | undefined\n const telegramCfg = tg?.telegram as Record<string, unknown> | undefined\n if (telegramCfg?.botToken) {\n await settings.setAll({\n botToken: telegramCfg.botToken,\n chatId: telegramCfg.chatId,\n notificationTopicId: telegramCfg.notificationTopicId ?? null,\n assistantTopicId: telegramCfg.assistantTopicId ?? null,\n })\n terminal.log.success('Telegram settings migrated from legacy config')\n return\n }\n }\n\n // Interactive setup via terminal\n const { validateBotToken, validateChatId, validateBotAdmin } = await import('./validators.js')\n\n let botToken = ''\n while (true) {\n botToken = await terminal.text({\n message: 'Telegram bot token (from @BotFather):',\n validate: (val) => {\n if (!val.trim()) return 'Token cannot be empty'\n return undefined\n },\n })\n botToken = botToken.trim()\n\n const spin = terminal.spinner()\n spin.start('Validating token...')\n const result = await validateBotToken(botToken)\n if (result.ok) {\n spin.stop(`Connected to @${result.botUsername}`)\n break\n }\n spin.fail(result.error)\n const action = await terminal.select({\n message: 'What to do?',\n options: [\n { label: 'Re-enter token', value: 'retry' },\n { label: 'Use as-is (skip validation)', value: 'skip' },\n ],\n })\n if (action === 'skip') break\n }\n\n // Chat ID detection\n terminal.log.info('Send a message in your Telegram supergroup to detect the chat ID,')\n terminal.log.info('or enter the chat ID manually.')\n\n const chatIdMethod = await terminal.select({\n message: 'How to get the chat ID?',\n options: [\n { value: 'manual', label: 'Enter chat ID manually' },\n { value: 'detect', label: 'Auto-detect from group message' },\n ],\n })\n\n let chatId: number\n if (chatIdMethod === 'manual') {\n const val = await terminal.text({\n message: 'Supergroup chat ID (e.g. -1001234567890):',\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || !Number.isInteger(n)) return 'Chat ID must be an integer'\n return undefined\n },\n })\n chatId = Number(val.trim())\n } else {\n // Simple polling-based detection\n terminal.log.step('Listening for messages... Send \"hi\" in the group.')\n chatId = await detectChatIdViaPolling(botToken, terminal)\n }\n\n // Validate chat ID\n const chatResult = await validateChatId(botToken, chatId)\n if (chatResult.ok) {\n terminal.log.success(`Group: ${chatResult.title}${chatResult.isForum ? ' (Topics enabled)' : ''}`)\n } else {\n terminal.log.warning(chatResult.error)\n }\n\n // Validate admin\n const adminResult = await validateBotAdmin(botToken, chatId)\n if (adminResult.ok) {\n terminal.log.success('Bot has admin privileges')\n } else {\n terminal.log.warning(adminResult.error)\n }\n\n await settings.setAll({\n botToken,\n chatId,\n notificationTopicId: null,\n assistantTopicId: null,\n })\n terminal.log.success('Telegram settings saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const choice = await terminal.select({\n message: 'What to configure?',\n options: [\n { value: 'token', label: 'Change bot token' },\n { value: 'chatId', label: 'Change chat ID' },\n { value: 'done', label: 'Done' },\n ],\n })\n\n if (choice === 'token') {\n const token = await terminal.text({\n message: 'New bot token:',\n validate: (v) => (!v.trim() ? 'Token cannot be empty' : undefined),\n })\n await settings.set('botToken', token.trim())\n terminal.log.success('Bot token updated')\n } else if (choice === 'chatId') {\n const val = await terminal.text({\n message: 'New chat ID:',\n defaultValue: String(current.chatId ?? ''),\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || !Number.isInteger(n)) return 'Chat ID must be an integer'\n return undefined\n },\n })\n await settings.set('chatId', Number(val.trim()))\n terminal.log.success('Chat ID updated')\n }\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('Telegram settings cleared')\n }\n },\n\n async setup(ctx) {\n const config = ctx.pluginConfig as Record<string, unknown>\n if (!config.botToken || !config.chatId) {\n ctx.log.info('Telegram disabled (missing botToken or chatId)')\n return\n }\n\n const core = ctx.core as OpenACPCore\n const settingsManager = core.lifecycleManager?.settingsManager\n\n // If topic IDs are null in plugin settings but present in main config, migrate them.\n // This handles users who ran a version where ensureTopics saved to main config instead of plugin settings.\n if ((config.notificationTopicId == null || config.assistantTopicId == null) && settingsManager) {\n const mainCfg = core.configManager.get()\n const legacy = (mainCfg as any)?.channels?.telegram as Record<string, unknown> | undefined\n const migrated: Record<string, unknown> = {}\n if (legacy?.notificationTopicId != null && config.notificationTopicId == null) {\n config.notificationTopicId = legacy.notificationTopicId\n migrated.notificationTopicId = legacy.notificationTopicId\n }\n if (legacy?.assistantTopicId != null && config.assistantTopicId == null) {\n config.assistantTopicId = legacy.assistantTopicId\n migrated.assistantTopicId = legacy.assistantTopicId\n }\n if (Object.keys(migrated).length > 0) {\n await settingsManager.updatePluginSettings(ctx.pluginName, migrated)\n ctx.log.info('Migrated topic IDs from main config to plugin settings')\n }\n }\n\n const { TelegramAdapter } = await import('./adapter.js')\n // config is a Record<string, unknown> from pluginConfig; at runtime it\n // contains all TelegramChannelConfig fields populated from the migrated config.\n adapter = new TelegramAdapter(core, {\n ...config,\n enabled: true,\n maxMessageLength: 4096,\n } as unknown as TelegramChannelConfig, async (updates) => {\n // Save topic IDs to plugin settings so they persist across restarts\n if (settingsManager) {\n await settingsManager.updatePluginSettings(ctx.pluginName, updates)\n }\n })\n\n ctx.registerService('adapter:telegram', adapter)\n ctx.log.info('Telegram adapter registered')\n },\n\n async teardown() {\n if (adapter) {\n await adapter.stop()\n }\n },\n }\n}\n\nasync function detectChatIdViaPolling(\n token: string,\n terminal: InstallContext['terminal'],\n): Promise<number> {\n let lastUpdateId = 0\n try {\n const clearRes = await fetch(`https://api.telegram.org/bot${token}/getUpdates?offset=-1`)\n const clearData = (await clearRes.json()) as { ok: boolean; result?: Array<{ update_id: number }> }\n if (clearData.ok && clearData.result?.length) {\n lastUpdateId = clearData.result[clearData.result.length - 1].update_id\n }\n } catch {\n // ignore\n }\n\n const MAX_ATTEMPTS = 120\n const POLL_INTERVAL = 2000\n\n for (let i = 0; i < MAX_ATTEMPTS; i++) {\n try {\n const offset = lastUpdateId ? lastUpdateId + 1 : 0\n const res = await fetch(`https://api.telegram.org/bot${token}/getUpdates?offset=${offset}&timeout=2`)\n const data = (await res.json()) as {\n ok: boolean\n result?: Array<{\n update_id: number\n message?: { chat: { id: number; title?: string; type: string } }\n my_chat_member?: { chat: { id: number; title?: string; type: string } }\n }>\n }\n\n if (data.ok && data.result?.length) {\n for (const update of data.result) {\n lastUpdateId = update.update_id\n const chat = update.message?.chat ?? update.my_chat_member?.chat\n if (chat && (chat.type === 'supergroup' || chat.type === 'group')) {\n terminal.log.success(`Group detected: ${chat.title ?? chat.id} (${chat.id})`)\n return chat.id\n }\n }\n }\n } catch {\n // Network error, retry\n }\n await new Promise((r) => setTimeout(r, POLL_INTERVAL))\n }\n\n // Fallback to manual\n terminal.log.warning('Timed out waiting for messages. Enter chat ID manually.')\n const val = await terminal.text({\n message: 'Supergroup chat ID (e.g. -1001234567890):',\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || !Number.isInteger(n)) return 'Chat ID must be an integer'\n return undefined\n },\n })\n return Number(val.trim())\n}\n\nexport default createTelegramPlugin()\n"],"mappings":"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","names":[]}
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  telegram_default
3
- } from "./chunk-5TCXYDLR.js";
3
+ } from "./chunk-237WYH6H.js";
4
4
  import {
5
5
  notifications_default
6
6
  } from "./chunk-3EWTPOF7.js";
7
7
  import {
8
8
  tunnel_default
9
- } from "./chunk-4B6PCWQP.js";
9
+ } from "./chunk-PA6MNBG4.js";
10
10
  import {
11
11
  api_server_default
12
- } from "./chunk-JUFN4XMB.js";
12
+ } from "./chunk-KDU3ZEWT.js";
13
13
  import {
14
14
  security_default
15
15
  } from "./chunk-5OCGO27U.js";
@@ -18,10 +18,10 @@ import {
18
18
  } from "./chunk-3NAFXVQM.js";
19
19
  import {
20
20
  context_default
21
- } from "./chunk-ZHGPZBS4.js";
21
+ } from "./chunk-UWH7KIAA.js";
22
22
  import {
23
23
  speech_default
24
- } from "./chunk-NT6FYV27.js";
24
+ } from "./chunk-TMVTSWVH.js";
25
25
 
26
26
  // src/plugins/core-plugins.ts
27
27
  var corePlugins = [
@@ -41,4 +41,4 @@ var corePlugins = [
41
41
  export {
42
42
  corePlugins
43
43
  };
44
- //# sourceMappingURL=chunk-E2SLHZAC.js.map
44
+ //# sourceMappingURL=chunk-2HEFALTZ.js.map
@@ -1,7 +1,7 @@
1
1
  // src/core/plugin/plugin-installer.ts
2
2
  import { exec } from "child_process";
3
3
  import { promisify } from "util";
4
- import * as fs from "fs";
4
+ import * as fs from "fs/promises";
5
5
  import * as os from "os";
6
6
  import * as path from "path";
7
7
  import { pathToFileURL } from "url";
@@ -9,7 +9,12 @@ var execAsync = promisify(exec);
9
9
  async function importFromDir(packageName, dir) {
10
10
  const pkgDir = path.join(dir, "node_modules", ...packageName.split("/"));
11
11
  const pkgJsonPath = path.join(pkgDir, "package.json");
12
- const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
12
+ let pkgJson;
13
+ try {
14
+ pkgJson = JSON.parse(await fs.readFile(pkgJsonPath, "utf-8"));
15
+ } catch (err) {
16
+ throw new Error(`Cannot read package.json for "${packageName}" at ${pkgJsonPath}: ${err.message}`);
17
+ }
13
18
  let entry;
14
19
  const exportsMain = pkgJson.exports?.["."];
15
20
  if (typeof exportsMain === "string") {
@@ -20,6 +25,11 @@ async function importFromDir(packageName, dir) {
20
25
  entry = pkgJson.main ?? "index.js";
21
26
  }
22
27
  const entryPath = path.join(pkgDir, entry);
28
+ try {
29
+ await fs.access(entryPath);
30
+ } catch {
31
+ throw new Error(`Entry point "${entry}" not found for "${packageName}" at ${entryPath}`);
32
+ }
23
33
  return import(pathToFileURL(entryPath).href);
24
34
  }
25
35
  var VALID_NPM_NAME = /^(@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*(@[\w.^~>=<|-]+)?$/i;
@@ -42,4 +52,4 @@ export {
42
52
  importFromDir,
43
53
  installNpmPlugin
44
54
  };
45
- //# sourceMappingURL=chunk-I53NEV3S.js.map
55
+ //# sourceMappingURL=chunk-5WGVYX3C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/plugin/plugin-installer.ts"],"sourcesContent":["import { exec } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport * as fs from 'node:fs/promises'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\nimport { pathToFileURL } from 'node:url'\n\nconst execAsync = promisify(exec)\n\n/**\n * Import a package resolved from a specific directory (not the project root).\n * Reads the package's package.json to find the ESM entry point, then imports by file path.\n */\nexport async function importFromDir(packageName: string, dir: string): Promise<any> {\n const pkgDir = path.join(dir, 'node_modules', ...packageName.split('/'))\n const pkgJsonPath = path.join(pkgDir, 'package.json')\n\n let pkgJson: Record<string, any>\n try {\n pkgJson = JSON.parse(await fs.readFile(pkgJsonPath, 'utf-8'))\n } catch (err) {\n throw new Error(`Cannot read package.json for \"${packageName}\" at ${pkgJsonPath}: ${(err as Error).message}`)\n }\n\n // Resolve entry: exports[\".\"].import > main > index.js\n let entry: string\n const exportsMain = pkgJson.exports?.['.']\n if (typeof exportsMain === 'string') {\n entry = exportsMain\n } else if (exportsMain?.import) {\n entry = exportsMain.import\n } else {\n entry = pkgJson.main ?? 'index.js'\n }\n\n const entryPath = path.join(pkgDir, entry)\n try {\n await fs.access(entryPath)\n } catch {\n throw new Error(`Entry point \"${entry}\" not found for \"${packageName}\" at ${entryPath}`)\n }\n\n return import(pathToFileURL(entryPath).href)\n}\n\n/** Valid npm package name: optional @scope/, alphanumeric/hyphens/dots, optional @version */\nconst VALID_NPM_NAME = /^(@[a-z0-9][\\w.-]*\\/)?[a-z0-9][\\w.-]*(@[\\w.^~>=<|-]+)?$/i;\n\n/**\n * Install an npm package to the plugins directory and return the loaded module.\n * Tries to import first; if not installed, runs npm install asynchronously.\n */\nexport async function installNpmPlugin(packageName: string, pluginsDir?: string): Promise<any> {\n if (!VALID_NPM_NAME.test(packageName)) {\n throw new Error(`Invalid package name: \"${packageName}\". Must be a valid npm package name.`);\n }\n\n const dir = pluginsDir ?? path.join(os.homedir(), '.openacp', 'plugins')\n\n // Try import from plugins dir first — already installed\n try {\n return await importFromDir(packageName, dir)\n } catch {\n // Not installed, proceed with install\n }\n\n await execAsync(`npm install ${packageName} --prefix \"${dir}\" --save`, {\n timeout: 60000,\n })\n\n return await importFromDir(packageName, dir)\n}\n"],"mappings":";AAAA,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,SAAS,qBAAqB;AAE9B,IAAM,YAAY,UAAU,IAAI;AAMhC,eAAsB,cAAc,aAAqB,KAA2B;AAClF,QAAM,SAAc,UAAK,KAAK,gBAAgB,GAAG,YAAY,MAAM,GAAG,CAAC;AACvE,QAAM,cAAmB,UAAK,QAAQ,cAAc;AAEpD,MAAI;AACJ,MAAI;AACF,cAAU,KAAK,MAAM,MAAS,YAAS,aAAa,OAAO,CAAC;AAAA,EAC9D,SAAS,KAAK;AACZ,UAAM,IAAI,MAAM,iCAAiC,WAAW,QAAQ,WAAW,KAAM,IAAc,OAAO,EAAE;AAAA,EAC9G;AAGA,MAAI;AACJ,QAAM,cAAc,QAAQ,UAAU,GAAG;AACzC,MAAI,OAAO,gBAAgB,UAAU;AACnC,YAAQ;AAAA,EACV,WAAW,aAAa,QAAQ;AAC9B,YAAQ,YAAY;AAAA,EACtB,OAAO;AACL,YAAQ,QAAQ,QAAQ;AAAA,EAC1B;AAEA,QAAM,YAAiB,UAAK,QAAQ,KAAK;AACzC,MAAI;AACF,UAAS,UAAO,SAAS;AAAA,EAC3B,QAAQ;AACN,UAAM,IAAI,MAAM,gBAAgB,KAAK,oBAAoB,WAAW,QAAQ,SAAS,EAAE;AAAA,EACzF;AAEA,SAAO,OAAO,cAAc,SAAS,EAAE;AACzC;AAGA,IAAM,iBAAiB;AAMvB,eAAsB,iBAAiB,aAAqB,YAAmC;AAC7F,MAAI,CAAC,eAAe,KAAK,WAAW,GAAG;AACrC,UAAM,IAAI,MAAM,0BAA0B,WAAW,sCAAsC;AAAA,EAC7F;AAEA,QAAM,MAAM,cAAmB,UAAQ,WAAQ,GAAG,YAAY,SAAS;AAGvE,MAAI;AACF,WAAO,MAAM,cAAc,aAAa,GAAG;AAAA,EAC7C,QAAQ;AAAA,EAER;AAEA,QAAM,UAAU,eAAe,WAAW,cAAc,GAAG,YAAY;AAAA,IACrE,SAAS;AAAA,EACX,CAAC;AAED,SAAO,MAAM,cAAc,aAAa,GAAG;AAC7C;","names":[]}
@@ -659,7 +659,7 @@ function registerConfigRoutes(router, deps) {
659
659
  }
660
660
  const lastKey = parts[parts.length - 1];
661
661
  target[lastKey] = value;
662
- const { ConfigSchema } = await import("./config-UCAFCS5W.js");
662
+ const { ConfigSchema } = await import("./config-KN6NKKPF.js");
663
663
  const result = ConfigSchema.safeParse(cloned);
664
664
  if (!result.success) {
665
665
  deps.sendJson(res, 400, {
@@ -1113,4 +1113,4 @@ export {
1113
1113
  StaticServer,
1114
1114
  ApiServer
1115
1115
  };
1116
- //# sourceMappingURL=chunk-IXMIC4GQ.js.map
1116
+ //# sourceMappingURL=chunk-BTJHGSLM.js.map
@@ -3,7 +3,7 @@ import {
3
3
  ConfigSchema,
4
4
  applyMigrations,
5
5
  expandHome
6
- } from "./chunk-JOMDPFQ2.js";
6
+ } from "./chunk-W4LK6WJP.js";
7
7
 
8
8
  // src/core/doctor/index.ts
9
9
  import * as fs8 from "fs";
@@ -647,4 +647,4 @@ var DoctorEngine = class {
647
647
  export {
648
648
  DoctorEngine
649
649
  };
650
- //# sourceMappingURL=chunk-43JVXFYP.js.map
650
+ //# sourceMappingURL=chunk-GEOXPGCO.js.map
@@ -66,7 +66,7 @@ function createApiServerPlugin() {
66
66
  },
67
67
  async setup(ctx) {
68
68
  const config = ctx.pluginConfig;
69
- const { ApiServer } = await import("./api-server-WFB5K6FP.js");
69
+ const { ApiServer } = await import("./api-server-JLBDKCU4.js");
70
70
  const apiConfig = {
71
71
  port: config.port ?? 0,
72
72
  host: config.host ?? "127.0.0.1"
@@ -94,4 +94,4 @@ var api_server_default = createApiServerPlugin();
94
94
  export {
95
95
  api_server_default
96
96
  };
97
- //# sourceMappingURL=chunk-JUFN4XMB.js.map
97
+ //# sourceMappingURL=chunk-KDU3ZEWT.js.map
@@ -60,19 +60,26 @@ var ContextManager = class {
60
60
  return null;
61
61
  }
62
62
  async listSessions(query) {
63
- const provider = await this.getProvider(query.repoPath);
64
- if (!provider) return null;
65
- return provider.listSessions(query);
63
+ for (const provider of this.providers) {
64
+ if (!await provider.isAvailable(query.repoPath)) continue;
65
+ const result = await provider.listSessions(query);
66
+ if (result.sessions.length > 0) return result;
67
+ }
68
+ return null;
66
69
  }
67
70
  async buildContext(query, options) {
68
71
  const queryKey = `${query.type}:${query.value}:${options?.limit ?? ""}:${options?.maxTokens ?? ""}`;
69
72
  const cached = this.cache.get(query.repoPath, queryKey);
70
73
  if (cached) return cached;
71
- const provider = await this.getProvider(query.repoPath);
72
- if (!provider) return null;
73
- const result = await provider.buildContext(query, options);
74
- if (result) this.cache.set(query.repoPath, queryKey, result);
75
- return result;
74
+ for (const provider of this.providers) {
75
+ if (!await provider.isAvailable(query.repoPath)) continue;
76
+ const result = await provider.buildContext(query, options);
77
+ if (result && result.markdown) {
78
+ this.cache.set(query.repoPath, queryKey, result);
79
+ return result;
80
+ }
81
+ }
82
+ return null;
76
83
  }
77
84
  };
78
85
 
@@ -533,4 +540,4 @@ export {
533
540
  ContextManager,
534
541
  EntireProvider
535
542
  };
536
- //# sourceMappingURL=chunk-QWP76EBW.js.map
543
+ //# sourceMappingURL=chunk-MITTQMGZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plugins/context/context-manager.ts","../../src/plugins/context/context-cache.ts","../../src/plugins/context/entire/message-cleaner.ts","../../src/plugins/context/entire/conversation-builder.ts","../../src/plugins/context/entire/entire-provider.ts"],"sourcesContent":["import * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { ContextProvider, ContextQuery, ContextOptions, ContextResult, SessionListResult } from \"./context-provider.js\";\nimport { ContextCache } from \"./context-cache.js\";\n\nexport class ContextManager {\n private providers: ContextProvider[] = [];\n private cache: ContextCache;\n\n constructor() {\n this.cache = new ContextCache(path.join(os.homedir(), \".openacp\", \"cache\", \"entire\"));\n }\n\n register(provider: ContextProvider): void {\n this.providers.push(provider);\n }\n\n async getProvider(repoPath: string): Promise<ContextProvider | null> {\n for (const provider of this.providers) {\n if (await provider.isAvailable(repoPath)) return provider;\n }\n return null;\n }\n\n async listSessions(query: ContextQuery): Promise<SessionListResult | null> {\n for (const provider of this.providers) {\n if (!(await provider.isAvailable(query.repoPath))) continue;\n const result = await provider.listSessions(query);\n if (result.sessions.length > 0) return result;\n }\n return null;\n }\n\n async buildContext(query: ContextQuery, options?: ContextOptions): Promise<ContextResult | null> {\n const queryKey = `${query.type}:${query.value}:${options?.limit ?? \"\"}:${options?.maxTokens ?? \"\"}`;\n const cached = this.cache.get(query.repoPath, queryKey);\n if (cached) return cached;\n\n for (const provider of this.providers) {\n if (!(await provider.isAvailable(query.repoPath))) continue;\n const result = await provider.buildContext(query, options);\n if (result && result.markdown) {\n this.cache.set(query.repoPath, queryKey, result);\n return result;\n }\n }\n return null;\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as crypto from \"node:crypto\";\nimport type { ContextResult } from \"./context-provider.js\";\n\nconst DEFAULT_TTL_MS = 60 * 60 * 1000;\n\nexport class ContextCache {\n constructor(private cacheDir: string, private ttlMs: number = DEFAULT_TTL_MS) {\n fs.mkdirSync(cacheDir, { recursive: true });\n }\n\n private keyHash(repoPath: string, queryKey: string): string {\n return crypto.createHash(\"sha256\").update(`${repoPath}:${queryKey}`).digest(\"hex\").slice(0, 16);\n }\n\n private filePath(repoPath: string, queryKey: string): string {\n return path.join(this.cacheDir, `${this.keyHash(repoPath, queryKey)}.json`);\n }\n\n get(repoPath: string, queryKey: string): ContextResult | null {\n const fp = this.filePath(repoPath, queryKey);\n try {\n const stat = fs.statSync(fp);\n if (Date.now() - stat.mtimeMs > this.ttlMs) { fs.unlinkSync(fp); return null; }\n return JSON.parse(fs.readFileSync(fp, \"utf-8\")) as ContextResult;\n } catch { return null; }\n }\n\n set(repoPath: string, queryKey: string, result: ContextResult): void {\n fs.writeFileSync(this.filePath(repoPath, queryKey), JSON.stringify(result));\n }\n}\n","const SYSTEM_TAG_PATTERNS: RegExp[] = [\n /<system-reminder>[\\s\\S]*?<\\/system-reminder>/g,\n /<local-command-caveat>[\\s\\S]*?<\\/local-command-caveat>/g,\n /<local-command-stdout>[\\s\\S]*?<\\/local-command-stdout>/g,\n /<command-name>[\\s\\S]*?<\\/command-name>/g,\n /<command-message>[\\s\\S]*?<\\/command-message>/g,\n /<user-prompt-submit-hook>[\\s\\S]*?<\\/user-prompt-submit-hook>/g,\n /<ide_selection>[\\s\\S]*?<\\/ide_selection>/g,\n /<ide_context>[\\s\\S]*?<\\/ide_context>/g,\n /<ide_opened_file>[\\s\\S]*?<\\/ide_opened_file>/g,\n /<cursor_context>[\\s\\S]*?<\\/cursor_context>/g,\n /<attached_files>[\\s\\S]*?<\\/attached_files>/g,\n /<repo_context>[\\s\\S]*?<\\/repo_context>/g,\n /<task-notification>[\\s\\S]*?<\\/task-notification>/g,\n];\n\nconst COMMAND_ARGS_RE = /<command-args>([\\s\\S]*?)<\\/command-args>/;\n\nexport function cleanSystemTags(text: string): string {\n const argsMatch = COMMAND_ARGS_RE.exec(text);\n const userArgs = argsMatch?.[1]?.trim() ?? \"\";\n text = text.replace(/<command-args>[\\s\\S]*?<\\/command-args>/g, \"\");\n for (const pat of SYSTEM_TAG_PATTERNS) {\n text = text.replace(new RegExp(pat.source, pat.flags), \"\");\n }\n text = text.trim();\n if (!text && userArgs) return userArgs;\n if (text && userArgs && text !== userArgs) return `${text}\\n${userArgs}`;\n return text || userArgs;\n}\n\nconst SKILL_INDICATORS = [\n \"Base directory for this skill:\",\n \"<HARD-GATE>\",\n \"## Checklist\",\n \"## Process Flow\",\n \"## Key Principles\",\n \"digraph brainstorming\",\n \"You MUST create a task for each\",\n];\n\nexport function isSkillPrompt(text: string): boolean {\n for (const indicator of SKILL_INDICATORS) {\n if (text.includes(indicator)) return true;\n }\n if (text.length > 2000) {\n const headerCount = (text.match(/## /g) || []).length;\n if (headerCount >= 3) return true;\n }\n return false;\n}\n\nexport function isNoiseMessage(text: string): boolean {\n const cleaned = cleanSystemTags(text);\n if (!cleaned) return true;\n if (/^(ready|ready\\.)$/i.test(cleaned)) return true;\n if (cleaned.includes(\"Tell your human partner that this command is deprecated\")) return true;\n if (cleaned.startsWith(\"Read the output file to retrieve the result:\")) return true;\n if (/^(opus|sonnet|haiku|claude)(\\[.*\\])?$/i.test(cleaned)) return true;\n return false;\n}\n","import type { ContextMode } from \"../context-provider.js\";\nimport { cleanSystemTags, isSkillPrompt, isNoiseMessage } from \"./message-cleaner.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface AssistantPart {\n type: \"text\" | \"edit\" | \"write\";\n content?: string;\n file?: string;\n old?: string;\n new?: string;\n fileContent?: string;\n}\n\nexport interface Turn {\n userText: string;\n userTimestamp: string;\n assistantParts: AssistantPart[];\n}\n\nexport interface ParseResult {\n turns: Turn[];\n branch: string;\n firstTimestamp: string;\n lastTimestamp: string;\n}\n\nexport interface SessionMarkdownInput {\n markdown: string;\n startTime: string;\n endTime: string;\n agent: string;\n turns: number;\n branch: string;\n files: string[];\n}\n\n// ─── Mode selection ────────────────────────────────────────────────────────────\n\n/**\n * Select rendering mode based on total turn count.\n * ≤10 → full\n * 11-25 → balanced\n * >25 → compact\n */\nexport function selectMode(totalTurns: number): ContextMode {\n if (totalTurns <= 10) return \"full\";\n if (totalTurns <= 25) return \"balanced\";\n return \"compact\";\n}\n\n// ─── Token estimation ─────────────────────────────────────────────────────────\n\nexport function estimateTokens(text: string): number {\n return Math.floor(text.length / 4);\n}\n\n// ─── Path helpers ─────────────────────────────────────────────────────────────\n\nfunction shortenPath(fp: string): string {\n const parts = fp.split(\"/\");\n if (parts.length >= 2) return parts.slice(-2).join(\"/\");\n return fp;\n}\n\nfunction countLines(s: string): number {\n const trimmed = s.trim();\n if (!trimmed) return 0;\n return trimmed.split(\"\\n\").length;\n}\n\n// ─── Content extraction ───────────────────────────────────────────────────────\n\ntype ContentBlock = { type: string; [key: string]: unknown };\n\nfunction extractText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (Array.isArray(content)) {\n return content\n .filter((b): b is ContentBlock => typeof b === \"object\" && b !== null && (b as ContentBlock).type === \"text\")\n .map((b) => (b as unknown as { text: string }).text)\n .join(\"\\n\");\n }\n return \"\";\n}\n\nfunction extractContentBlocks(content: unknown): ContentBlock[] {\n if (typeof content === \"string\") return [{ type: \"text\", text: content }];\n if (Array.isArray(content)) {\n return content.filter((b): b is ContentBlock => typeof b === \"object\" && b !== null);\n }\n return [];\n}\n\nfunction isToolResultOnly(content: unknown): boolean {\n if (typeof content === \"string\") return false;\n if (!Array.isArray(content)) return true;\n for (const block of content) {\n if (typeof block === \"object\" && block !== null) {\n const b = block as ContentBlock;\n if (b.type === \"text\" && typeof b.text === \"string\" && (b.text as string).trim()) return false;\n if (b.type === \"image\") return false;\n }\n }\n return true;\n}\n\nfunction hasImage(content: unknown): boolean {\n if (!Array.isArray(content)) return false;\n return content.some((b) => typeof b === \"object\" && b !== null && (b as ContentBlock).type === \"image\");\n}\n\n// ─── Format functions ─────────────────────────────────────────────────────────\n\nfunction formatEditFull(filePath: string, oldStr: string, newStr: string): string {\n const lines: string[] = [];\n lines.push(`✏️ \\`${filePath}\\``);\n lines.push(\"```diff\");\n for (const line of oldStr.split(\"\\n\")) lines.push(`- ${line}`);\n for (const line of newStr.split(\"\\n\")) lines.push(`+ ${line}`);\n lines.push(\"```\");\n return lines.join(\"\\n\");\n}\n\nfunction formatEditBalanced(filePath: string, oldStr: string, newStr: string, maxDiffLines = 12): string {\n const oldLines = oldStr.split(\"\\n\");\n const newLines = newStr.split(\"\\n\");\n const total = oldLines.length + newLines.length;\n const lines: string[] = [];\n lines.push(`✏️ \\`${filePath}\\``);\n lines.push(\"```diff\");\n if (total <= maxDiffLines) {\n for (const line of oldLines) lines.push(`- ${line}`);\n for (const line of newLines) lines.push(`+ ${line}`);\n } else {\n const half = Math.floor(maxDiffLines / 2);\n for (const line of oldLines.slice(0, half)) lines.push(`- ${line}`);\n if (oldLines.length > half) lines.push(` ... (-${oldLines.length} lines total)`);\n for (const line of newLines.slice(0, half)) lines.push(`+ ${line}`);\n if (newLines.length > half) lines.push(` ... (+${newLines.length} lines total)`);\n }\n lines.push(\"```\");\n return lines.join(\"\\n\");\n}\n\nfunction formatEditCompact(filePath: string, oldStr: string, newStr: string): string {\n const oldLines = countLines(oldStr);\n const newLines = countLines(newStr);\n let firstNew = \"\";\n for (const line of newStr.split(\"\\n\")) {\n const stripped = line.trim();\n if (stripped && !stripped.startsWith(\"//\") && !stripped.startsWith(\"*\")) {\n firstNew = stripped.slice(0, 80);\n break;\n }\n }\n if (firstNew) {\n return `✏️ \\`${filePath}\\` (-${oldLines}/+${newLines} lines): \\`${firstNew}\\``;\n }\n return `✏️ \\`${filePath}\\` (-${oldLines}/+${newLines} lines)`;\n}\n\nfunction formatWriteFull(filePath: string, content: string): string {\n const lines: string[] = [];\n lines.push(`📝 \\`${filePath}\\``);\n lines.push(\"```\");\n lines.push(content);\n lines.push(\"```\");\n return lines.join(\"\\n\");\n}\n\nfunction formatWriteBalanced(filePath: string, content: string, maxLines = 15): string {\n const contentLines = content.split(\"\\n\");\n const lines: string[] = [];\n lines.push(`📝 \\`${filePath}\\` (${contentLines.length} lines)`);\n lines.push(\"```\");\n for (const line of contentLines.slice(0, maxLines)) lines.push(line);\n if (contentLines.length > maxLines) lines.push(`... (${contentLines.length - maxLines} more lines)`);\n lines.push(\"```\");\n return lines.join(\"\\n\");\n}\n\nfunction formatWriteCompact(filePath: string, content: string): string {\n const numLines = countLines(content);\n return `📝 \\`${filePath}\\` (${numLines} lines written)`;\n}\n\n// ─── Parser ───────────────────────────────────────────────────────────────────\n\ninterface RawEvent {\n type?: string;\n message?: { role?: string; content?: unknown };\n timestamp?: string;\n uuid?: string;\n parentUuid?: string | null;\n sessionId?: string;\n gitBranch?: string;\n}\n\nexport function parseJsonlToTurns(jsonl: string): ParseResult {\n const events: RawEvent[] = [];\n for (const rawLine of jsonl.split(\"\\n\")) {\n const line = rawLine.trim();\n if (!line) continue;\n try {\n events.push(JSON.parse(line) as RawEvent);\n } catch {\n // skip invalid JSON lines\n }\n }\n\n // Extract gitBranch from first event that has it\n let branch = \"unknown\";\n for (const e of events) {\n if (e.gitBranch) {\n branch = e.gitBranch;\n break;\n }\n }\n\n const convEvents = events.filter((e) => e.type === \"user\" || e.type === \"assistant\");\n\n const turns: Turn[] = [];\n let currentTurn: Turn | null = null;\n\n for (const e of convEvents) {\n const etype = e.type;\n const content = e.message?.content ?? [];\n const ts = e.timestamp ?? \"\";\n\n if (etype === \"user\") {\n if (isToolResultOnly(content)) continue;\n\n const text = extractText(content);\n\n if (isSkillPrompt(text)) continue;\n if (isNoiseMessage(text)) continue;\n\n const cleaned = cleanSystemTags(text);\n if (!cleaned) continue;\n\n // Push previous turn if any\n if (currentTurn) turns.push(currentTurn);\n\n const imgSuffix = hasImage(content) ? \" [image]\" : \"\";\n currentTurn = {\n userText: cleaned + imgSuffix,\n userTimestamp: ts,\n assistantParts: [],\n };\n } else if (etype === \"assistant\" && currentTurn) {\n const blocks = extractContentBlocks(content);\n let pendingText: string | null = null;\n\n for (const block of blocks) {\n const btype = block.type;\n\n if (btype === \"text\") {\n const text = typeof block.text === \"string\" ? (block.text as string).trim() : \"\";\n if (text) pendingText = text;\n } else if (btype === \"tool_use\") {\n const name = typeof block.name === \"string\" ? block.name : \"\";\n const inp = (typeof block.input === \"object\" && block.input !== null ? block.input : {}) as Record<string, string>;\n\n if (name === \"Edit\") {\n if (pendingText) {\n currentTurn.assistantParts.push({ type: \"text\", content: pendingText });\n pendingText = null;\n }\n currentTurn.assistantParts.push({\n type: \"edit\",\n file: shortenPath(inp.file_path ?? \"\"),\n old: inp.old_string ?? \"\",\n new: inp.new_string ?? \"\",\n });\n } else if (name === \"Write\") {\n if (pendingText) {\n currentTurn.assistantParts.push({ type: \"text\", content: pendingText });\n pendingText = null;\n }\n currentTurn.assistantParts.push({\n type: \"write\",\n file: shortenPath(inp.file_path ?? \"\"),\n fileContent: inp.content ?? \"\",\n });\n }\n // Skip Read, Bash, Grep, Glob, etc.\n }\n }\n\n if (pendingText) {\n currentTurn.assistantParts.push({ type: \"text\", content: pendingText });\n }\n }\n }\n\n if (currentTurn) turns.push(currentTurn);\n\n const firstTimestamp = turns[0]?.userTimestamp ?? \"\";\n const lastTimestamp = turns[turns.length - 1]?.userTimestamp ?? \"\";\n\n return { turns, branch, firstTimestamp, lastTimestamp };\n}\n\n// ─── Markdown builder ─────────────────────────────────────────────────────────\n\nexport function buildSessionMarkdown(turns: Turn[], mode: ContextMode): string {\n const out: string[] = [];\n\n for (let i = 0; i < turns.length; i++) {\n const turn = turns[i];\n const userText = turn.userText.trim();\n if (!userText) continue;\n\n out.push(`**User [${i + 1}]:**`);\n out.push(userText);\n out.push(\"\");\n\n let hasContent = false;\n\n for (const part of turn.assistantParts) {\n if (part.type === \"text\") {\n if (!hasContent) {\n out.push(\"**Assistant:**\");\n hasContent = true;\n }\n out.push(part.content ?? \"\");\n out.push(\"\");\n } else if (part.type === \"edit\") {\n if (!hasContent) {\n out.push(\"**Assistant:**\");\n hasContent = true;\n }\n const file = part.file ?? \"\";\n const oldStr = part.old ?? \"\";\n const newStr = part.new ?? \"\";\n if (mode === \"full\") {\n out.push(formatEditFull(file, oldStr, newStr));\n } else if (mode === \"balanced\") {\n out.push(formatEditBalanced(file, oldStr, newStr));\n } else {\n out.push(formatEditCompact(file, oldStr, newStr));\n }\n out.push(\"\");\n } else if (part.type === \"write\") {\n if (!hasContent) {\n out.push(\"**Assistant:**\");\n hasContent = true;\n }\n const file = part.file ?? \"\";\n const content = part.fileContent ?? \"\";\n if (mode === \"full\") {\n out.push(formatWriteFull(file, content));\n } else if (mode === \"balanced\") {\n out.push(formatWriteBalanced(file, content));\n } else {\n out.push(formatWriteCompact(file, content));\n }\n out.push(\"\");\n }\n }\n\n out.push(\"---\");\n out.push(\"\");\n }\n\n return out.join(\"\\n\");\n}\n\n// ─── Session merger ───────────────────────────────────────────────────────────\n\nconst DISCLAIMER = `> **Note:** This conversation history may contain outdated information. File contents, code, and project state may have changed since these sessions were recorded. Use this as context only — always verify against current files before acting.`;\n\nexport function mergeSessionsMarkdown(\n sessions: SessionMarkdownInput[],\n mode: ContextMode,\n title: string\n): string {\n // Sort sessions chronologically (oldest first)\n const sorted = [...sessions].sort((a, b) => a.startTime.localeCompare(b.startTime));\n\n const totalTurns = sorted.reduce((sum, s) => sum + s.turns, 0);\n const overallStart = sorted[0]?.startTime.slice(0, 16) ?? \"?\";\n const overallEnd = sorted[sorted.length - 1]?.endTime.slice(0, 16) ?? \"?\";\n\n const out: string[] = [];\n out.push(`# Conversation History from ${title}`);\n out.push(`${sorted.length} sessions | ${totalTurns} turns | ${overallStart} → ${overallEnd} | mode: ${mode}`);\n out.push(\"\");\n\n for (let i = 0; i < sorted.length; i++) {\n const s = sorted[i];\n const start = s.startTime.slice(0, 16);\n const end = s.endTime.slice(0, 16);\n out.push(`## Session Conversation History ${i + 1} — ${start} → ${end} (${s.agent}, ${s.turns} turns, branch: ${s.branch})`);\n out.push(\"\");\n out.push(s.markdown);\n }\n\n out.push(DISCLAIMER);\n out.push(\"\");\n\n return out.join(\"\\n\");\n}\n","import type { ContextProvider, ContextQuery, ContextOptions, ContextResult, SessionListResult, SessionInfo } from \"../context-provider.js\";\nimport type { ContextMode } from \"../context-provider.js\";\nimport { DEFAULT_MAX_TOKENS, TOKENS_PER_TURN_ESTIMATE } from \"../context-provider.js\";\nimport { CheckpointReader } from \"./checkpoint-reader.js\";\nimport { parseJsonlToTurns, buildSessionMarkdown, mergeSessionsMarkdown, selectMode, estimateTokens, type SessionMarkdownInput } from \"./conversation-builder.js\";\n\nexport class EntireProvider implements ContextProvider {\n readonly name = \"entire\";\n\n async isAvailable(repoPath: string): Promise<boolean> {\n return new CheckpointReader(repoPath).hasEntireBranch();\n }\n\n async listSessions(query: ContextQuery): Promise<SessionListResult> {\n const reader = new CheckpointReader(query.repoPath);\n const sessions = await this.resolveSessions(reader, query);\n const estimatedTokens = sessions.reduce((sum, s) => sum + s.turnCount * TOKENS_PER_TURN_ESTIMATE, 0);\n return { sessions, estimatedTokens };\n }\n\n async buildContext(query: ContextQuery, options?: ContextOptions): Promise<ContextResult> {\n const maxTokens = options?.maxTokens ?? DEFAULT_MAX_TOKENS;\n const reader = new CheckpointReader(query.repoPath);\n let sessions = await this.resolveSessions(reader, query);\n\n if (options?.limit && sessions.length > options.limit) {\n sessions = sessions.slice(-options.limit);\n }\n\n if (sessions.length === 0) {\n return { markdown: \"\", tokenEstimate: 0, sessionCount: 0, totalTurns: 0, mode: \"full\", truncated: false, timeRange: { start: \"\", end: \"\" } };\n }\n\n // Rebuild each session, cache parsed turns for potential re-render\n const parsedSessions: { session: SessionInfo; jsonl: string; }[] = [];\n for (const sess of sessions) {\n const jsonl = reader.getTranscript(sess.transcriptPath);\n if (jsonl) parsedSessions.push({ session: sess, jsonl });\n }\n\n if (parsedSessions.length === 0) {\n return { markdown: \"\", tokenEstimate: 0, sessionCount: 0, totalTurns: 0, mode: \"full\", truncated: false, timeRange: { start: \"\", end: \"\" } };\n }\n\n const totalTurns = parsedSessions.reduce((sum, ps) => {\n const parsed = parseJsonlToTurns(ps.jsonl);\n return sum + parsed.turns.length;\n }, 0);\n\n let mode = selectMode(totalTurns);\n const title = this.buildTitle(query);\n\n // Build markdown for each session\n let sessionMarkdowns = this.buildSessionMarkdowns(parsedSessions, mode);\n let merged = mergeSessionsMarkdown(sessionMarkdowns, mode, title);\n let tokens = estimateTokens(merged);\n\n // Auto-downgrade to compact if over budget\n if (tokens > maxTokens && mode !== \"compact\") {\n mode = \"compact\";\n sessionMarkdowns = this.buildSessionMarkdowns(parsedSessions, \"compact\");\n merged = mergeSessionsMarkdown(sessionMarkdowns, \"compact\", title);\n tokens = estimateTokens(merged);\n }\n\n // Truncate oldest sessions if still over budget\n let truncated = false;\n while (tokens > maxTokens && sessionMarkdowns.length > 1) {\n sessionMarkdowns = sessionMarkdowns.slice(1);\n truncated = true;\n merged = mergeSessionsMarkdown(sessionMarkdowns, mode, title);\n tokens = estimateTokens(merged);\n }\n\n const allTimes = sessionMarkdowns.flatMap(s => [s.startTime, s.endTime]).filter(Boolean).sort();\n const finalTurns = sessionMarkdowns.reduce((sum, s) => sum + s.turns, 0);\n\n return {\n markdown: merged,\n tokenEstimate: tokens,\n sessionCount: sessionMarkdowns.length,\n totalTurns: finalTurns,\n mode,\n truncated,\n timeRange: { start: allTimes[0] ?? \"\", end: allTimes[allTimes.length - 1] ?? \"\" },\n };\n }\n\n private buildSessionMarkdowns(parsedSessions: { session: SessionInfo; jsonl: string }[], mode: ContextMode): SessionMarkdownInput[] {\n return parsedSessions.map(ps => {\n const parsed = parseJsonlToTurns(ps.jsonl);\n return {\n markdown: buildSessionMarkdown(parsed.turns, mode),\n startTime: parsed.firstTimestamp,\n endTime: parsed.lastTimestamp,\n agent: ps.session.agent,\n turns: parsed.turns.length,\n branch: ps.session.branch,\n files: ps.session.filesTouched.map(f => f.split(\"/\").pop() ?? f),\n };\n });\n }\n\n private async resolveSessions(reader: CheckpointReader, query: ContextQuery): Promise<SessionInfo[]> {\n switch (query.type) {\n case \"branch\": return reader.resolveByBranch(query.value);\n case \"commit\": return reader.resolveByCommit(query.value);\n case \"pr\": return reader.resolveByPr(query.value);\n case \"checkpoint\": return reader.resolveByCheckpoint(query.value);\n case \"session\": return reader.resolveBySessionId(query.value);\n case \"latest\": return reader.resolveLatest(parseInt(query.value) || 5);\n default: return [];\n }\n }\n\n private buildTitle(query: ContextQuery): string {\n switch (query.type) {\n case \"pr\": return `PR #${query.value.replace(/.*\\/pull\\//, \"\")}`;\n case \"branch\": return `branch \\`${query.value}\\``;\n case \"commit\": return `commit \\`${query.value.slice(0, 8)}\\``;\n case \"checkpoint\": return `checkpoint \\`${query.value}\\``;\n case \"session\": return `session \\`${query.value.slice(0, 8)}...\\``;\n case \"latest\": return `latest ${query.value} sessions`;\n default: return \"unknown\";\n }\n }\n}\n"],"mappings":"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","names":["path"]}
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-2R5XM3ES.js";
7
7
  import {
8
8
  expandHome
9
- } from "./chunk-JOMDPFQ2.js";
9
+ } from "./chunk-W4LK6WJP.js";
10
10
 
11
11
  // src/core/config/config-editor.ts
12
12
  import * as os from "os";
@@ -167,7 +167,7 @@ async function ensureDiscordPlugin() {
167
167
  }
168
168
  try {
169
169
  console.log(dim(`Installing ${DISCORD_PACKAGE}...`));
170
- const { installNpmPlugin } = await import("./plugin-installer-5XHORMLS.js");
170
+ const { installNpmPlugin } = await import("./plugin-installer-VSTYZSXC.js");
171
171
  const mod = await installNpmPlugin(DISCORD_PACKAGE);
172
172
  console.log(ok(`${DISCORD_PACKAGE} installed`));
173
173
  return mod;
@@ -676,4 +676,4 @@ function flattenToPaths(obj, prefix = "") {
676
676
  export {
677
677
  runConfigEditor
678
678
  };
679
- //# sourceMappingURL=chunk-QBEQJFGL.js.map
679
+ //# sourceMappingURL=chunk-MPGEHTGE.js.map
@@ -112,11 +112,15 @@ function createTunnelPlugin() {
112
112
  },
113
113
  async setup(ctx) {
114
114
  const config = ctx.pluginConfig;
115
+ if (!config.enabled) {
116
+ ctx.log.info("Tunnel disabled");
117
+ return;
118
+ }
115
119
  if (!config.provider) {
116
120
  ctx.log.info("Tunnel disabled (no provider configured)");
117
121
  return;
118
122
  }
119
- const { TunnelService } = await import("./tunnel-service-I2NFUX3V.js");
123
+ const { TunnelService } = await import("./tunnel-service-ZMO4THKE.js");
120
124
  const tunnelSvc = new TunnelService(config);
121
125
  const publicUrl = await tunnelSvc.start();
122
126
  service = tunnelSvc;
@@ -183,4 +187,4 @@ var tunnel_default = createTunnelPlugin();
183
187
  export {
184
188
  tunnel_default
185
189
  };
186
- //# sourceMappingURL=chunk-4B6PCWQP.js.map
190
+ //# sourceMappingURL=chunk-PA6MNBG4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plugins/tunnel/index.ts"],"sourcesContent":["import type { OpenACPPlugin, InstallContext } from '../../core/plugin/types.js'\nimport type { TunnelConfig } from '../../core/config/config.js'\n\nfunction createTunnelPlugin(): OpenACPPlugin {\n let service: { stop(): Promise<void> } | null = null\n\n return {\n name: '@openacp/tunnel',\n version: '1.0.0',\n description: 'Expose local services to internet via tunnel providers',\n essential: false,\n permissions: ['services:register', 'kernel:access', 'commands:register'],\n\n async install(ctx: InstallContext) {\n const { terminal, settings, legacyConfig } = ctx\n\n // Migrate from legacy config if present\n if (legacyConfig) {\n const tunnelCfg = legacyConfig.tunnel as Record<string, unknown> | undefined\n if (tunnelCfg) {\n await settings.setAll({\n enabled: tunnelCfg.enabled ?? true,\n provider: tunnelCfg.provider ?? 'cloudflare',\n port: tunnelCfg.port ?? 3100,\n options: tunnelCfg.options ?? {},\n maxUserTunnels: tunnelCfg.maxUserTunnels ?? 5,\n storeTtlMinutes: tunnelCfg.storeTtlMinutes ?? 60,\n auth: tunnelCfg.auth ?? { enabled: false },\n })\n terminal.log.success('Tunnel settings migrated from legacy config')\n return\n }\n }\n\n // Interactive setup\n const provider = await terminal.select({\n message: 'Tunnel provider:',\n options: [\n { value: 'cloudflare', label: 'Cloudflare (cloudflared)', hint: 'Free, no account needed' },\n { value: 'ngrok', label: 'ngrok', hint: 'Requires auth token' },\n { value: 'bore', label: 'bore', hint: 'Self-hostable' },\n { value: 'tailscale', label: 'Tailscale Funnel' },\n ],\n })\n\n const portStr = await terminal.text({\n message: 'Local port to expose:',\n defaultValue: '3100',\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || n < 1 || n > 65535) return 'Port must be 1-65535'\n return undefined\n },\n })\n\n let authToken = ''\n if (provider === 'ngrok') {\n authToken = await terminal.text({\n message: 'ngrok auth token:',\n validate: (v) => (!v.trim() ? 'Auth token cannot be empty' : undefined),\n })\n authToken = authToken.trim()\n }\n\n await settings.setAll({\n enabled: true,\n provider,\n port: Number(portStr.trim()),\n options: authToken ? { authtoken: authToken } : {},\n maxUserTunnels: 5,\n storeTtlMinutes: 60,\n auth: { enabled: false },\n })\n terminal.log.success('Tunnel settings saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const choice = await terminal.select({\n message: 'What to configure?',\n options: [\n { value: 'provider', label: `Change provider (current: ${current.provider ?? 'none'})` },\n { value: 'port', label: `Change port (current: ${current.port ?? 3100})` },\n { value: 'toggle', label: `${current.enabled ? 'Disable' : 'Enable'} tunnel` },\n { value: 'done', label: 'Done' },\n ],\n })\n\n if (choice === 'provider') {\n const provider = await terminal.select({\n message: 'Tunnel provider:',\n options: [\n { value: 'cloudflare', label: 'Cloudflare' },\n { value: 'ngrok', label: 'ngrok' },\n { value: 'bore', label: 'bore' },\n { value: 'tailscale', label: 'Tailscale' },\n ],\n })\n await settings.set('provider', provider)\n terminal.log.success('Provider updated')\n } else if (choice === 'port') {\n const val = await terminal.text({\n message: 'New port:',\n defaultValue: String(current.port ?? 3100),\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || n < 1 || n > 65535) return 'Port must be 1-65535'\n return undefined\n },\n })\n await settings.set('port', Number(val.trim()))\n terminal.log.success('Port updated')\n } else if (choice === 'toggle') {\n const newState = !current.enabled\n await settings.set('enabled', newState)\n terminal.log.success(`Tunnel ${newState ? 'enabled' : 'disabled'}`)\n }\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('Tunnel settings cleared')\n }\n },\n\n async setup(ctx) {\n const config = ctx.pluginConfig as Record<string, unknown>\n if (!config.enabled) {\n ctx.log.info('Tunnel disabled')\n return\n }\n if (!config.provider) {\n ctx.log.info('Tunnel disabled (no provider configured)')\n return\n }\n\n const { TunnelService } = await import('./tunnel-service.js')\n const tunnelSvc = new TunnelService(config as unknown as TunnelConfig)\n const publicUrl = await tunnelSvc.start()\n service = tunnelSvc\n\n ctx.registerService('tunnel', tunnelSvc)\n\n ctx.registerCommand({\n name: 'tunnel',\n description: 'Manage tunnels: /tunnel <port> [label] | /tunnel stop <port>',\n category: 'plugin',\n handler: async (args) => {\n const parts = args.raw.trim().split(/\\s+/)\n\n // /tunnel stop <port>\n if (parts[0] === 'stop' && parts[1]) {\n const port = parseInt(parts[1], 10)\n if (isNaN(port)) return { type: 'error', message: 'Invalid port number' }\n try {\n await tunnelSvc.stopTunnel(port)\n return { type: 'text', text: `Tunnel on port ${port} stopped.` }\n } catch (err) {\n return { type: 'error', message: (err as Error).message }\n }\n }\n\n // /tunnel <port> [label]\n if (parts[0] && parts[0] !== '') {\n const port = parseInt(parts[0], 10)\n if (isNaN(port)) return { type: 'error', message: 'Invalid port number' }\n const label = parts.slice(1).join(' ') || undefined\n try {\n const entry = await tunnelSvc.addTunnel(port, { label })\n return { type: 'text', text: `Tunnel created: ${entry.publicUrl ?? 'starting...'}` }\n } catch (err) {\n return { type: 'error', message: (err as Error).message }\n }\n }\n\n // /tunnel (no args) — show current tunnel URL\n const url = tunnelSvc.getPublicUrl()\n return { type: 'text', text: url ? `Tunnel: ${url}` : 'No tunnel active.' }\n },\n })\n\n ctx.registerCommand({\n name: 'tunnels',\n description: 'List active tunnels',\n category: 'plugin',\n handler: async () => {\n const userTunnels = tunnelSvc.listTunnels()\n const systemUrl = tunnelSvc.getPublicUrl()\n const items = [\n { label: 'System', detail: systemUrl },\n ...userTunnels.map(t => ({\n label: t.label ?? `Port ${t.port}`,\n detail: `${t.publicUrl ?? t.status} (${t.provider})`,\n })),\n ]\n return { type: 'list', title: 'Active Tunnels', items }\n },\n })\n\n ctx.log.info(`Tunnel ready: ${publicUrl}`)\n },\n\n async teardown() {\n if (service) {\n await service.stop()\n }\n },\n }\n}\n\nexport default createTunnelPlugin()\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  expandHome
3
- } from "./chunk-JOMDPFQ2.js";
3
+ } from "./chunk-W4LK6WJP.js";
4
4
 
5
5
  // src/cli/daemon.ts
6
6
  import { spawn } from "child_process";
@@ -169,4 +169,4 @@ export {
169
169
  clearRunning,
170
170
  shouldAutoStart
171
171
  };
172
- //# sourceMappingURL=chunk-VD3QSMVY.js.map
172
+ //# sourceMappingURL=chunk-QWVHCTCA.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  installNpmPlugin
3
- } from "./chunk-I53NEV3S.js";
3
+ } from "./chunk-5WGVYX3C.js";
4
4
  import {
5
5
  GroqSTT,
6
6
  SpeechService
@@ -225,4 +225,4 @@ var speech_default = speechPlugin;
225
225
  export {
226
226
  speech_default
227
227
  };
228
- //# sourceMappingURL=chunk-NT6FYV27.js.map
228
+ //# sourceMappingURL=chunk-TMVTSWVH.js.map