@openacp/cli 2026.331.1 → 2026.331.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 (182) hide show
  1. package/README.md +2 -1
  2. package/dist/cli.js +24987 -270
  3. package/dist/cli.js.map +1 -1
  4. package/dist/data/registry-snapshot.json +1 -1
  5. package/dist/index.d.ts +10 -0
  6. package/dist/index.js +17669 -406
  7. package/dist/index.js.map +1 -1
  8. package/package.json +2 -2
  9. package/dist/adapter-ELG3VRZ3.js +0 -14
  10. package/dist/adapter-ELG3VRZ3.js.map +0 -1
  11. package/dist/agent-catalog-UYD26QDK.js +0 -10
  12. package/dist/agent-catalog-UYD26QDK.js.map +0 -1
  13. package/dist/agent-dependencies-ED2ZTUHG.js +0 -23
  14. package/dist/agent-dependencies-ED2ZTUHG.js.map +0 -1
  15. package/dist/agent-registry-YOGP656W.js +0 -8
  16. package/dist/agent-registry-YOGP656W.js.map +0 -1
  17. package/dist/agent-store-5UHZH2XI.js +0 -8
  18. package/dist/agent-store-5UHZH2XI.js.map +0 -1
  19. package/dist/api-client-PEMHYL5U.js +0 -13
  20. package/dist/api-client-PEMHYL5U.js.map +0 -1
  21. package/dist/api-server-DATG2KBR.js +0 -10
  22. package/dist/api-server-DATG2KBR.js.map +0 -1
  23. package/dist/api-server-L5Z7XACW.js +0 -7
  24. package/dist/api-server-L5Z7XACW.js.map +0 -1
  25. package/dist/autostart-CUPZMKKC.js +0 -22
  26. package/dist/autostart-CUPZMKKC.js.map +0 -1
  27. package/dist/chunk-23SRIVG4.js +0 -50
  28. package/dist/chunk-23SRIVG4.js.map +0 -1
  29. package/dist/chunk-2KT6TROD.js +0 -129
  30. package/dist/chunk-2KT6TROD.js.map +0 -1
  31. package/dist/chunk-2R5XM3ES.js +0 -154
  32. package/dist/chunk-2R5XM3ES.js.map +0 -1
  33. package/dist/chunk-3EWTPOF7.js +0 -51
  34. package/dist/chunk-3EWTPOF7.js.map +0 -1
  35. package/dist/chunk-566W6INH.js +0 -83
  36. package/dist/chunk-566W6INH.js.map +0 -1
  37. package/dist/chunk-5WGVYX3C.js +0 -55
  38. package/dist/chunk-5WGVYX3C.js.map +0 -1
  39. package/dist/chunk-7GXEMMEV.js +0 -44
  40. package/dist/chunk-7GXEMMEV.js.map +0 -1
  41. package/dist/chunk-7U6IZIJP.js +0 -186
  42. package/dist/chunk-7U6IZIJP.js.map +0 -1
  43. package/dist/chunk-7YIKTRSM.js +0 -105
  44. package/dist/chunk-7YIKTRSM.js.map +0 -1
  45. package/dist/chunk-7ZCQF6QM.js +0 -27
  46. package/dist/chunk-7ZCQF6QM.js.map +0 -1
  47. package/dist/chunk-AFKX424Q.js +0 -92
  48. package/dist/chunk-AFKX424Q.js.map +0 -1
  49. package/dist/chunk-BYCJQPMN.js +0 -543
  50. package/dist/chunk-BYCJQPMN.js.map +0 -1
  51. package/dist/chunk-CDAUYTVP.js +0 -41
  52. package/dist/chunk-CDAUYTVP.js.map +0 -1
  53. package/dist/chunk-EWVXSTQK.js +0 -6544
  54. package/dist/chunk-EWVXSTQK.js.map +0 -1
  55. package/dist/chunk-FNRSWA2K.js +0 -1
  56. package/dist/chunk-FNRSWA2K.js.map +0 -1
  57. package/dist/chunk-FPKQYCQS.js +0 -776
  58. package/dist/chunk-FPKQYCQS.js.map +0 -1
  59. package/dist/chunk-IZ5UEZF7.js +0 -138
  60. package/dist/chunk-IZ5UEZF7.js.map +0 -1
  61. package/dist/chunk-K6UY5M75.js +0 -653
  62. package/dist/chunk-K6UY5M75.js.map +0 -1
  63. package/dist/chunk-KGAQW6F4.js +0 -106
  64. package/dist/chunk-KGAQW6F4.js.map +0 -1
  65. package/dist/chunk-LGFWH3AE.js +0 -26
  66. package/dist/chunk-LGFWH3AE.js.map +0 -1
  67. package/dist/chunk-LRV56K2M.js +0 -4106
  68. package/dist/chunk-LRV56K2M.js.map +0 -1
  69. package/dist/chunk-MDJHCCFS.js +0 -485
  70. package/dist/chunk-MDJHCCFS.js.map +0 -1
  71. package/dist/chunk-MLF4W5R6.js +0 -101
  72. package/dist/chunk-MLF4W5R6.js.map +0 -1
  73. package/dist/chunk-NHD5XDD2.js +0 -686
  74. package/dist/chunk-NHD5XDD2.js.map +0 -1
  75. package/dist/chunk-NJX75BLK.js +0 -259
  76. package/dist/chunk-NJX75BLK.js.map +0 -1
  77. package/dist/chunk-NOEAJNTK.js +0 -156
  78. package/dist/chunk-NOEAJNTK.js.map +0 -1
  79. package/dist/chunk-ON7HB5O7.js +0 -58
  80. package/dist/chunk-ON7HB5O7.js.map +0 -1
  81. package/dist/chunk-OSBZXY2W.js +0 -126
  82. package/dist/chunk-OSBZXY2W.js.map +0 -1
  83. package/dist/chunk-OYSAN7UX.js +0 -15
  84. package/dist/chunk-OYSAN7UX.js.map +0 -1
  85. package/dist/chunk-P3HHJANC.js +0 -209
  86. package/dist/chunk-P3HHJANC.js.map +0 -1
  87. package/dist/chunk-R2YLDQLI.js +0 -1115
  88. package/dist/chunk-R2YLDQLI.js.map +0 -1
  89. package/dist/chunk-R6KZYF7D.js +0 -231
  90. package/dist/chunk-R6KZYF7D.js.map +0 -1
  91. package/dist/chunk-S64CB6J3.js +0 -98
  92. package/dist/chunk-S64CB6J3.js.map +0 -1
  93. package/dist/chunk-SSLVNCEA.js +0 -236
  94. package/dist/chunk-SSLVNCEA.js.map +0 -1
  95. package/dist/chunk-TGP34LQN.js +0 -681
  96. package/dist/chunk-TGP34LQN.js.map +0 -1
  97. package/dist/chunk-VUSCVRJL.js +0 -229
  98. package/dist/chunk-VUSCVRJL.js.map +0 -1
  99. package/dist/chunk-W26AUH5B.js +0 -61
  100. package/dist/chunk-W26AUH5B.js.map +0 -1
  101. package/dist/chunk-WQCJTU2C.js +0 -84
  102. package/dist/chunk-WQCJTU2C.js.map +0 -1
  103. package/dist/chunk-XRJUS6FE.js +0 -53
  104. package/dist/chunk-XRJUS6FE.js.map +0 -1
  105. package/dist/chunk-YZCKSNRN.js +0 -453
  106. package/dist/chunk-YZCKSNRN.js.map +0 -1
  107. package/dist/chunk-ZIRH6QWW.js +0 -69
  108. package/dist/chunk-ZIRH6QWW.js.map +0 -1
  109. package/dist/chunk-ZSLHHQPQ.js +0 -282
  110. package/dist/chunk-ZSLHHQPQ.js.map +0 -1
  111. package/dist/config-X4UP7H6R.js +0 -13
  112. package/dist/config-X4UP7H6R.js.map +0 -1
  113. package/dist/config-editor-7BENRVG5.js +0 -11
  114. package/dist/config-editor-7BENRVG5.js.map +0 -1
  115. package/dist/config-registry-M3FFWEVM.js +0 -18
  116. package/dist/config-registry-M3FFWEVM.js.map +0 -1
  117. package/dist/context-FVGCU5TI.js +0 -9
  118. package/dist/context-FVGCU5TI.js.map +0 -1
  119. package/dist/core-plugins-JSY2I44L.js +0 -25
  120. package/dist/core-plugins-JSY2I44L.js.map +0 -1
  121. package/dist/daemon-UOSRDEXW.js +0 -34
  122. package/dist/daemon-UOSRDEXW.js.map +0 -1
  123. package/dist/dev-loader-7P3HZCIA.js +0 -37
  124. package/dist/dev-loader-7P3HZCIA.js.map +0 -1
  125. package/dist/doctor-6DLACBR4.js +0 -10
  126. package/dist/doctor-6DLACBR4.js.map +0 -1
  127. package/dist/file-service-FQQYME7M.js +0 -8
  128. package/dist/file-service-FQQYME7M.js.map +0 -1
  129. package/dist/install-cloudflared-LNS5L5FR.js +0 -33
  130. package/dist/install-cloudflared-LNS5L5FR.js.map +0 -1
  131. package/dist/install-context-KZO5FR4D.js +0 -78
  132. package/dist/install-context-KZO5FR4D.js.map +0 -1
  133. package/dist/install-jq-SN4IA5K4.js +0 -31
  134. package/dist/install-jq-SN4IA5K4.js.map +0 -1
  135. package/dist/instance-context-FLCE7VZ4.js +0 -13
  136. package/dist/instance-context-FLCE7VZ4.js.map +0 -1
  137. package/dist/instance-registry-SW5FWKHO.js +0 -7
  138. package/dist/instance-registry-SW5FWKHO.js.map +0 -1
  139. package/dist/integrate-JIEZYDOR.js +0 -371
  140. package/dist/integrate-JIEZYDOR.js.map +0 -1
  141. package/dist/log-YZ243M5G.js +0 -25
  142. package/dist/log-YZ243M5G.js.map +0 -1
  143. package/dist/main-D7M2AKRM.js +0 -697
  144. package/dist/main-D7M2AKRM.js.map +0 -1
  145. package/dist/menu-ALFN37IR.js +0 -15
  146. package/dist/menu-ALFN37IR.js.map +0 -1
  147. package/dist/notifications-MO23S7S3.js +0 -8
  148. package/dist/notifications-MO23S7S3.js.map +0 -1
  149. package/dist/plugin-create-HFKS23JY.js +0 -968
  150. package/dist/plugin-create-HFKS23JY.js.map +0 -1
  151. package/dist/plugin-installer-VSTYZSXC.js +0 -9
  152. package/dist/plugin-installer-VSTYZSXC.js.map +0 -1
  153. package/dist/plugin-registry-6J3YSFHF.js +0 -7
  154. package/dist/plugin-registry-6J3YSFHF.js.map +0 -1
  155. package/dist/plugin-search-MGKAL5JM.js +0 -39
  156. package/dist/plugin-search-MGKAL5JM.js.map +0 -1
  157. package/dist/post-upgrade-F4YPMTUT.js +0 -79
  158. package/dist/post-upgrade-F4YPMTUT.js.map +0 -1
  159. package/dist/read-text-file-DJBTITIB.js +0 -7
  160. package/dist/read-text-file-DJBTITIB.js.map +0 -1
  161. package/dist/registry-client-GTBWLXYU.js +0 -7
  162. package/dist/registry-client-GTBWLXYU.js.map +0 -1
  163. package/dist/security-O4XGN2CM.js +0 -8
  164. package/dist/security-O4XGN2CM.js.map +0 -1
  165. package/dist/settings-manager-B4UN2LAC.js +0 -7
  166. package/dist/settings-manager-B4UN2LAC.js.map +0 -1
  167. package/dist/setup-44WLBIOT.js +0 -989
  168. package/dist/setup-44WLBIOT.js.map +0 -1
  169. package/dist/speech-GHTSWDAN.js +0 -9
  170. package/dist/speech-GHTSWDAN.js.map +0 -1
  171. package/dist/suggest-RST5VOHB.js +0 -36
  172. package/dist/suggest-RST5VOHB.js.map +0 -1
  173. package/dist/telegram-D7ASLVEB.js +0 -7
  174. package/dist/telegram-D7ASLVEB.js.map +0 -1
  175. package/dist/tunnel-ALJDPFDQ.js +0 -10
  176. package/dist/tunnel-ALJDPFDQ.js.map +0 -1
  177. package/dist/tunnel-service-TBAHDXMF.js +0 -755
  178. package/dist/tunnel-service-TBAHDXMF.js.map +0 -1
  179. package/dist/validators-GITLOFXC.js +0 -11
  180. package/dist/validators-GITLOFXC.js.map +0 -1
  181. package/dist/version-AXXV6IV2.js +0 -15
  182. package/dist/version-AXXV6IV2.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/plugins/context/index.ts","../../src/plugins/context/history/history-context-builder.ts","../../src/plugins/context/history/history-provider.ts","../../src/plugins/context/history/history-recorder.ts","../../src/plugins/context/history/history-store.ts"],"sourcesContent":["import * as path from 'node:path'\nimport type { OpenACPPlugin, InstallContext } from '../../core/plugin/types.js'\nimport type { SessionRecord } from '../../core/types.js'\nimport { ContextManager } from './context-manager.js'\nimport { EntireProvider } from './entire/entire-provider.js'\nimport { HistoryProvider } from './history/history-provider.js'\nimport { HistoryRecorder } from './history/history-recorder.js'\nimport { HistoryStore } from './history/history-store.js'\n\nconst contextPlugin: OpenACPPlugin = {\n name: '@openacp/context',\n version: '1.0.0',\n description: 'Conversation context management with pluggable providers',\n essential: false,\n permissions: ['services:register', 'middleware:register', 'kernel:access'],\n\n async install(ctx: InstallContext) {\n const { settings, terminal } = ctx\n\n // No interactive prompts needed — save defaults\n await settings.setAll({ enabled: true })\n terminal.log.success('Context defaults saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const toggle = await terminal.confirm({\n message: `Context service is ${current.enabled !== false ? 'enabled' : 'disabled'}. Toggle?`,\n initialValue: false,\n })\n if (toggle) {\n const newState = current.enabled === false\n await settings.set('enabled', newState)\n terminal.log.success(`Context service ${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('Context settings cleared')\n }\n },\n\n async setup(ctx) {\n // History recording and context\n const historyDir = path.join(ctx.instanceRoot, 'history')\n const store = new HistoryStore(historyDir)\n const recorder = new HistoryRecorder(store)\n\n // Access session records via SessionManager (kernel:access)\n const sessionManager = ctx.sessions as { listRecords(): SessionRecord[] }\n const getRecords = () => sessionManager.listRecords()\n\n // Register providers — local first (priority), entire as fallback\n const cachePath = path.join(ctx.instanceRoot, 'cache', 'entire')\n const manager = new ContextManager(cachePath)\n manager.register(new HistoryProvider(store, getRecords))\n manager.register(new EntireProvider())\n ctx.registerService('context', manager)\n\n // Middleware: capture user prompts\n ctx.registerMiddleware('agent:beforePrompt', {\n priority: 200,\n handler: async (payload, next) => {\n recorder.onBeforePrompt(payload.sessionId, payload.text, payload.attachments)\n return next()\n },\n })\n\n // Middleware: capture agent events\n ctx.registerMiddleware('agent:afterEvent', {\n priority: 200,\n handler: async (payload, next) => {\n recorder.onAfterEvent(payload.sessionId, payload.event)\n return next()\n },\n })\n\n // Middleware: finalize turn and write to disk\n ctx.registerMiddleware('turn:end', {\n priority: 200,\n handler: async (payload, next) => {\n await recorder.onTurnEnd(payload.sessionId, payload.stopReason)\n return next()\n },\n })\n\n // Middleware: capture permission resolutions\n ctx.registerMiddleware('permission:afterResolve', {\n priority: 200,\n handler: async (payload, next) => {\n recorder.onPermissionResolved(payload.sessionId, payload.requestId, payload.decision)\n return next()\n },\n })\n\n // Middleware: clean up recorder memory on session destroy\n ctx.registerMiddleware('session:afterDestroy', {\n priority: 200,\n handler: async (payload, next) => {\n recorder.finalize(payload.sessionId)\n return next()\n },\n })\n\n ctx.log.info('Context service ready (local history + entire providers)')\n },\n}\n\nexport default contextPlugin\n","import type { ContextMode } from \"../context-provider.js\";\nimport type { Turn, Step, ToolCallStep } from \"./types.js\";\n\nexport function selectLevel(turnCount: number): ContextMode {\n if (turnCount <= 10) return \"full\";\n if (turnCount <= 25) return \"balanced\";\n return \"compact\";\n}\n\nexport function estimateTokens(text: string): number {\n return Math.floor(text.length / 4);\n}\n\nexport function buildHistoryMarkdown(turns: Turn[], mode: ContextMode): string {\n if (turns.length === 0) return \"\";\n switch (mode) {\n case \"full\":\n return buildFull(turns);\n case \"balanced\":\n return buildBalanced(turns);\n case \"compact\":\n return buildCompact(turns);\n }\n}\n\n// ─── Full Mode ───────────────────────────────────────────────────────────────\n\nfunction buildFull(turns: Turn[]): string {\n const out: string[] = [];\n let userIndex = 0;\n\n for (const turn of turns) {\n if (turn.role === \"user\") {\n userIndex++;\n out.push(`**User [${userIndex}]:**`);\n out.push(turn.content ?? \"\");\n if (turn.attachments?.length) {\n out.push(turn.attachments.map((a) => `[${a.type}: ${a.fileName}]`).join(\" \"));\n }\n out.push(\"\");\n } else if (turn.role === \"assistant\" && turn.steps?.length) {\n out.push(\"**Assistant:**\");\n\n for (const step of turn.steps) {\n out.push(renderStepFull(step));\n }\n\n if (turn.usage) {\n const parts: string[] = [];\n if (turn.usage.tokensUsed) parts.push(`${turn.usage.tokensUsed.toLocaleString()} tokens`);\n if (turn.usage.cost) parts.push(`$${turn.usage.cost.amount.toFixed(4)}`);\n if (parts.length) out.push(`**Usage**: ${parts.join(\", \")}`);\n }\n\n out.push(\"\");\n out.push(\"---\");\n out.push(\"\");\n }\n }\n\n return out.join(\"\\n\");\n}\n\nfunction renderStepFull(step: Step): string {\n switch (step.type) {\n case \"thinking\":\n return `> **Thinking**: ${step.content}\\n`;\n case \"text\":\n return `${step.content}\\n`;\n case \"tool_call\":\n return renderToolCallFull(step);\n case \"plan\":\n return renderPlan(step.entries);\n case \"image\":\n return `[Image: ${step.mimeType}]\\n`;\n case \"audio\":\n return `[Audio: ${step.mimeType}]\\n`;\n case \"resource\":\n return `[Resource: ${step.name}] ${step.uri}\\n`;\n case \"resource_link\":\n return `[Resource Link: ${step.name}] ${step.uri}\\n`;\n case \"mode_change\":\n return `*Mode changed to: ${step.modeId}*\\n`;\n case \"config_change\":\n return `*Config ${step.configId} set to: ${step.value}*\\n`;\n }\n}\n\nfunction renderToolCallFull(step: ToolCallStep): string {\n const lines: string[] = [];\n const loc = step.locations?.[0];\n const locStr = loc ? (loc.line ? `${loc.path}:${loc.line}` : loc.path) : \"\";\n\n if (step.diff) {\n lines.push(`**[${step.name}]** \\`${locStr || step.diff.path}\\``);\n lines.push(\"```diff\");\n if (step.diff.oldText) {\n for (const line of step.diff.oldText.split(\"\\n\")) lines.push(`- ${line}`);\n }\n for (const line of step.diff.newText.split(\"\\n\")) lines.push(`+ ${line}`);\n lines.push(\"```\");\n } else {\n lines.push(`**[${step.name}]** \\`${locStr}\\``);\n }\n\n if (step.permission) {\n lines.push(`*Permission: ${step.permission.outcome}*`);\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\nfunction renderPlan(entries: { content: string; priority: string; status: string }[]): string {\n const lines = [\"**Plan:**\"];\n for (const e of entries) {\n const icon = e.status === \"completed\" || e.status === \"done\" ? \"✅\" : e.status === \"in_progress\" ? \"🔄\" : \"⬜\";\n lines.push(`${icon} ${e.content} (${e.priority})`);\n }\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n// ─── Balanced Mode ───────────────────────────────────────────────────────────\n\nfunction buildBalanced(turns: Turn[]): string {\n const out: string[] = [];\n let userIndex = 0;\n\n for (const turn of turns) {\n if (turn.role === \"user\") {\n userIndex++;\n out.push(`**User [${userIndex}]:**`);\n out.push(turn.content ?? \"\");\n out.push(\"\");\n } else if (turn.role === \"assistant\" && turn.steps?.length) {\n out.push(\"**Assistant:**\");\n\n for (const step of turn.steps) {\n if (step.type === \"thinking\") continue;\n\n if (step.type === \"text\") {\n out.push(step.content);\n } else if (step.type === \"tool_call\") {\n out.push(renderToolCallBalanced(step));\n } else if (step.type === \"plan\") {\n out.push(renderPlan(step.entries));\n } else {\n out.push(renderStepFull(step));\n }\n }\n\n out.push(\"\");\n out.push(\"---\");\n out.push(\"\");\n }\n }\n\n return out.join(\"\\n\");\n}\n\nfunction renderToolCallBalanced(step: ToolCallStep): string {\n const loc = step.locations?.[0];\n const locStr = loc ? (loc.line ? `${loc.path}:${loc.line}` : loc.path) : \"\";\n\n if (step.diff) {\n const oldLines = step.diff.oldText?.split(\"\\n\").length ?? 0;\n const newLines = step.diff.newText.split(\"\\n\").length;\n return `- ${step.name} \\`${locStr || step.diff.path}\\` (-${oldLines}/+${newLines} lines)`;\n }\n\n return `- ${step.name} \\`${locStr}\\``;\n}\n\n// ─── Compact Mode ────────────────────────────────────────────────────────────\n\nfunction buildCompact(turns: Turn[]): string {\n const out: string[] = [];\n let i = 0;\n\n while (i < turns.length) {\n const turn = turns[i];\n if (turn.role === \"user\") {\n const userText = (turn.content ?? \"\").slice(0, 100);\n const nextTurn = turns[i + 1];\n if (nextTurn?.role === \"assistant\" && nextTurn.steps?.length) {\n const tools = nextTurn.steps\n .filter((s) => s.type === \"tool_call\")\n .map((s) => (s as ToolCallStep).name);\n const texts = nextTurn.steps\n .filter((s) => s.type === \"text\")\n .map((s) => (s as { content: string }).content.slice(0, 80));\n const parts: string[] = [];\n if (tools.length) parts.push(tools.join(\", \"));\n if (texts.length) parts.push(texts.join(\" \"));\n out.push(`User: ${userText} → Assistant: ${parts.join(\" | \")}`);\n i += 2;\n } else {\n out.push(`User: ${userText}`);\n i++;\n }\n } else {\n i++;\n }\n }\n\n return out.join(\"\\n\");\n}\n","import type { SessionRecord } from \"../../../core/types.js\";\nimport type {\n ContextProvider,\n ContextQuery,\n ContextOptions,\n ContextResult,\n ContextMode,\n SessionInfo,\n SessionListResult,\n} from \"../context-provider.js\";\nimport { DEFAULT_MAX_TOKENS, TOKENS_PER_TURN_ESTIMATE } from \"../context-provider.js\";\nimport { HistoryStore } from \"./history-store.js\";\nimport {\n buildHistoryMarkdown,\n selectLevel,\n estimateTokens,\n} from \"./history-context-builder.js\";\n\nconst EMPTY_RESULT: ContextResult = {\n markdown: \"\",\n tokenEstimate: 0,\n sessionCount: 0,\n totalTurns: 0,\n mode: \"full\",\n truncated: false,\n timeRange: { start: \"\", end: \"\" },\n};\n\nexport class HistoryProvider implements ContextProvider {\n readonly name = \"local\";\n\n constructor(\n private readonly store: HistoryStore,\n private readonly getSessionRecords: () => SessionRecord[]\n ) {}\n\n async isAvailable(_repoPath: string): Promise<boolean> {\n return true;\n }\n\n async listSessions(query: ContextQuery): Promise<SessionListResult> {\n if (!this.isSupportedType(query.type)) {\n return { sessions: [], estimatedTokens: 0 };\n }\n\n const candidates = await this.resolveCandidates(query);\n const sessions: SessionInfo[] = [];\n let estimatedTokens = 0;\n\n for (const record of candidates) {\n const history = await this.store.read(record.sessionId);\n if (!history) continue;\n const turnCount = history.turns.length;\n const tokenEstimate = turnCount * TOKENS_PER_TURN_ESTIMATE;\n sessions.push(this.toSessionInfo(record, turnCount));\n estimatedTokens += tokenEstimate;\n }\n\n return { sessions, estimatedTokens };\n }\n\n async buildContext(query: ContextQuery, options?: ContextOptions): Promise<ContextResult> {\n if (!this.isSupportedType(query.type)) {\n return { ...EMPTY_RESULT };\n }\n\n const maxTokens = options?.maxTokens ?? DEFAULT_MAX_TOKENS;\n const candidates = await this.resolveCandidates(query, options?.limit);\n\n // Load histories for sessions that have files\n type LoadedSession = {\n record: SessionRecord;\n history: import(\"./types.js\").SessionHistory;\n };\n\n const loaded: LoadedSession[] = [];\n for (const record of candidates) {\n const history = await this.store.read(record.sessionId);\n if (history) {\n loaded.push({ record, history });\n }\n }\n\n if (loaded.length === 0) {\n return { ...EMPTY_RESULT };\n }\n\n const totalTurns = loaded.reduce((sum, s) => sum + s.history.turns.length, 0);\n const labelAgent = options?.labelAgent ?? false;\n\n // Auto-select mode based on total turn count\n let mode: ContextMode = selectLevel(totalTurns);\n\n // Build markdown with selected mode\n let markdown = this.buildMergedMarkdown(loaded, mode, query, labelAgent);\n let tokenEstimate = estimateTokens(markdown);\n\n // Downgrade to compact if over budget\n if (tokenEstimate > maxTokens && mode !== \"compact\") {\n mode = \"compact\";\n markdown = this.buildMergedMarkdown(loaded, mode, query, labelAgent);\n tokenEstimate = estimateTokens(markdown);\n }\n\n // Truncate oldest sessions if still over budget\n let truncated = false;\n let activeSessions = [...loaded];\n while (tokenEstimate > maxTokens && activeSessions.length > 1) {\n // Remove the oldest session (last in list, sorted newest-first)\n activeSessions = activeSessions.slice(0, activeSessions.length - 1);\n markdown = this.buildMergedMarkdown(activeSessions, mode, query, labelAgent);\n tokenEstimate = estimateTokens(markdown);\n truncated = true;\n }\n\n const timeRange = this.computeTimeRange(activeSessions.map((s) => s.record));\n\n return {\n markdown,\n tokenEstimate,\n sessionCount: activeSessions.length,\n totalTurns: activeSessions.reduce((sum, s) => sum + s.history.turns.length, 0),\n mode,\n truncated,\n timeRange,\n };\n }\n\n // ─── Private helpers ─────────────────────────────────────────────────────────\n\n private isSupportedType(type: ContextQuery[\"type\"]): boolean {\n return type === \"session\" || type === \"latest\";\n }\n\n private async resolveCandidates(query: ContextQuery, limit?: number): Promise<SessionRecord[]> {\n const all = this.getSessionRecords();\n\n if (query.type === \"session\") {\n const found = all.find((r) => r.sessionId === query.value);\n return found ? [found] : [];\n }\n\n // latest: sort by lastActiveAt descending, take N\n const n = limit ?? (parseInt(query.value, 10) || 5);\n const sorted = [...all].sort(\n (a, b) => new Date(b.lastActiveAt).getTime() - new Date(a.lastActiveAt).getTime()\n );\n return sorted.slice(0, n);\n }\n\n private toSessionInfo(record: SessionRecord, turnCount: number): SessionInfo {\n return {\n checkpointId: \"\",\n sessionIndex: \"\",\n transcriptPath: \"\",\n createdAt: record.createdAt,\n endedAt: record.lastActiveAt,\n branch: \"\",\n agent: record.agentName,\n turnCount,\n filesTouched: [],\n sessionId: record.sessionId,\n };\n }\n\n private buildMergedMarkdown(\n sessions: Array<{ record: SessionRecord; history: import(\"./types.js\").SessionHistory }>,\n mode: ContextMode,\n query: ContextQuery,\n labelAgent = false\n ): string {\n if (sessions.length === 0) return \"\";\n\n const totalTurns = sessions.reduce((sum, s) => sum + s.history.turns.length, 0);\n const title = query.type === \"session\" ? query.value : `latest ${sessions.length} sessions`;\n\n const parts: string[] = [];\n parts.push(`# Conversation History — ${title}`);\n parts.push(`${sessions.length} sessions | ${totalTurns} turns | mode: ${mode}`);\n parts.push(\"\");\n\n for (let i = 0; i < sessions.length; i++) {\n const { record, history } = sessions[i];\n\n parts.push(`## Session ${i + 1} — ${record.agentName} · ${record.sessionId} (${history.turns.length} turns)`);\n parts.push(\"\");\n\n if (labelAgent && history.turns.length > 0) {\n const agentTimeline = this.buildAgentTimeline(record);\n const labeledMd = this.buildLabeledHistoryMarkdown(history.turns, mode, agentTimeline);\n if (labeledMd) {\n parts.push(labeledMd);\n }\n } else {\n const sessionMd = buildHistoryMarkdown(history.turns, mode);\n if (sessionMd) {\n parts.push(sessionMd);\n }\n }\n }\n\n parts.push(\n \"> **Note:** This conversation history may contain outdated information. Verify current state before acting on past context.\"\n );\n\n return parts.join(\"\\n\");\n }\n\n /**\n * Build a timeline of agent boundaries from the session record.\n * Returns sorted entries: [{ agentName, startedAt }] where startedAt is the\n * ISO timestamp when that agent started handling the session.\n *\n * The first agent runs from session creation until the first switch.\n * Each agentSwitchHistory entry records when the *previous* agent was switched away,\n * so the next agent starts at that switchedAt timestamp.\n */\n private buildAgentTimeline(record: SessionRecord): Array<{ agentName: string; switchedAt: number }> {\n const timeline: Array<{ agentName: string; switchedAt: number }> = [];\n\n // The first agent starts at the beginning of time (0)\n const firstAgentName = record.firstAgent ?? record.agentName;\n timeline.push({ agentName: firstAgentName, switchedAt: 0 });\n\n if (record.agentSwitchHistory && record.agentSwitchHistory.length > 0) {\n // Each entry in agentSwitchHistory records a *completed* agent stint:\n // { agentName: \"claude\", switchedAt: \"...\", ... } means claude was active\n // and was switched away at switchedAt. The next agent in sequence starts at that time.\n //\n // To reconstruct: after the last switchHistory entry, the current record.agentName is active.\n // But we need to map turns to agents, so we build boundaries.\n\n for (let i = 0; i < record.agentSwitchHistory.length; i++) {\n const entry = record.agentSwitchHistory[i];\n const switchTime = new Date(entry.switchedAt).getTime();\n\n // Determine which agent comes after this switch\n const nextAgent = i < record.agentSwitchHistory.length - 1\n ? record.agentSwitchHistory[i + 1].agentName\n : record.agentName; // current agent is the last one\n\n timeline.push({ agentName: nextAgent, switchedAt: switchTime });\n }\n }\n\n return timeline;\n }\n\n /**\n * Determine which agent produced a turn based on its timestamp and the agent timeline.\n */\n private resolveAgentForTurn(\n turnTimestamp: string,\n timeline: Array<{ agentName: string; switchedAt: number }>\n ): string {\n const turnTime = new Date(turnTimestamp).getTime();\n\n // Walk backward through the timeline to find the last boundary before this turn\n for (let i = timeline.length - 1; i >= 0; i--) {\n if (turnTime >= timeline[i].switchedAt) {\n return timeline[i].agentName;\n }\n }\n\n // Fallback to first agent\n return timeline[0].agentName;\n }\n\n /**\n * Build history markdown with agent labels inserted at agent boundaries.\n */\n private buildLabeledHistoryMarkdown(\n turns: import(\"./types.js\").Turn[],\n mode: ContextMode,\n agentTimeline: Array<{ agentName: string; switchedAt: number }>\n ): string {\n // If there's only one agent (no switches), just add a single label\n if (agentTimeline.length <= 1) {\n const label = `### [${agentTimeline[0]?.agentName ?? \"unknown\"}]\\n`;\n const md = buildHistoryMarkdown(turns, mode);\n return md ? label + \"\\n\" + md : label;\n }\n\n // Group turns by agent segments, then render each segment with a label\n const segments: Array<{ agentName: string; turns: import(\"./types.js\").Turn[] }> = [];\n let currentAgent = \"\";\n\n for (const turn of turns) {\n const agent = this.resolveAgentForTurn(turn.timestamp, agentTimeline);\n if (agent !== currentAgent) {\n segments.push({ agentName: agent, turns: [] });\n currentAgent = agent;\n }\n segments[segments.length - 1].turns.push(turn);\n }\n\n const parts: string[] = [];\n for (const segment of segments) {\n parts.push(`### [${segment.agentName}]`);\n parts.push(\"\");\n const md = buildHistoryMarkdown(segment.turns, mode);\n if (md) {\n parts.push(md);\n }\n }\n\n return parts.join(\"\\n\");\n }\n\n private computeTimeRange(\n records: SessionRecord[]\n ): { start: string; end: string } {\n if (records.length === 0) return { start: \"\", end: \"\" };\n\n const dates = records.map((r) => r.createdAt).filter(Boolean);\n const ends = records.map((r) => r.lastActiveAt).filter(Boolean);\n\n const start = dates.sort()[0] ?? \"\";\n const end = ends.sort().reverse()[0] ?? \"\";\n\n return { start, end };\n }\n}\n","import type { AgentEvent, Attachment } from \"../../../core/types.js\";\nimport type { HistoryStore } from \"./history-store.js\";\nimport type {\n HistoryAttachment,\n ResourceLinkStep,\n ResourceStep,\n SessionHistory,\n Step,\n ToolCallStep,\n Turn,\n} from \"./types.js\";\n\nexport interface RecorderState {\n history: SessionHistory;\n currentAssistantTurn: Turn | null;\n}\n\nfunction toHistoryAttachment(att: Attachment): HistoryAttachment {\n return {\n type: att.type,\n fileName: att.fileName,\n mimeType: att.mimeType,\n size: att.size,\n };\n}\n\nfunction extractDiff(\n content: unknown,\n): { path: string; oldText?: string; newText: string } | null {\n if (!Array.isArray(content)) return null;\n for (const item of content) {\n if (\n item &&\n typeof item === \"object\" &&\n (item as Record<string, unknown>).type === \"diff\"\n ) {\n const d = item as Record<string, unknown>;\n if (typeof d.path === \"string\" && typeof d.newText === \"string\") {\n const result: { path: string; oldText?: string; newText: string } = {\n path: d.path,\n newText: d.newText,\n };\n if (typeof d.oldText === \"string\") result.oldText = d.oldText;\n return result;\n }\n }\n }\n return null;\n}\n\nfunction extractLocations(\n locations: unknown,\n): { path: string; line?: number }[] | undefined {\n if (!Array.isArray(locations)) return undefined;\n const result: { path: string; line?: number }[] = [];\n for (const loc of locations) {\n if (loc && typeof loc === \"object\" && typeof (loc as any).path === \"string\") {\n const entry: { path: string; line?: number } = { path: (loc as any).path };\n if (typeof (loc as any).line === \"number\") entry.line = (loc as any).line;\n result.push(entry);\n }\n }\n return result.length > 0 ? result : undefined;\n}\n\nconst IGNORED_TYPES = new Set([\n \"session_end\",\n \"error\",\n \"system_message\",\n \"commands_update\",\n \"session_info_update\",\n \"model_update\",\n \"user_message_chunk\",\n \"tts_strip\",\n]);\n\nexport class HistoryRecorder {\n private states = new Map<string, RecorderState>();\n\n constructor(private readonly store: HistoryStore) {}\n\n onBeforePrompt(\n sessionId: string,\n text: string,\n attachments: Attachment[] | undefined,\n ): void {\n let state = this.states.get(sessionId);\n if (!state) {\n state = {\n history: { version: 1, sessionId, turns: [] },\n currentAssistantTurn: null,\n };\n this.states.set(sessionId, state);\n }\n\n const userTurn: Turn = {\n index: state.history.turns.length,\n role: \"user\",\n timestamp: new Date().toISOString(),\n content: text,\n };\n if (attachments && attachments.length > 0) {\n userTurn.attachments = attachments.map(toHistoryAttachment);\n }\n state.history.turns.push(userTurn);\n\n const assistantTurn: Turn = {\n index: state.history.turns.length,\n role: \"assistant\",\n timestamp: new Date().toISOString(),\n steps: [],\n };\n state.history.turns.push(assistantTurn);\n state.currentAssistantTurn = assistantTurn;\n }\n\n onAfterEvent(sessionId: string, event: AgentEvent): void {\n const state = this.states.get(sessionId);\n if (!state || !state.currentAssistantTurn) return;\n\n const turn = state.currentAssistantTurn;\n const steps = turn.steps!;\n\n if (IGNORED_TYPES.has(event.type)) return;\n\n switch (event.type) {\n case \"text\": {\n const last = steps[steps.length - 1];\n if (last && last.type === \"text\") {\n last.content += event.content;\n } else {\n steps.push({ type: \"text\", content: event.content });\n }\n break;\n }\n\n case \"thought\": {\n const last = steps[steps.length - 1];\n if (last && last.type === \"thinking\") {\n last.content += event.content;\n } else {\n steps.push({ type: \"thinking\", content: event.content });\n }\n break;\n }\n\n case \"tool_call\": {\n const step: ToolCallStep = {\n type: \"tool_call\",\n id: event.id,\n name: event.name,\n status: event.status,\n };\n if (event.kind) step.kind = event.kind;\n steps.push(step);\n break;\n }\n\n case \"tool_update\": {\n const existing = this.findToolCall(steps, event.id);\n if (!existing) break;\n existing.status = event.status;\n if (event.rawInput !== undefined) existing.input = event.rawInput;\n if (event.rawOutput !== undefined) existing.output = event.rawOutput;\n if (event.content !== undefined) {\n const diff = extractDiff(event.content);\n if (diff) existing.diff = diff;\n }\n if (event.locations !== undefined) {\n const locs = extractLocations(event.locations);\n if (locs) existing.locations = locs;\n }\n break;\n }\n\n case \"plan\": {\n steps.push({\n type: \"plan\",\n entries: event.entries.map((e) => ({\n content: e.content,\n priority: e.priority,\n status: e.status,\n })),\n });\n break;\n }\n\n case \"usage\": {\n turn.usage = {};\n if (event.tokensUsed !== undefined) turn.usage.tokensUsed = event.tokensUsed;\n if (event.contextSize !== undefined) turn.usage.contextSize = event.contextSize;\n if (event.cost) turn.usage.cost = event.cost;\n break;\n }\n\n case \"image_content\": {\n steps.push({\n type: \"image\",\n mimeType: event.mimeType,\n filePath: \"\",\n });\n break;\n }\n\n case \"audio_content\": {\n steps.push({\n type: \"audio\",\n mimeType: event.mimeType,\n filePath: \"\",\n });\n break;\n }\n\n case \"resource_content\": {\n const step: ResourceStep = {\n type: \"resource\",\n uri: event.uri,\n name: event.name,\n };\n if (event.text !== undefined) step.text = event.text;\n steps.push(step);\n break;\n }\n\n case \"resource_link\": {\n const step: ResourceLinkStep = {\n type: \"resource_link\",\n uri: event.uri,\n name: event.name,\n };\n if (event.title !== undefined) step.title = event.title;\n if (event.description !== undefined)\n step.description = event.description;\n steps.push(step);\n break;\n }\n\n case \"current_mode_update\": {\n steps.push({ type: \"mode_change\", modeId: event.modeId });\n break;\n }\n\n case \"config_option_update\": {\n for (const opt of event.options) {\n steps.push({\n type: \"config_change\",\n configId: opt.id,\n value: String(opt.currentValue),\n });\n }\n break;\n }\n }\n }\n\n onPermissionResolved(\n sessionId: string,\n requestId: string,\n decision: string,\n ): void {\n const state = this.states.get(sessionId);\n if (!state || !state.currentAssistantTurn) return;\n const step = this.findToolCall(state.currentAssistantTurn.steps!, requestId);\n if (!step) return;\n step.permission = { requested: true, outcome: decision };\n }\n\n async onTurnEnd(sessionId: string, stopReason: string): Promise<void> {\n const state = this.states.get(sessionId);\n if (!state || !state.currentAssistantTurn) return;\n state.currentAssistantTurn.stopReason = stopReason;\n state.currentAssistantTurn = null;\n await this.store.write(state.history);\n }\n\n finalize(sessionId: string): void {\n this.states.delete(sessionId);\n }\n\n getState(sessionId: string): RecorderState | undefined {\n return this.states.get(sessionId);\n }\n\n private findToolCall(steps: Step[], id: string): ToolCallStep | undefined {\n for (let i = steps.length - 1; i >= 0; i--) {\n const s = steps[i];\n if (s.type === \"tool_call\" && s.id === id) return s;\n }\n return undefined;\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { SessionHistory } from \"./types.js\";\n\nexport class HistoryStore {\n constructor(private readonly dir: string) {}\n\n async write(history: SessionHistory): Promise<void> {\n await fs.promises.mkdir(this.dir, { recursive: true });\n const filePath = this.filePath(history.sessionId);\n await fs.promises.writeFile(filePath, JSON.stringify(history, null, 2));\n }\n\n async read(sessionId: string): Promise<SessionHistory | null> {\n const filePath = this.filePath(sessionId);\n try {\n const raw = await fs.promises.readFile(filePath, \"utf-8\");\n return JSON.parse(raw) as SessionHistory;\n } catch {\n return null;\n }\n }\n\n async exists(sessionId: string): Promise<boolean> {\n try {\n await fs.promises.access(this.filePath(sessionId));\n return true;\n } catch {\n return false;\n }\n }\n\n async list(): Promise<string[]> {\n try {\n const files = await fs.promises.readdir(this.dir);\n return files\n .filter((f) => f.endsWith(\".json\"))\n .map((f) => f.replace(/\\.json$/, \"\"));\n } catch {\n return [];\n }\n }\n\n async delete(sessionId: string): Promise<void> {\n try {\n await fs.promises.unlink(this.filePath(sessionId));\n } catch {\n // file may not exist — safe to ignore\n }\n }\n\n private filePath(sessionId: string): string {\n return path.join(this.dir, `${sessionId}.json`);\n }\n}\n"],"mappings":"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","names":["path"]}
@@ -1,138 +0,0 @@
1
- // src/plugins/file-service/file-service.ts
2
- import fs from "fs";
3
- import path from "path";
4
- import { OggOpusDecoder } from "ogg-opus-decoder";
5
- import wav from "node-wav";
6
- var MIME_TO_EXT = {
7
- "image/jpeg": ".jpg",
8
- "image/png": ".png",
9
- "image/gif": ".gif",
10
- "image/webp": ".webp",
11
- "image/svg+xml": ".svg",
12
- "audio/ogg": ".ogg",
13
- "audio/mpeg": ".mp3",
14
- "audio/wav": ".wav",
15
- "audio/webm": ".webm",
16
- "audio/mp4": ".m4a",
17
- "video/mp4": ".mp4",
18
- "video/webm": ".webm",
19
- "application/pdf": ".pdf",
20
- "text/plain": ".txt"
21
- };
22
- var EXT_TO_MIME = {
23
- ".jpg": "image/jpeg",
24
- ".jpeg": "image/jpeg",
25
- ".png": "image/png",
26
- ".gif": "image/gif",
27
- ".webp": "image/webp",
28
- ".svg": "image/svg+xml",
29
- ".ogg": "audio/ogg",
30
- ".oga": "audio/ogg",
31
- ".mp3": "audio/mpeg",
32
- ".wav": "audio/wav",
33
- ".m4a": "audio/mp4",
34
- ".mp4": "video/mp4",
35
- ".pdf": "application/pdf",
36
- ".txt": "text/plain"
37
- };
38
- function classifyMime(mimeType) {
39
- if (mimeType.startsWith("image/")) return "image";
40
- if (mimeType.startsWith("audio/")) return "audio";
41
- return "file";
42
- }
43
- var FileService = class _FileService {
44
- constructor(baseDir) {
45
- this.baseDir = baseDir;
46
- }
47
- /**
48
- * Remove session file directories older than maxAgeDays.
49
- * Called on startup to prevent unbounded disk growth.
50
- */
51
- async cleanupOldFiles(maxAgeDays) {
52
- const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1e3;
53
- let removed = 0;
54
- try {
55
- const entries = await fs.promises.readdir(this.baseDir, { withFileTypes: true });
56
- for (const entry of entries) {
57
- if (!entry.isDirectory()) continue;
58
- const dirPath = path.join(this.baseDir, entry.name);
59
- try {
60
- const stat = await fs.promises.stat(dirPath);
61
- if (stat.mtimeMs < cutoff) {
62
- await fs.promises.rm(dirPath, { recursive: true, force: true });
63
- removed++;
64
- }
65
- } catch {
66
- }
67
- }
68
- } catch {
69
- }
70
- return removed;
71
- }
72
- async saveFile(sessionId, fileName, data, mimeType) {
73
- const sessionDir = path.join(this.baseDir, sessionId);
74
- await fs.promises.mkdir(sessionDir, { recursive: true });
75
- const safeName = `${Date.now()}-${fileName.replace(/[^a-zA-Z0-9._-]/g, "_")}`;
76
- const filePath = path.join(sessionDir, safeName);
77
- await fs.promises.writeFile(filePath, data);
78
- return {
79
- type: classifyMime(mimeType),
80
- filePath,
81
- fileName,
82
- mimeType,
83
- size: data.length
84
- };
85
- }
86
- async resolveFile(filePath) {
87
- try {
88
- const stat = await fs.promises.stat(filePath);
89
- if (!stat.isFile()) return null;
90
- const ext = path.extname(filePath).toLowerCase();
91
- const mimeType = EXT_TO_MIME[ext] || "application/octet-stream";
92
- return {
93
- type: classifyMime(mimeType),
94
- filePath,
95
- fileName: path.basename(filePath),
96
- mimeType,
97
- size: stat.size
98
- };
99
- } catch {
100
- return null;
101
- }
102
- }
103
- /**
104
- * Convert OGG Opus audio to WAV format.
105
- * Telegram voice messages use OGG Opus which many AI agents can't read.
106
- */
107
- async convertOggToWav(oggData) {
108
- const decoder = new OggOpusDecoder();
109
- await decoder.ready;
110
- try {
111
- const { channelData, sampleRate } = await decoder.decode(new Uint8Array(oggData));
112
- const wavData = wav.encode(channelData, { sampleRate, float: true, bitDepth: 32 });
113
- return Buffer.from(wavData);
114
- } finally {
115
- decoder.free();
116
- }
117
- }
118
- /** Instance method — delegates to static for FileServiceInterface compliance */
119
- async readTextFileWithRange(filePath, options) {
120
- return _FileService.readTextFileWithRange(filePath, options);
121
- }
122
- static async readTextFileWithRange(filePath, options) {
123
- const { readTextFileWithRange } = await import("./read-text-file-DJBTITIB.js");
124
- return readTextFileWithRange(filePath, options);
125
- }
126
- /** Instance method — delegates to static for FileServiceInterface compliance */
127
- extensionFromMime(mimeType) {
128
- return _FileService.extensionFromMime(mimeType);
129
- }
130
- static extensionFromMime(mimeType) {
131
- return MIME_TO_EXT[mimeType] || ".bin";
132
- }
133
- };
134
-
135
- export {
136
- FileService
137
- };
138
- //# sourceMappingURL=chunk-IZ5UEZF7.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/plugins/file-service/file-service.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { OggOpusDecoder } from \"ogg-opus-decoder\";\nimport wav from \"node-wav\";\nimport type { Attachment } from \"../../core/types.js\";\n\nconst MIME_TO_EXT: Record<string, string> = {\n \"image/jpeg\": \".jpg\",\n \"image/png\": \".png\",\n \"image/gif\": \".gif\",\n \"image/webp\": \".webp\",\n \"image/svg+xml\": \".svg\",\n \"audio/ogg\": \".ogg\",\n \"audio/mpeg\": \".mp3\",\n \"audio/wav\": \".wav\",\n \"audio/webm\": \".webm\",\n \"audio/mp4\": \".m4a\",\n \"video/mp4\": \".mp4\",\n \"video/webm\": \".webm\",\n \"application/pdf\": \".pdf\",\n \"text/plain\": \".txt\",\n};\n\nconst EXT_TO_MIME: Record<string, string> = {\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".png\": \"image/png\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".ogg\": \"audio/ogg\",\n \".oga\": \"audio/ogg\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".m4a\": \"audio/mp4\",\n \".mp4\": \"video/mp4\",\n \".pdf\": \"application/pdf\",\n \".txt\": \"text/plain\",\n};\n\nfunction classifyMime(mimeType: string): Attachment[\"type\"] {\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n return \"file\";\n}\n\nexport class FileService {\n constructor(private baseDir: string) {}\n\n /**\n * Remove session file directories older than maxAgeDays.\n * Called on startup to prevent unbounded disk growth.\n */\n async cleanupOldFiles(maxAgeDays: number): Promise<number> {\n const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;\n let removed = 0;\n try {\n const entries = await fs.promises.readdir(this.baseDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const dirPath = path.join(this.baseDir, entry.name);\n try {\n const stat = await fs.promises.stat(dirPath);\n if (stat.mtimeMs < cutoff) {\n await fs.promises.rm(dirPath, { recursive: true, force: true });\n removed++;\n }\n } catch {\n // Skip inaccessible directories\n }\n }\n } catch {\n // Base dir doesn't exist yet — nothing to clean\n }\n return removed;\n }\n\n async saveFile(\n sessionId: string,\n fileName: string,\n data: Buffer,\n mimeType: string,\n ): Promise<Attachment> {\n const sessionDir = path.join(this.baseDir, sessionId);\n await fs.promises.mkdir(sessionDir, { recursive: true });\n\n const safeName = `${Date.now()}-${fileName.replace(/[^a-zA-Z0-9._-]/g, \"_\")}`;\n const filePath = path.join(sessionDir, safeName);\n await fs.promises.writeFile(filePath, data);\n\n return {\n type: classifyMime(mimeType),\n filePath,\n fileName,\n mimeType,\n size: data.length,\n };\n }\n\n async resolveFile(filePath: string): Promise<Attachment | null> {\n try {\n const stat = await fs.promises.stat(filePath);\n if (!stat.isFile()) return null;\n\n const ext = path.extname(filePath).toLowerCase();\n const mimeType = EXT_TO_MIME[ext] || \"application/octet-stream\";\n\n return {\n type: classifyMime(mimeType),\n filePath,\n fileName: path.basename(filePath),\n mimeType,\n size: stat.size,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Convert OGG Opus audio to WAV format.\n * Telegram voice messages use OGG Opus which many AI agents can't read.\n */\n async convertOggToWav(oggData: Buffer): Promise<Buffer> {\n const decoder = new OggOpusDecoder();\n await decoder.ready;\n try {\n const { channelData, sampleRate } = await decoder.decode(new Uint8Array(oggData));\n const wavData = wav.encode(channelData, { sampleRate, float: true, bitDepth: 32 });\n return Buffer.from(wavData);\n } finally {\n decoder.free();\n }\n }\n\n /** Instance method — delegates to static for FileServiceInterface compliance */\n async readTextFileWithRange(\n filePath: string,\n options?: { line?: number; limit?: number },\n ): Promise<string> {\n return FileService.readTextFileWithRange(filePath, options);\n }\n\n static async readTextFileWithRange(\n filePath: string,\n options?: { line?: number; limit?: number },\n ): Promise<string> {\n // Delegate to core utility (canonical implementation)\n const { readTextFileWithRange } = await import(\"../../core/utils/read-text-file.js\");\n return readTextFileWithRange(filePath, options);\n }\n\n /** Instance method — delegates to static for FileServiceInterface compliance */\n extensionFromMime(mimeType: string): string {\n return FileService.extensionFromMime(mimeType);\n }\n\n static extensionFromMime(mimeType: string): string {\n return MIME_TO_EXT[mimeType] || \".bin\";\n }\n}\n"],"mappings":"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","names":[]}