@agentprojectcontext/apx 1.25.0 → 1.27.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (718) hide show
  1. package/package.json +42 -12
  2. package/skills/apx/SKILL.md +50 -119
  3. package/skills/apx-agency-agents/SKILL.md +141 -0
  4. package/skills/apx-agent/SKILL.md +100 -0
  5. package/skills/apx-mcp/SKILL.md +114 -0
  6. package/skills/apx-mcp-builder/SKILL.md +186 -0
  7. package/skills/apx-project/SKILL.md +100 -0
  8. package/skills/apx-routine/SKILL.md +138 -0
  9. package/skills/apx-runtime/SKILL.md +115 -0
  10. package/skills/apx-sessions/SKILL.md +281 -0
  11. package/skills/apx-skill-builder/SKILL.md +149 -0
  12. package/skills/apx-task/SKILL.md +95 -0
  13. package/skills/apx-telegram/SKILL.md +115 -0
  14. package/skills/apx-voice/SKILL.md +135 -0
  15. package/src/core/agent/constants.js +3 -0
  16. package/src/core/agent/ghost-guard.js +24 -0
  17. package/src/core/agent/index.js +35 -0
  18. package/src/core/agent/model-router.js +257 -0
  19. package/src/core/agent/prompt-builder.js +313 -0
  20. package/src/core/agent/prompts/channels/api.md +7 -0
  21. package/src/core/agent/prompts/channels/cli.md +6 -0
  22. package/src/core/agent/prompts/channels/code.md +20 -0
  23. package/src/core/agent/prompts/channels/deck.md +6 -0
  24. package/src/core/agent/prompts/channels/desktop.md +24 -0
  25. package/src/core/agent/prompts/channels/routine.md +9 -0
  26. package/src/core/agent/prompts/channels/telegram.md +9 -0
  27. package/src/core/agent/prompts/channels/terminal.md +16 -0
  28. package/src/core/agent/prompts/channels/web.md +7 -0
  29. package/src/core/agent/prompts/channels/web_sidebar.md +7 -0
  30. package/src/core/agent/prompts/modes/voice.md +4 -0
  31. package/src/core/agent/prompts/super-agent-base.md +42 -0
  32. package/src/core/agent/pseudo-tools.js +40 -0
  33. package/src/core/agent/retry.js +85 -0
  34. package/src/core/agent/run-agent.js +423 -0
  35. package/src/core/agent/self-memory.js +155 -0
  36. package/src/{daemon → core/agent}/tool-call-parser.js +83 -10
  37. package/src/core/agent/tools-overlap.js +66 -0
  38. package/src/core/apc-skill-sync.js +97 -0
  39. package/src/core/code-sessions-store.js +150 -0
  40. package/src/core/config.js +473 -11
  41. package/src/core/desktop/autostart.js +162 -0
  42. package/src/core/engines/_health.js +63 -0
  43. package/src/{daemon → core}/engines/anthropic.js +16 -0
  44. package/src/core/engines/gemini.js +168 -0
  45. package/src/core/engines/groq.js +8 -0
  46. package/src/{daemon → core}/engines/index.js +3 -1
  47. package/src/{daemon → core}/engines/mock.js +22 -0
  48. package/src/{daemon → core}/engines/ollama.js +35 -0
  49. package/src/core/engines/openai-compatible.js +145 -0
  50. package/src/core/engines/openai.js +8 -0
  51. package/src/core/engines/openrouter.js +8 -0
  52. package/src/core/git-baseline.js +147 -0
  53. package/src/core/identity.js +21 -0
  54. package/src/core/logging.js +1 -1
  55. package/src/core/mcp/index.js +14 -0
  56. package/src/{daemon/mcp-runner.js → core/mcp/runner.js} +18 -6
  57. package/src/core/mcp/sources.js +246 -0
  58. package/src/core/memory/active-threads.js +124 -0
  59. package/src/core/memory/broker.js +144 -0
  60. package/src/core/memory/compactor.js +186 -0
  61. package/src/core/memory/embed-engines/gemini.js +62 -0
  62. package/src/core/memory/embed-engines/index.js +148 -0
  63. package/src/core/memory/embed-engines/ollama.js +55 -0
  64. package/src/core/memory/embed-engines/openai.js +64 -0
  65. package/src/core/memory/embed-engines/tf.js +20 -0
  66. package/src/core/memory/embeddings.js +132 -0
  67. package/src/core/memory/index.js +161 -0
  68. package/src/core/memory/indexer.js +257 -0
  69. package/src/core/memory/store.js +231 -0
  70. package/src/core/messages-store.js +143 -25
  71. package/src/core/parser.js +78 -16
  72. package/src/core/scaffold.js +175 -79
  73. package/src/core/tasks-store.js +264 -0
  74. package/src/core/telegram-identity.js +126 -0
  75. package/src/core/tools/index.js +6 -0
  76. package/src/core/voice/engines/elevenlabs.js +96 -0
  77. package/src/core/voice/engines/gemini.js +148 -0
  78. package/src/core/voice/engines/index.js +144 -0
  79. package/src/core/voice/engines/mock.js +59 -0
  80. package/src/core/voice/engines/openai.js +82 -0
  81. package/src/core/voice/engines/piper.js +93 -0
  82. package/src/core/voice/index.js +3 -0
  83. package/src/core/voice/tts.js +89 -0
  84. package/src/{daemon → host/daemon}/apc-runtime-context.js +1 -1
  85. package/src/host/daemon/api/admin-config.js +159 -0
  86. package/src/host/daemon/api/admin.js +72 -0
  87. package/src/host/daemon/api/agents.js +284 -0
  88. package/src/host/daemon/api/artifacts.js +52 -0
  89. package/src/host/daemon/api/code.js +351 -0
  90. package/src/host/daemon/api/config.js +104 -0
  91. package/src/host/daemon/api/connections.js +42 -0
  92. package/src/host/daemon/api/conversations.js +161 -0
  93. package/src/host/daemon/api/deck.js +511 -0
  94. package/src/host/daemon/api/desktop.js +71 -0
  95. package/src/host/daemon/api/embeddings.js +65 -0
  96. package/src/host/daemon/api/engines.js +80 -0
  97. package/src/host/daemon/api/exec.js +193 -0
  98. package/src/host/daemon/api/health.js +10 -0
  99. package/src/host/daemon/api/identity.js +36 -0
  100. package/src/host/daemon/api/mcps.js +205 -0
  101. package/src/host/daemon/api/messages.js +83 -0
  102. package/src/host/daemon/api/pairing.js +194 -0
  103. package/src/host/daemon/api/plugins.js +19 -0
  104. package/src/host/daemon/api/projects.js +35 -0
  105. package/src/host/daemon/api/routines.js +84 -0
  106. package/src/host/daemon/api/run.js +55 -0
  107. package/src/host/daemon/api/runtimes.js +219 -0
  108. package/src/host/daemon/api/sessions-search.js +177 -0
  109. package/src/host/daemon/api/sessions.js +115 -0
  110. package/src/host/daemon/api/shared.js +217 -0
  111. package/src/host/daemon/api/super-agent.js +208 -0
  112. package/src/host/daemon/api/tasks.js +118 -0
  113. package/src/host/daemon/api/telegram.js +325 -0
  114. package/src/host/daemon/api/tools.js +21 -0
  115. package/src/host/daemon/api/top-level.js +131 -0
  116. package/src/host/daemon/api/transcribe.js +35 -0
  117. package/src/host/daemon/api/tts.js +44 -0
  118. package/src/host/daemon/api/voice.js +519 -0
  119. package/src/host/daemon/api/web.js +123 -0
  120. package/src/host/daemon/api.js +152 -0
  121. package/src/{daemon → host/daemon}/compact.js +1 -1
  122. package/src/{daemon → host/daemon}/db.js +19 -5
  123. package/src/{daemon/overlay-ws.js → host/daemon/desktop-ws.js} +7 -7
  124. package/src/host/daemon/engine-sessions.js +245 -0
  125. package/src/{daemon → host/daemon}/index.js +27 -10
  126. package/src/{daemon/plugins/overlay.js → host/daemon/plugins/desktop.js} +36 -28
  127. package/src/{daemon → host/daemon}/plugins/index.js +2 -2
  128. package/src/{daemon → host/daemon}/plugins/telegram.js +165 -33
  129. package/src/{daemon → host/daemon}/project-config.js +31 -7
  130. package/src/{daemon → host/daemon}/routines.js +27 -8
  131. package/src/{daemon → host/daemon}/skills-loader.js +4 -2
  132. package/src/{daemon → host/daemon}/smoke.js +9 -5
  133. package/src/{daemon → host/daemon}/super-agent-tools/helpers.js +1 -1
  134. package/src/host/daemon/super-agent-tools/index.js +157 -0
  135. package/src/{daemon → host/daemon}/super-agent-tools/registry-bridge.js +1 -1
  136. package/src/{daemon → host/daemon}/super-agent-tools/tools/add-project.js +2 -2
  137. package/src/{daemon → host/daemon}/super-agent-tools/tools/ask-questions.js +4 -0
  138. package/src/{daemon → host/daemon}/super-agent-tools/tools/call-agent.js +5 -2
  139. package/src/{daemon → host/daemon}/super-agent-tools/tools/call-runtime.js +117 -8
  140. package/src/host/daemon/super-agent-tools/tools/create-task.js +52 -0
  141. package/src/{daemon → host/daemon}/super-agent-tools/tools/import-agent.js +2 -3
  142. package/src/{daemon → host/daemon}/super-agent-tools/tools/list-agents.js +1 -1
  143. package/src/host/daemon/super-agent-tools/tools/list-tasks.js +52 -0
  144. package/src/{daemon → host/daemon}/super-agent-tools/tools/list-vault-agents.js +1 -1
  145. package/src/host/daemon/super-agent-tools/tools/read-self-memory.js +21 -0
  146. package/src/host/daemon/super-agent-tools/tools/remember.js +40 -0
  147. package/src/{daemon → host/daemon}/super-agent-tools/tools/search-messages.js +1 -1
  148. package/src/host/daemon/super-agent-tools/tools/search-sessions.js +134 -0
  149. package/src/{daemon → host/daemon}/super-agent-tools/tools/send-telegram.js +2 -2
  150. package/src/{daemon → host/daemon}/super-agent-tools/tools/set-identity.js +1 -1
  151. package/src/{daemon → host/daemon}/super-agent-tools/tools/set-permission-mode.js +1 -1
  152. package/src/{daemon → host/daemon}/super-agent-tools/tools/tail-messages.js +1 -1
  153. package/src/host/daemon/super-agent.js +129 -0
  154. package/src/host/daemon/token-store.js +118 -0
  155. package/src/host/daemon/tool-call-parser.js +2 -0
  156. package/src/{daemon → host/daemon}/transcription.js +1 -1
  157. package/src/{daemon → host/daemon}/wakeup.js +2 -2
  158. package/src/interfaces/cli/claude-permissions.js +33 -0
  159. package/src/{cli → interfaces/cli}/commands/agent.js +43 -8
  160. package/src/{cli → interfaces/cli}/commands/command.js +1 -1
  161. package/src/{cli → interfaces/cli}/commands/config.js +1 -1
  162. package/src/{cli → interfaces/cli}/commands/daemon.js +67 -0
  163. package/src/interfaces/cli/commands/desktop.js +335 -0
  164. package/src/interfaces/cli/commands/exec.js +92 -0
  165. package/src/{cli → interfaces/cli}/commands/identity.js +6 -63
  166. package/src/{cli → interfaces/cli}/commands/init.js +1 -1
  167. package/src/{cli → interfaces/cli}/commands/mcp.js +69 -10
  168. package/src/{cli → interfaces/cli}/commands/memory.js +2 -2
  169. package/src/interfaces/cli/commands/model.js +136 -0
  170. package/src/interfaces/cli/commands/pair.js +170 -0
  171. package/src/interfaces/cli/commands/project-config.js +131 -0
  172. package/src/{cli → interfaces/cli}/commands/project.js +1 -1
  173. package/src/{cli → interfaces/cli}/commands/search.js +1 -1
  174. package/src/interfaces/cli/commands/session.js +892 -0
  175. package/src/interfaces/cli/commands/sessions.js +997 -0
  176. package/src/{cli → interfaces/cli}/commands/setup.js +98 -4
  177. package/src/{cli → interfaces/cli}/commands/skills.js +117 -9
  178. package/src/{cli → interfaces/cli}/commands/status.js +9 -1
  179. package/src/{cli → interfaces/cli}/commands/sys.js +96 -17
  180. package/src/interfaces/cli/commands/task.js +179 -0
  181. package/src/interfaces/cli/commands/telegram.js +366 -0
  182. package/src/{cli → interfaces/cli}/commands/update.js +1 -1
  183. package/src/interfaces/cli/commands/voice.js +258 -0
  184. package/src/{cli → interfaces/cli}/http.js +6 -2
  185. package/src/{cli → interfaces/cli}/index.js +955 -63
  186. package/src/interfaces/cli/postinstall.js +34 -0
  187. package/src/interfaces/desktop/assets/app-icon-180.png +0 -0
  188. package/src/interfaces/desktop/assets/app-icon-32.png +0 -0
  189. package/src/interfaces/desktop/assets/app-icon.png +0 -0
  190. package/src/interfaces/desktop/assets/apx-logo.png +0 -0
  191. package/src/interfaces/desktop/assets/superagent.png +0 -0
  192. package/src/interfaces/desktop/assets/tray-icon.png +0 -0
  193. package/src/interfaces/desktop/index.html +18 -0
  194. package/src/interfaces/desktop/main.js +652 -0
  195. package/src/interfaces/desktop/preload.js +48 -0
  196. package/src/interfaces/desktop/renderer.js +1006 -0
  197. package/src/interfaces/desktop/style.css +400 -0
  198. package/src/{mcp → interfaces/mcp-server}/index.js +2 -2
  199. package/src/interfaces/tui/_shims/util-which.ts +53 -0
  200. package/src/{tui → interfaces/tui}/app.tsx +2 -2
  201. package/src/{tui → interfaces/tui}/component/prompt/index.tsx +4 -1
  202. package/src/{tui → interfaces/tui}/context/sdk-apx.tsx +84 -16
  203. package/src/interfaces/tui/context/sync-apx.tsx +398 -0
  204. package/src/interfaces/tui/routes/session/index.tsx +368 -0
  205. package/src/interfaces/tui/routes/session/message-actions.tsx +58 -0
  206. package/src/interfaces/tui/routes/session/sidebar-apx.tsx +114 -0
  207. package/src/{tui → interfaces/tui}/tsconfig.json +1 -0
  208. package/src/{tui → interfaces/tui}/util/clipboard.ts +1 -1
  209. package/src/interfaces/web/README.md +102 -0
  210. package/src/interfaces/web/coming-soon.html +65 -0
  211. package/src/interfaces/web/components.json +25 -0
  212. package/src/interfaces/web/dist/assets/index-BDUsA6L6.css +1 -0
  213. package/src/interfaces/web/dist/assets/index-CfWyjPBa.js +548 -0
  214. package/src/interfaces/web/dist/assets/index-CfWyjPBa.js.map +1 -0
  215. package/src/interfaces/web/dist/favicon/dark/android-chrome-192x192.png +0 -0
  216. package/src/interfaces/web/dist/favicon/dark/android-chrome-512x512.png +0 -0
  217. package/src/interfaces/web/dist/favicon/dark/apple-touch-icon.png +0 -0
  218. package/src/interfaces/web/dist/favicon/dark/favicon-16x16.png +0 -0
  219. package/src/interfaces/web/dist/favicon/dark/favicon-32x32.png +0 -0
  220. package/src/interfaces/web/dist/favicon/dark/favicon-48x48.png +0 -0
  221. package/src/interfaces/web/dist/favicon/dark/favicon.ico +0 -0
  222. package/src/interfaces/web/dist/favicon/dark/favicon.webp +0 -0
  223. package/src/interfaces/web/dist/favicon/dark/site.webmanifest +18 -0
  224. package/src/interfaces/web/dist/favicon/white/android-chrome-192x192.png +0 -0
  225. package/src/interfaces/web/dist/favicon/white/android-chrome-512x512.png +0 -0
  226. package/src/interfaces/web/dist/favicon/white/apple-touch-icon.png +0 -0
  227. package/src/interfaces/web/dist/favicon/white/favicon-16x16.png +0 -0
  228. package/src/interfaces/web/dist/favicon/white/favicon-32x32.png +0 -0
  229. package/src/interfaces/web/dist/favicon/white/favicon-48x48.png +0 -0
  230. package/src/interfaces/web/dist/favicon/white/favicon.ico +0 -0
  231. package/src/interfaces/web/dist/favicon/white/favicon.webp +0 -0
  232. package/src/interfaces/web/dist/favicon/white/site.webmanifest +18 -0
  233. package/src/interfaces/web/dist/index.html +27 -0
  234. package/src/interfaces/web/dist/logo/logo_dark.webp +0 -0
  235. package/src/interfaces/web/dist/logo/logo_only_dark.webp +0 -0
  236. package/src/interfaces/web/dist/logo/logo_only_white.webp +0 -0
  237. package/src/interfaces/web/dist/logo/logo_vertical_dark.webp +0 -0
  238. package/src/interfaces/web/dist/logo/logo_vertical_white.webp +0 -0
  239. package/src/interfaces/web/dist/logo/logo_white.webp +0 -0
  240. package/src/interfaces/web/dist/modules/superagent.png +0 -0
  241. package/src/interfaces/web/index.html +26 -0
  242. package/src/interfaces/web/package-lock.json +4253 -0
  243. package/src/interfaces/web/package.json +55 -0
  244. package/src/interfaces/web/playwright.config.ts +45 -0
  245. package/src/interfaces/web/pnpm-lock.yaml +2946 -0
  246. package/src/interfaces/web/public/favicon/dark/android-chrome-192x192.png +0 -0
  247. package/src/interfaces/web/public/favicon/dark/android-chrome-512x512.png +0 -0
  248. package/src/interfaces/web/public/favicon/dark/apple-touch-icon.png +0 -0
  249. package/src/interfaces/web/public/favicon/dark/favicon-16x16.png +0 -0
  250. package/src/interfaces/web/public/favicon/dark/favicon-32x32.png +0 -0
  251. package/src/interfaces/web/public/favicon/dark/favicon-48x48.png +0 -0
  252. package/src/interfaces/web/public/favicon/dark/favicon.ico +0 -0
  253. package/src/interfaces/web/public/favicon/dark/favicon.webp +0 -0
  254. package/src/interfaces/web/public/favicon/dark/site.webmanifest +18 -0
  255. package/src/interfaces/web/public/favicon/white/android-chrome-192x192.png +0 -0
  256. package/src/interfaces/web/public/favicon/white/android-chrome-512x512.png +0 -0
  257. package/src/interfaces/web/public/favicon/white/apple-touch-icon.png +0 -0
  258. package/src/interfaces/web/public/favicon/white/favicon-16x16.png +0 -0
  259. package/src/interfaces/web/public/favicon/white/favicon-32x32.png +0 -0
  260. package/src/interfaces/web/public/favicon/white/favicon-48x48.png +0 -0
  261. package/src/interfaces/web/public/favicon/white/favicon.ico +0 -0
  262. package/src/interfaces/web/public/favicon/white/favicon.webp +0 -0
  263. package/src/interfaces/web/public/favicon/white/site.webmanifest +18 -0
  264. package/src/interfaces/web/public/logo/logo_dark.webp +0 -0
  265. package/src/interfaces/web/public/logo/logo_only_dark.webp +0 -0
  266. package/src/interfaces/web/public/logo/logo_only_white.webp +0 -0
  267. package/src/interfaces/web/public/logo/logo_vertical_dark.webp +0 -0
  268. package/src/interfaces/web/public/logo/logo_vertical_white.webp +0 -0
  269. package/src/interfaces/web/public/logo/logo_white.webp +0 -0
  270. package/src/interfaces/web/public/modules/superagent.png +0 -0
  271. package/src/interfaces/web/src/App.tsx +199 -0
  272. package/src/interfaces/web/src/components/AddProjectDialog.tsx +121 -0
  273. package/src/interfaces/web/src/components/ModelCombobox.tsx +96 -0
  274. package/src/interfaces/web/src/components/RobyBubble.tsx +213 -0
  275. package/src/interfaces/web/src/components/Section.tsx +44 -0
  276. package/src/interfaces/web/src/components/TelegramChannelDialog.tsx +97 -0
  277. package/src/interfaces/web/src/components/TelegramSendDialog.tsx +48 -0
  278. package/src/interfaces/web/src/components/Toast.tsx +84 -0
  279. package/src/interfaces/web/src/components/UiSelect.tsx +74 -0
  280. package/src/interfaces/web/src/components/chat/Composer.tsx +43 -0
  281. package/src/interfaces/web/src/components/chat/ContextBar.tsx +111 -0
  282. package/src/interfaces/web/src/components/chat/MessageBubble.tsx +95 -0
  283. package/src/interfaces/web/src/components/chat/MessageList.tsx +35 -0
  284. package/src/interfaces/web/src/components/chat/ModelPicker.tsx +145 -0
  285. package/src/interfaces/web/src/components/chat/ToolCall.tsx +141 -0
  286. package/src/interfaces/web/src/components/code/CodeChangesTab.tsx +87 -0
  287. package/src/interfaces/web/src/components/code/CodeComposer.tsx +87 -0
  288. package/src/interfaces/web/src/components/code/CodeContextTab.tsx +83 -0
  289. package/src/interfaces/web/src/components/code/CodeProjectPicker.tsx +39 -0
  290. package/src/interfaces/web/src/components/code/CodeSessionList.tsx +97 -0
  291. package/src/interfaces/web/src/components/code/CodeSidePanel.tsx +44 -0
  292. package/src/interfaces/web/src/components/code/CodeToolTrail.tsx +29 -0
  293. package/src/interfaces/web/src/components/code/DiffView.tsx +67 -0
  294. package/src/interfaces/web/src/components/common/Qr.tsx +27 -0
  295. package/src/interfaces/web/src/components/common/TabLayout.tsx +46 -0
  296. package/src/interfaces/web/src/components/common/TabNav.tsx +113 -0
  297. package/src/interfaces/web/src/components/config/ConfigTabsEditor.tsx +202 -0
  298. package/src/interfaces/web/src/components/config/GlobalConfigEditor.tsx +42 -0
  299. package/src/interfaces/web/src/components/config/global-config-sections.ts +60 -0
  300. package/src/interfaces/web/src/components/config/project-config-sections.ts +58 -0
  301. package/src/interfaces/web/src/components/deck/DaemonCard.tsx +58 -0
  302. package/src/interfaces/web/src/components/deck/DesktopGroup.tsx +33 -0
  303. package/src/interfaces/web/src/components/deck/WidgetRow.tsx +100 -0
  304. package/src/interfaces/web/src/components/layout/Logo.tsx +59 -0
  305. package/src/interfaces/web/src/components/layout/ProjectAvatar.tsx +116 -0
  306. package/src/interfaces/web/src/components/layout/ProjectSidebar.tsx +151 -0
  307. package/src/interfaces/web/src/components/settings/AdvancedPanel.tsx +45 -0
  308. package/src/interfaces/web/src/components/settings/AppearancePanel.tsx +72 -0
  309. package/src/interfaces/web/src/components/settings/DefaultRouterCard.tsx +232 -0
  310. package/src/interfaces/web/src/components/settings/DevicesPanel.tsx +60 -0
  311. package/src/interfaces/web/src/components/settings/EnginesPanel.tsx +127 -0
  312. package/src/interfaces/web/src/components/settings/IdentityPanel.tsx +69 -0
  313. package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +226 -0
  314. package/src/interfaces/web/src/components/settings/PairDeviceDialog.tsx +175 -0
  315. package/src/interfaces/web/src/components/settings/SuperAgentPanel.tsx +93 -0
  316. package/src/interfaces/web/src/components/settings/TelegramChannelsPanel.tsx +90 -0
  317. package/src/interfaces/web/src/components/settings/TelegramContactsPanel.tsx +101 -0
  318. package/src/interfaces/web/src/components/settings/TelegramGlobalPanel.tsx +100 -0
  319. package/src/interfaces/web/src/components/settings/TelegramRolesPanel.tsx +108 -0
  320. package/src/interfaces/web/src/components/settings/TelegramSettingsTabs.tsx +55 -0
  321. package/src/interfaces/web/src/components/settings/providers/ProviderCard.tsx +95 -0
  322. package/src/interfaces/web/src/components/settings/providers/ProviderModal.tsx +405 -0
  323. package/src/interfaces/web/src/components/settings/providers/typeStyles.ts +155 -0
  324. package/src/interfaces/web/src/components/settings/providers/types.ts +26 -0
  325. package/src/interfaces/web/src/components/ui/accordion.tsx +72 -0
  326. package/src/interfaces/web/src/components/ui/alert-dialog.tsx +187 -0
  327. package/src/interfaces/web/src/components/ui/alert.tsx +76 -0
  328. package/src/interfaces/web/src/components/ui/aspect-ratio.tsx +22 -0
  329. package/src/interfaces/web/src/components/ui/avatar.tsx +107 -0
  330. package/src/interfaces/web/src/components/ui/badge.tsx +52 -0
  331. package/src/interfaces/web/src/components/ui/breadcrumb.tsx +125 -0
  332. package/src/interfaces/web/src/components/ui/button-group.tsx +87 -0
  333. package/src/interfaces/web/src/components/ui/button.tsx +58 -0
  334. package/src/interfaces/web/src/components/ui/calendar.tsx +221 -0
  335. package/src/interfaces/web/src/components/ui/card.tsx +103 -0
  336. package/src/interfaces/web/src/components/ui/carousel.tsx +242 -0
  337. package/src/interfaces/web/src/components/ui/chart.tsx +371 -0
  338. package/src/interfaces/web/src/components/ui/chat-input.tsx +122 -0
  339. package/src/interfaces/web/src/components/ui/checkbox.tsx +29 -0
  340. package/src/interfaces/web/src/components/ui/collapsible.tsx +19 -0
  341. package/src/interfaces/web/src/components/ui/combobox.tsx +295 -0
  342. package/src/interfaces/web/src/components/ui/command.tsx +196 -0
  343. package/src/interfaces/web/src/components/ui/context-menu.tsx +271 -0
  344. package/src/interfaces/web/src/components/ui/dialog.tsx +158 -0
  345. package/src/interfaces/web/src/components/ui/direction.tsx +4 -0
  346. package/src/interfaces/web/src/components/ui/drawer.tsx +134 -0
  347. package/src/interfaces/web/src/components/ui/dropdown-menu.tsx +266 -0
  348. package/src/interfaces/web/src/components/ui/empty.tsx +104 -0
  349. package/src/interfaces/web/src/components/ui/field.tsx +236 -0
  350. package/src/interfaces/web/src/components/ui/hover-card.tsx +51 -0
  351. package/src/interfaces/web/src/components/ui/input-group.tsx +158 -0
  352. package/src/interfaces/web/src/components/ui/input-otp.tsx +85 -0
  353. package/src/interfaces/web/src/components/ui/input.tsx +20 -0
  354. package/src/interfaces/web/src/components/ui/item.tsx +201 -0
  355. package/src/interfaces/web/src/components/ui/kbd.tsx +26 -0
  356. package/src/interfaces/web/src/components/ui/label.tsx +20 -0
  357. package/src/interfaces/web/src/components/ui/menubar.tsx +280 -0
  358. package/src/interfaces/web/src/components/ui/native-select.tsx +61 -0
  359. package/src/interfaces/web/src/components/ui/navigation-menu.tsx +168 -0
  360. package/src/interfaces/web/src/components/ui/pagination.tsx +130 -0
  361. package/src/interfaces/web/src/components/ui/popover.tsx +88 -0
  362. package/src/interfaces/web/src/components/ui/progress.tsx +83 -0
  363. package/src/interfaces/web/src/components/ui/radio-group.tsx +36 -0
  364. package/src/interfaces/web/src/components/ui/resizable.tsx +50 -0
  365. package/src/interfaces/web/src/components/ui/scroll-area.tsx +53 -0
  366. package/src/interfaces/web/src/components/ui/select.tsx +201 -0
  367. package/src/interfaces/web/src/components/ui/separator.tsx +23 -0
  368. package/src/interfaces/web/src/components/ui/sheet.tsx +138 -0
  369. package/src/interfaces/web/src/components/ui/sidebar.tsx +723 -0
  370. package/src/interfaces/web/src/components/ui/skeleton.tsx +13 -0
  371. package/src/interfaces/web/src/components/ui/slider.tsx +52 -0
  372. package/src/interfaces/web/src/components/ui/sonner.tsx +49 -0
  373. package/src/interfaces/web/src/components/ui/spinner.tsx +10 -0
  374. package/src/interfaces/web/src/components/ui/switch.tsx +30 -0
  375. package/src/interfaces/web/src/components/ui/table.tsx +116 -0
  376. package/src/interfaces/web/src/components/ui/tabs.tsx +72 -0
  377. package/src/interfaces/web/src/components/ui/textarea.tsx +18 -0
  378. package/src/interfaces/web/src/components/ui/tip.tsx +21 -0
  379. package/src/interfaces/web/src/components/ui/toggle-group.tsx +87 -0
  380. package/src/interfaces/web/src/components/ui/toggle.tsx +45 -0
  381. package/src/interfaces/web/src/components/ui/tooltip.tsx +64 -0
  382. package/src/interfaces/web/src/components/ui.tsx +211 -0
  383. package/src/interfaces/web/src/components/voice/VoiceProviderList.tsx +197 -0
  384. package/src/interfaces/web/src/components/voice/VoiceProviderModal.tsx +213 -0
  385. package/src/interfaces/web/src/components/voice/VoiceSttCard.tsx +72 -0
  386. package/src/interfaces/web/src/components/voice/VoiceTestCard.tsx +112 -0
  387. package/src/interfaces/web/src/components/voice/useTtsPlayer.ts +59 -0
  388. package/src/interfaces/web/src/constants/index.ts +91 -0
  389. package/src/interfaces/web/src/hooks/use-mobile.ts +19 -0
  390. package/src/interfaces/web/src/hooks/useChat.ts +276 -0
  391. package/src/interfaces/web/src/hooks/useDaemonStatus.ts +12 -0
  392. package/src/interfaces/web/src/hooks/useDevices.ts +12 -0
  393. package/src/interfaces/web/src/hooks/useEngines.ts +10 -0
  394. package/src/interfaces/web/src/hooks/useGlobalConfig.ts +24 -0
  395. package/src/interfaces/web/src/hooks/useIdentity.ts +16 -0
  396. package/src/interfaces/web/src/hooks/useProjects.ts +27 -0
  397. package/src/interfaces/web/src/hooks/useTelegram.ts +35 -0
  398. package/src/interfaces/web/src/hooks/useTheme.tsx +57 -0
  399. package/src/interfaces/web/src/hooks/useTokenBootstrap.ts +122 -0
  400. package/src/interfaces/web/src/i18n/en.ts +767 -0
  401. package/src/interfaces/web/src/i18n/es.ts +770 -0
  402. package/src/interfaces/web/src/i18n/index.ts +86 -0
  403. package/src/interfaces/web/src/lib/api/admin.ts +30 -0
  404. package/src/interfaces/web/src/lib/api/agents.ts +46 -0
  405. package/src/interfaces/web/src/lib/api/code.ts +122 -0
  406. package/src/interfaces/web/src/lib/api/conversations.ts +16 -0
  407. package/src/interfaces/web/src/lib/api/deck.ts +106 -0
  408. package/src/interfaces/web/src/lib/api/desktop.ts +54 -0
  409. package/src/interfaces/web/src/lib/api/embeddings.ts +44 -0
  410. package/src/interfaces/web/src/lib/api/engines.ts +17 -0
  411. package/src/interfaces/web/src/lib/api/filesystem.ts +12 -0
  412. package/src/interfaces/web/src/lib/api/health.ts +6 -0
  413. package/src/interfaces/web/src/lib/api/identity.ts +7 -0
  414. package/src/interfaces/web/src/lib/api/mcps.ts +29 -0
  415. package/src/interfaces/web/src/lib/api/messages.ts +24 -0
  416. package/src/interfaces/web/src/lib/api/projects.ts +29 -0
  417. package/src/interfaces/web/src/lib/api/routines.ts +14 -0
  418. package/src/interfaces/web/src/lib/api/sessions.ts +16 -0
  419. package/src/interfaces/web/src/lib/api/super_agent.ts +29 -0
  420. package/src/interfaces/web/src/lib/api/tasks.ts +19 -0
  421. package/src/interfaces/web/src/lib/api/telegram.ts +57 -0
  422. package/src/interfaces/web/src/lib/api/tools.ts +13 -0
  423. package/src/interfaces/web/src/lib/api/voice.ts +169 -0
  424. package/src/interfaces/web/src/lib/api.ts +48 -0
  425. package/src/interfaces/web/src/lib/cn.ts +6 -0
  426. package/src/interfaces/web/src/lib/code-context.ts +83 -0
  427. package/src/interfaces/web/src/lib/config-values.ts +29 -0
  428. package/src/interfaces/web/src/lib/device.ts +10 -0
  429. package/src/interfaces/web/src/lib/http.ts +104 -0
  430. package/src/interfaces/web/src/lib/secrets.ts +15 -0
  431. package/src/interfaces/web/src/lib/utils.ts +6 -0
  432. package/src/interfaces/web/src/main.tsx +16 -0
  433. package/src/interfaces/web/src/screens/ApxAdminScreen.tsx +174 -0
  434. package/src/interfaces/web/src/screens/PairingScreen.tsx +105 -0
  435. package/src/interfaces/web/src/screens/ProjectScreen.tsx +178 -0
  436. package/src/interfaces/web/src/screens/SettingsScreen.tsx +111 -0
  437. package/src/interfaces/web/src/screens/base/AgentDefaultsTab.tsx +274 -0
  438. package/src/interfaces/web/src/screens/base/ComingSoon.tsx +16 -0
  439. package/src/interfaces/web/src/screens/base/GlobalTasksTab.tsx +53 -0
  440. package/src/interfaces/web/src/screens/base/LogsTab.tsx +188 -0
  441. package/src/interfaces/web/src/screens/base/ModelsTab.tsx +13 -0
  442. package/src/interfaces/web/src/screens/base/SessionsTab.tsx +58 -0
  443. package/src/interfaces/web/src/screens/base/WorkspacesTab.tsx +49 -0
  444. package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +295 -0
  445. package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +173 -0
  446. package/src/interfaces/web/src/screens/modules/DesktopScreen.tsx +304 -0
  447. package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +174 -0
  448. package/src/interfaces/web/src/screens/project/AgentBrainGraph.tsx +152 -0
  449. package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +455 -0
  450. package/src/interfaces/web/src/screens/project/AgentsTab.tsx +364 -0
  451. package/src/interfaces/web/src/screens/project/ChatTab.tsx +198 -0
  452. package/src/interfaces/web/src/screens/project/ConfigTab.tsx +94 -0
  453. package/src/interfaces/web/src/screens/project/McpsTab.tsx +149 -0
  454. package/src/interfaces/web/src/screens/project/MemoriesTab.tsx +134 -0
  455. package/src/interfaces/web/src/screens/project/Overview.tsx +37 -0
  456. package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +386 -0
  457. package/src/interfaces/web/src/screens/project/TasksTab.tsx +116 -0
  458. package/src/interfaces/web/src/screens/project/TelegramTab.tsx +126 -0
  459. package/src/interfaces/web/src/screens/project/ThreadsTab.tsx +100 -0
  460. package/src/interfaces/web/src/styles.css +128 -0
  461. package/src/interfaces/web/src/types/daemon.ts +289 -0
  462. package/src/interfaces/web/tailwind.config.js +53 -0
  463. package/src/interfaces/web/tsconfig.json +24 -0
  464. package/src/interfaces/web/vite.config.ts +50 -0
  465. package/src/cli/commands/exec.js +0 -56
  466. package/src/cli/commands/overlay.js +0 -253
  467. package/src/cli/commands/session.js +0 -395
  468. package/src/cli/commands/sessions.js +0 -517
  469. package/src/cli/commands/telegram.js +0 -77
  470. package/src/cli/postinstall.js +0 -75
  471. package/src/cli-ts/commands/agent.ts +0 -173
  472. package/src/cli-ts/commands/chat.ts +0 -119
  473. package/src/cli-ts/commands/daemon.ts +0 -112
  474. package/src/cli-ts/commands/exec.ts +0 -109
  475. package/src/cli-ts/commands/mcp.ts +0 -235
  476. package/src/cli-ts/commands/session.ts +0 -224
  477. package/src/cli-ts/commands/status.ts +0 -61
  478. package/src/cli-ts/http.ts +0 -36
  479. package/src/cli-ts/index.ts +0 -73
  480. package/src/cli-ts/ui.ts +0 -107
  481. package/src/daemon/api.js +0 -1558
  482. package/src/daemon/engines/gemini.js +0 -56
  483. package/src/daemon/engines/openai.js +0 -79
  484. package/src/daemon/mcp-sources.js +0 -114
  485. package/src/daemon/super-agent-tools/index.js +0 -84
  486. package/src/daemon/super-agent-tools.js +0 -1
  487. package/src/daemon/super-agent.js +0 -541
  488. package/src/overlay/index.html +0 -44
  489. package/src/overlay/main.js +0 -480
  490. package/src/overlay/preload.js +0 -34
  491. package/src/overlay/renderer.js +0 -371
  492. package/src/overlay/style.css +0 -250
  493. package/src/tui/context/sync-apx.tsx +0 -284
  494. package/src/tui/routes/session/index.tsx +0 -274
  495. package/src/tui/routes/session/sidebar-apx.tsx +0 -90
  496. /package/src/{daemon → core}/tools/browser.js +0 -0
  497. /package/src/{daemon → core}/tools/fetch.js +0 -0
  498. /package/src/{daemon → core}/tools/glob.js +0 -0
  499. /package/src/{daemon → core}/tools/grep.js +0 -0
  500. /package/src/{daemon → core}/tools/registry.js +0 -0
  501. /package/src/{daemon → core}/tools/search.js +0 -0
  502. /package/src/{daemon → host/daemon}/conversations.js +0 -0
  503. /package/src/{daemon → host/daemon}/env-detect.js +0 -0
  504. /package/src/{daemon → host/daemon}/runtimes/_spawn.js +0 -0
  505. /package/src/{daemon → host/daemon}/runtimes/aider.js +0 -0
  506. /package/src/{daemon → host/daemon}/runtimes/claude-code.js +0 -0
  507. /package/src/{daemon → host/daemon}/runtimes/codex.js +0 -0
  508. /package/src/{daemon → host/daemon}/runtimes/cursor-agent.js +0 -0
  509. /package/src/{daemon → host/daemon}/runtimes/gemini-cli.js +0 -0
  510. /package/src/{daemon → host/daemon}/runtimes/index.js +0 -0
  511. /package/src/{daemon → host/daemon}/runtimes/opencode.js +0 -0
  512. /package/src/{daemon → host/daemon}/runtimes/qwen-code.js +0 -0
  513. /package/src/{daemon → host/daemon}/super-agent-tools/tools/call-mcp.js +0 -0
  514. /package/src/{daemon → host/daemon}/super-agent-tools/tools/edit-file.js +0 -0
  515. /package/src/{daemon → host/daemon}/super-agent-tools/tools/list-files.js +0 -0
  516. /package/src/{daemon → host/daemon}/super-agent-tools/tools/list-mcps.js +0 -0
  517. /package/src/{daemon → host/daemon}/super-agent-tools/tools/list-projects.js +0 -0
  518. /package/src/{daemon → host/daemon}/super-agent-tools/tools/list-skills.js +0 -0
  519. /package/src/{daemon → host/daemon}/super-agent-tools/tools/load-skill.js +0 -0
  520. /package/src/{daemon → host/daemon}/super-agent-tools/tools/read-agent-memory.js +0 -0
  521. /package/src/{daemon → host/daemon}/super-agent-tools/tools/read-file.js +0 -0
  522. /package/src/{daemon → host/daemon}/super-agent-tools/tools/run-shell.js +0 -0
  523. /package/src/{daemon → host/daemon}/super-agent-tools/tools/search-files.js +0 -0
  524. /package/src/{daemon → host/daemon}/super-agent-tools/tools/transcribe-audio.js +0 -0
  525. /package/src/{daemon → host/daemon}/super-agent-tools/tools/write-file.js +0 -0
  526. /package/src/{daemon → host/daemon}/thinking.js +0 -0
  527. /package/src/{daemon → host/daemon}/whisper-server.py +0 -0
  528. /package/src/{daemon → host/daemon}/whisper-transcribe.py +0 -0
  529. /package/src/{cli → interfaces/cli}/commands/a2a.js +0 -0
  530. /package/src/{cli → interfaces/cli}/commands/artifact.js +0 -0
  531. /package/src/{cli → interfaces/cli}/commands/chat.js +0 -0
  532. /package/src/{cli → interfaces/cli}/commands/log.js +0 -0
  533. /package/src/{cli → interfaces/cli}/commands/messages.js +0 -0
  534. /package/src/{cli → interfaces/cli}/commands/plugins.js +0 -0
  535. /package/src/{cli → interfaces/cli}/commands/routine.js +0 -0
  536. /package/src/{cli → interfaces/cli}/commands/runtime.js +0 -0
  537. /package/src/{cli → interfaces/cli}/terminal-chat/renderer.js +0 -0
  538. /package/src/{overlay → interfaces/desktop}/package.json +0 -0
  539. /package/src/{tui → interfaces/tui}/_shims/cli-error.ts +0 -0
  540. /package/src/{tui → interfaces/tui}/_shims/cli-logo.ts +0 -0
  541. /package/src/{tui → interfaces/tui}/_shims/cli-ui.ts +0 -0
  542. /package/src/{tui → interfaces/tui}/_shims/config-console-state.ts +0 -0
  543. /package/src/{tui → interfaces/tui}/_shims/core-any.ts +0 -0
  544. /package/src/{tui → interfaces/tui}/_shims/core-binary.ts +0 -0
  545. /package/src/{tui → interfaces/tui}/_shims/core-flag.ts +0 -0
  546. /package/src/{tui → interfaces/tui}/_shims/core-log.ts +0 -0
  547. /package/src/{tui → interfaces/tui}/_shims/lsp-language.ts +0 -0
  548. /package/src/{tui → interfaces/tui}/_shims/opencode-any.ts +0 -0
  549. /package/src/{tui → interfaces/tui}/_shims/opencode-sdk-v2.ts +0 -0
  550. /package/src/{tui → interfaces/tui}/_shims/plugin-tui.ts +0 -0
  551. /package/src/{tui → interfaces/tui}/_shims/prompt-display.ts +0 -0
  552. /package/src/{tui → interfaces/tui}/_shims/provider-provider.ts +0 -0
  553. /package/src/{tui → interfaces/tui}/_shims/session-retry.ts +0 -0
  554. /package/src/{tui → interfaces/tui}/_shims/session-schema.ts +0 -0
  555. /package/src/{tui → interfaces/tui}/_shims/session-session.ts +0 -0
  556. /package/src/{tui → interfaces/tui}/_shims/snapshot.ts +0 -0
  557. /package/src/{tui → interfaces/tui}/_shims/tool-any.ts +0 -0
  558. /package/src/{tui → interfaces/tui}/_shims/util-error.ts +0 -0
  559. /package/src/{tui → interfaces/tui}/_shims/util-filesystem.ts +0 -0
  560. /package/src/{tui → interfaces/tui}/_shims/util-format.ts +0 -0
  561. /package/src/{tui → interfaces/tui}/_shims/util-iife.ts +0 -0
  562. /package/src/{tui → interfaces/tui}/_shims/util-locale.ts +0 -0
  563. /package/src/{tui → interfaces/tui}/_shims/util-process.ts +0 -0
  564. /package/src/{tui → interfaces/tui}/asset/charge.wav +0 -0
  565. /package/src/{tui → interfaces/tui}/asset/pulse-a.wav +0 -0
  566. /package/src/{tui → interfaces/tui}/asset/pulse-b.wav +0 -0
  567. /package/src/{tui → interfaces/tui}/asset/pulse-c.wav +0 -0
  568. /package/src/{tui → interfaces/tui}/attach.ts +0 -0
  569. /package/src/{tui → interfaces/tui}/component/bg-pulse-render.ts +0 -0
  570. /package/src/{tui → interfaces/tui}/component/bg-pulse.tsx +0 -0
  571. /package/src/{tui → interfaces/tui}/component/border.tsx +0 -0
  572. /package/src/{tui → interfaces/tui}/component/dialog-agent.tsx +0 -0
  573. /package/src/{tui → interfaces/tui}/component/dialog-console-org.tsx +0 -0
  574. /package/src/{tui → interfaces/tui}/component/dialog-mcp.tsx +0 -0
  575. /package/src/{tui → interfaces/tui}/component/dialog-model.tsx +0 -0
  576. /package/src/{tui → interfaces/tui}/component/dialog-provider.tsx +0 -0
  577. /package/src/{tui → interfaces/tui}/component/dialog-retry-action.tsx +0 -0
  578. /package/src/{tui → interfaces/tui}/component/dialog-session-delete-failed.tsx +0 -0
  579. /package/src/{tui → interfaces/tui}/component/dialog-session-list.tsx +0 -0
  580. /package/src/{tui → interfaces/tui}/component/dialog-session-rename.tsx +0 -0
  581. /package/src/{tui → interfaces/tui}/component/dialog-skill.tsx +0 -0
  582. /package/src/{tui → interfaces/tui}/component/dialog-stash.tsx +0 -0
  583. /package/src/{tui → interfaces/tui}/component/dialog-status.tsx +0 -0
  584. /package/src/{tui → interfaces/tui}/component/dialog-tag.tsx +0 -0
  585. /package/src/{tui → interfaces/tui}/component/dialog-theme-list.tsx +0 -0
  586. /package/src/{tui → interfaces/tui}/component/dialog-variant.tsx +0 -0
  587. /package/src/{tui → interfaces/tui}/component/dialog-workspace-create.tsx +0 -0
  588. /package/src/{tui → interfaces/tui}/component/dialog-workspace-file-changes.tsx +0 -0
  589. /package/src/{tui → interfaces/tui}/component/dialog-workspace-unavailable.tsx +0 -0
  590. /package/src/{tui → interfaces/tui}/component/error-component.tsx +0 -0
  591. /package/src/{tui → interfaces/tui}/component/logo.tsx +0 -0
  592. /package/src/{tui → interfaces/tui}/component/plugin-route-missing.tsx +0 -0
  593. /package/src/{tui → interfaces/tui}/component/prompt/autocomplete.tsx +0 -0
  594. /package/src/{tui → interfaces/tui}/component/prompt/cwd.ts +0 -0
  595. /package/src/{tui → interfaces/tui}/component/prompt/frecency.tsx +0 -0
  596. /package/src/{tui → interfaces/tui}/component/prompt/history.tsx +0 -0
  597. /package/src/{tui → interfaces/tui}/component/prompt/part.ts +0 -0
  598. /package/src/{tui → interfaces/tui}/component/prompt/stash.tsx +0 -0
  599. /package/src/{tui → interfaces/tui}/component/prompt/traits.ts +0 -0
  600. /package/src/{tui → interfaces/tui}/component/spinner.tsx +0 -0
  601. /package/src/{tui → interfaces/tui}/component/startup-loading.tsx +0 -0
  602. /package/src/{tui → interfaces/tui}/component/todo-item.tsx +0 -0
  603. /package/src/{tui → interfaces/tui}/component/use-connected.tsx +0 -0
  604. /package/src/{tui → interfaces/tui}/component/workspace-label.tsx +0 -0
  605. /package/src/{tui → interfaces/tui}/config/cwd.ts +0 -0
  606. /package/src/{tui → interfaces/tui}/config/keybind.ts +0 -0
  607. /package/src/{tui → interfaces/tui}/config/tui-migrate.ts +0 -0
  608. /package/src/{tui → interfaces/tui}/config/tui-schema.ts +0 -0
  609. /package/src/{tui → interfaces/tui}/config/tui.ts +0 -0
  610. /package/src/{tui → interfaces/tui}/context/aggregate-failures.ts +0 -0
  611. /package/src/{tui → interfaces/tui}/context/args.tsx +0 -0
  612. /package/src/{tui → interfaces/tui}/context/command-palette.tsx +0 -0
  613. /package/src/{tui → interfaces/tui}/context/directory.ts +0 -0
  614. /package/src/{tui → interfaces/tui}/context/editor-zed.ts +0 -0
  615. /package/src/{tui → interfaces/tui}/context/editor.ts +0 -0
  616. /package/src/{tui → interfaces/tui}/context/event-apx.ts +0 -0
  617. /package/src/{tui → interfaces/tui}/context/event.ts +0 -0
  618. /package/src/{tui → interfaces/tui}/context/exit.tsx +0 -0
  619. /package/src/{tui → interfaces/tui}/context/helper.tsx +0 -0
  620. /package/src/{tui → interfaces/tui}/context/kv.tsx +0 -0
  621. /package/src/{tui → interfaces/tui}/context/local.tsx +0 -0
  622. /package/src/{tui → interfaces/tui}/context/path-format.tsx +0 -0
  623. /package/src/{tui → interfaces/tui}/context/project-apx.tsx +0 -0
  624. /package/src/{tui → interfaces/tui}/context/project.tsx +0 -0
  625. /package/src/{tui → interfaces/tui}/context/prompt.tsx +0 -0
  626. /package/src/{tui → interfaces/tui}/context/route.tsx +0 -0
  627. /package/src/{tui → interfaces/tui}/context/sdk.tsx +0 -0
  628. /package/src/{tui → interfaces/tui}/context/sync-v2.tsx +0 -0
  629. /package/src/{tui → interfaces/tui}/context/sync.tsx +0 -0
  630. /package/src/{tui → interfaces/tui}/context/theme/aura.json +0 -0
  631. /package/src/{tui → interfaces/tui}/context/theme/ayu.json +0 -0
  632. /package/src/{tui → interfaces/tui}/context/theme/carbonfox.json +0 -0
  633. /package/src/{tui → interfaces/tui}/context/theme/catppuccin-frappe.json +0 -0
  634. /package/src/{tui → interfaces/tui}/context/theme/catppuccin-macchiato.json +0 -0
  635. /package/src/{tui → interfaces/tui}/context/theme/catppuccin.json +0 -0
  636. /package/src/{tui → interfaces/tui}/context/theme/cobalt2.json +0 -0
  637. /package/src/{tui → interfaces/tui}/context/theme/cursor.json +0 -0
  638. /package/src/{tui → interfaces/tui}/context/theme/dracula.json +0 -0
  639. /package/src/{tui → interfaces/tui}/context/theme/everforest.json +0 -0
  640. /package/src/{tui → interfaces/tui}/context/theme/flexoki.json +0 -0
  641. /package/src/{tui → interfaces/tui}/context/theme/github.json +0 -0
  642. /package/src/{tui → interfaces/tui}/context/theme/gruvbox.json +0 -0
  643. /package/src/{tui → interfaces/tui}/context/theme/kanagawa.json +0 -0
  644. /package/src/{tui → interfaces/tui}/context/theme/lucent-orng.json +0 -0
  645. /package/src/{tui → interfaces/tui}/context/theme/material.json +0 -0
  646. /package/src/{tui → interfaces/tui}/context/theme/matrix.json +0 -0
  647. /package/src/{tui → interfaces/tui}/context/theme/mercury.json +0 -0
  648. /package/src/{tui → interfaces/tui}/context/theme/monokai.json +0 -0
  649. /package/src/{tui → interfaces/tui}/context/theme/nightowl.json +0 -0
  650. /package/src/{tui → interfaces/tui}/context/theme/nord.json +0 -0
  651. /package/src/{tui → interfaces/tui}/context/theme/one-dark.json +0 -0
  652. /package/src/{tui → interfaces/tui}/context/theme/opencode.json +0 -0
  653. /package/src/{tui → interfaces/tui}/context/theme/orng.json +0 -0
  654. /package/src/{tui → interfaces/tui}/context/theme/osaka-jade.json +0 -0
  655. /package/src/{tui → interfaces/tui}/context/theme/palenight.json +0 -0
  656. /package/src/{tui → interfaces/tui}/context/theme/rosepine.json +0 -0
  657. /package/src/{tui → interfaces/tui}/context/theme/solarized.json +0 -0
  658. /package/src/{tui → interfaces/tui}/context/theme/synthwave84.json +0 -0
  659. /package/src/{tui → interfaces/tui}/context/theme/tokyonight.json +0 -0
  660. /package/src/{tui → interfaces/tui}/context/theme/vercel.json +0 -0
  661. /package/src/{tui → interfaces/tui}/context/theme/vesper.json +0 -0
  662. /package/src/{tui → interfaces/tui}/context/theme/zenburn.json +0 -0
  663. /package/src/{tui → interfaces/tui}/context/theme.tsx +0 -0
  664. /package/src/{tui → interfaces/tui}/context/tui-config.tsx +0 -0
  665. /package/src/{tui → interfaces/tui}/event.ts +0 -0
  666. /package/src/{tui → interfaces/tui}/feature-plugins/home/footer.tsx +0 -0
  667. /package/src/{tui → interfaces/tui}/feature-plugins/home/tips-view.tsx +0 -0
  668. /package/src/{tui → interfaces/tui}/feature-plugins/home/tips.tsx +0 -0
  669. /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/context.tsx +0 -0
  670. /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/files.tsx +0 -0
  671. /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/footer.tsx +0 -0
  672. /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/lsp.tsx +0 -0
  673. /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/mcp.tsx +0 -0
  674. /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/todo.tsx +0 -0
  675. /package/src/{tui → interfaces/tui}/feature-plugins/system/plugins.tsx +0 -0
  676. /package/src/{tui → interfaces/tui}/feature-plugins/system/session-v2.tsx +0 -0
  677. /package/src/{tui → interfaces/tui}/feature-plugins/system/which-key.tsx +0 -0
  678. /package/src/{tui → interfaces/tui}/keymap.tsx +0 -0
  679. /package/src/{tui → interfaces/tui}/layer.ts +0 -0
  680. /package/src/{tui → interfaces/tui}/plugin/api.tsx +0 -0
  681. /package/src/{tui → interfaces/tui}/plugin/command-shim.ts +0 -0
  682. /package/src/{tui → interfaces/tui}/plugin/internal.ts +0 -0
  683. /package/src/{tui → interfaces/tui}/plugin/runtime.ts +0 -0
  684. /package/src/{tui → interfaces/tui}/plugin/slots.tsx +0 -0
  685. /package/src/{tui → interfaces/tui}/routes/home.tsx +0 -0
  686. /package/src/{tui → interfaces/tui}/routes/session/dialog-fork-from-timeline.tsx +0 -0
  687. /package/src/{tui → interfaces/tui}/routes/session/dialog-message.tsx +0 -0
  688. /package/src/{tui → interfaces/tui}/routes/session/dialog-subagent.tsx +0 -0
  689. /package/src/{tui → interfaces/tui}/routes/session/dialog-timeline.tsx +0 -0
  690. /package/src/{tui → interfaces/tui}/routes/session/footer.tsx +0 -0
  691. /package/src/{tui → interfaces/tui}/routes/session/permission.tsx +0 -0
  692. /package/src/{tui → interfaces/tui}/routes/session/question.tsx +0 -0
  693. /package/src/{tui → interfaces/tui}/routes/session/sidebar.tsx +0 -0
  694. /package/src/{tui → interfaces/tui}/routes/session/subagent-footer.tsx +0 -0
  695. /package/src/{tui → interfaces/tui}/run.ts +0 -0
  696. /package/src/{tui → interfaces/tui}/thread.ts +0 -0
  697. /package/src/{tui → interfaces/tui}/ui/dialog-alert.tsx +0 -0
  698. /package/src/{tui → interfaces/tui}/ui/dialog-confirm.tsx +0 -0
  699. /package/src/{tui → interfaces/tui}/ui/dialog-export-options.tsx +0 -0
  700. /package/src/{tui → interfaces/tui}/ui/dialog-help.tsx +0 -0
  701. /package/src/{tui → interfaces/tui}/ui/dialog-prompt.tsx +0 -0
  702. /package/src/{tui → interfaces/tui}/ui/dialog-select.tsx +0 -0
  703. /package/src/{tui → interfaces/tui}/ui/dialog.tsx +0 -0
  704. /package/src/{tui → interfaces/tui}/ui/link.tsx +0 -0
  705. /package/src/{tui → interfaces/tui}/ui/spinner.ts +0 -0
  706. /package/src/{tui → interfaces/tui}/ui/toast.tsx +0 -0
  707. /package/src/{tui → interfaces/tui}/util/editor.ts +0 -0
  708. /package/src/{tui → interfaces/tui}/util/model.ts +0 -0
  709. /package/src/{tui → interfaces/tui}/util/provider-origin.ts +0 -0
  710. /package/src/{tui → interfaces/tui}/util/revert-diff.ts +0 -0
  711. /package/src/{tui → interfaces/tui}/util/scroll.ts +0 -0
  712. /package/src/{tui → interfaces/tui}/util/selection.ts +0 -0
  713. /package/src/{tui → interfaces/tui}/util/signal.ts +0 -0
  714. /package/src/{tui → interfaces/tui}/util/sound.ts +0 -0
  715. /package/src/{tui → interfaces/tui}/util/transcript.ts +0 -0
  716. /package/src/{tui → interfaces/tui}/validate-session.ts +0 -0
  717. /package/src/{tui → interfaces/tui}/win32.ts +0 -0
  718. /package/src/{tui → interfaces/tui}/worker.ts +0 -0
@@ -0,0 +1,997 @@
1
+ // apx sessions — list AI engine sessions (Claude Code, Codex, APX, ...) without
2
+ // opening an interactive picker. Each engine is a small adapter; the command
3
+ // resolves a working directory (from a registered APX project or an explicit
4
+ // --dir) and asks the adapter to list that engine's sessions for it.
5
+ import fs from "node:fs";
6
+ import os from "node:os";
7
+ import path from "node:path";
8
+
9
+ // ── shared helpers ───────────────────────────────────────────────────────────
10
+
11
+ const homeDir = (opts) => (opts && opts.home) || os.homedir();
12
+
13
+ // Claude Code encodes a project cwd into a folder name by replacing every
14
+ // non-alphanumeric character with "-". Mirrors encodeClaudeProjectPath in the
15
+ // claude-code runtime adapter.
16
+ function encodeClaudeProjectPath(cwd) {
17
+ return String(cwd || "").replace(/[^A-Za-z0-9]/g, "-");
18
+ }
19
+
20
+ function safeStatMtime(p) {
21
+ try {
22
+ return fs.statSync(p).mtimeMs;
23
+ } catch {
24
+ return 0;
25
+ }
26
+ }
27
+
28
+ // File-modification timestamps get clobbered by Time Machine and other backup
29
+ // tools. Most engines write a `"timestamp": "<iso>"` field on every JSONL line
30
+ // — when present, that's a far more reliable order key than mtime. We read a
31
+ // short tail of the file and scan back for the latest valid timestamp,
32
+ // falling back to the head, then mtime, when nothing parses.
33
+ function readInternalTimestamp(file, { tailBytes = 8192, headBytes = 8192 } = {}) {
34
+ let stat;
35
+ try {
36
+ stat = fs.statSync(file);
37
+ } catch {
38
+ return 0;
39
+ }
40
+ const tail = readTimestampFromRange(file, Math.max(0, stat.size - tailBytes), stat.size, { fromEnd: true });
41
+ if (tail) return tail;
42
+ if (stat.size > tailBytes) {
43
+ const head = readTimestampFromRange(file, 0, Math.min(stat.size, headBytes), { fromEnd: false });
44
+ if (head) return head;
45
+ }
46
+ return stat.mtimeMs || 0;
47
+ }
48
+
49
+ function readTimestampFromRange(file, start, end, { fromEnd }) {
50
+ if (end <= start) return 0;
51
+ let buf;
52
+ try {
53
+ const fd = fs.openSync(file, "r");
54
+ try {
55
+ buf = Buffer.alloc(end - start);
56
+ fs.readSync(fd, buf, 0, buf.length, start);
57
+ } finally {
58
+ try { fs.closeSync(fd); } catch {}
59
+ }
60
+ } catch {
61
+ return 0;
62
+ }
63
+ const lines = buf.toString("utf8").split("\n");
64
+ const order = fromEnd ? [...lines.keys()].reverse() : [...lines.keys()];
65
+ for (const i of order) {
66
+ const line = lines[i];
67
+ if (!line || !line.includes('"timestamp"')) continue;
68
+ let d;
69
+ try {
70
+ d = JSON.parse(line);
71
+ } catch {
72
+ continue;
73
+ }
74
+ const ts = d?.timestamp || d?.payload?.timestamp;
75
+ if (!ts) continue;
76
+ const t = Date.parse(ts);
77
+ if (!Number.isNaN(t)) return t;
78
+ }
79
+ return 0;
80
+ }
81
+
82
+ function sessionTimestamp(file) {
83
+ return readInternalTimestamp(file) || safeStatMtime(file);
84
+ }
85
+
86
+ function fmtDate(ms) {
87
+ if (!ms) return " ";
88
+ const d = new Date(ms);
89
+ const p = (n) => String(n).padStart(2, "0");
90
+ return `${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`;
91
+ }
92
+
93
+ // Read the first bytes of a file (used for one-line JSONL headers).
94
+ function readHead(file, bytes = 8192) {
95
+ let fd;
96
+ try {
97
+ fd = fs.openSync(file, "r");
98
+ const buf = Buffer.alloc(bytes);
99
+ const n = fs.readSync(fd, buf, 0, bytes, 0);
100
+ return buf.subarray(0, n).toString("utf8");
101
+ } catch {
102
+ return "";
103
+ } finally {
104
+ if (fd !== undefined) {
105
+ try {
106
+ fs.closeSync(fd);
107
+ } catch {}
108
+ }
109
+ }
110
+ }
111
+
112
+ // Registered APX projects come from ~/.apx/config.json — APX does not know
113
+ // every project on disk, so an unregistered project must be passed via --dir.
114
+ function readApxProjects(opts) {
115
+ const cfgPath = path.join(homeDir(opts), ".apx", "config.json");
116
+ let entries = [];
117
+ try {
118
+ const cfg = JSON.parse(fs.readFileSync(cfgPath, "utf8"));
119
+ entries = Array.isArray(cfg.projects) ? cfg.projects : [];
120
+ } catch {}
121
+ return entries
122
+ .filter((e) => e && e.path)
123
+ .map((e) => {
124
+ const proj = { path: path.resolve(e.path), name: null, apxId: null };
125
+ try {
126
+ const pj = JSON.parse(
127
+ fs.readFileSync(path.join(proj.path, ".apc", "project.json"), "utf8")
128
+ );
129
+ if (pj.name) proj.name = pj.name;
130
+ if (pj.apx_id) proj.apxId = pj.apx_id;
131
+ } catch {}
132
+ if (!proj.name) proj.name = path.basename(proj.path);
133
+ return proj;
134
+ });
135
+ }
136
+
137
+ // Resolve the working directory the user wants sessions for.
138
+ // --dir <path> → explicit path
139
+ // --project <name> → look up a registered APX project
140
+ // neither → null (caller enters discovery mode)
141
+ function resolveTargetDir(args, opts) {
142
+ const dirFlag = args.flags.dir;
143
+ if (dirFlag && dirFlag !== true) return path.resolve(String(dirFlag));
144
+
145
+ const projFlag = args.flags.project;
146
+ if (projFlag && projFlag !== true) {
147
+ const q = String(projFlag).toLowerCase();
148
+ const projects = readApxProjects(opts);
149
+ const exact =
150
+ projects.find((p) => p.name.toLowerCase() === q) ||
151
+ projects.find((p) => path.basename(p.path).toLowerCase() === q);
152
+ if (exact) return exact.path;
153
+
154
+ const fuzzy = projects.filter(
155
+ (p) =>
156
+ p.name.toLowerCase().includes(q) || p.path.toLowerCase().includes(q)
157
+ );
158
+ if (fuzzy.length === 1) return fuzzy[0].path;
159
+ if (fuzzy.length > 1) {
160
+ throw new Error(
161
+ `--project "${projFlag}" is ambiguous; matches: ${fuzzy
162
+ .map((p) => p.name)
163
+ .join(", ")}`
164
+ );
165
+ }
166
+ const known = projects.length
167
+ ? projects.map((p) => p.name).join(", ")
168
+ : "(none registered)";
169
+ throw new Error(
170
+ `--project "${projFlag}" not found in registered APX projects (${known}). ` +
171
+ `Use --dir <path> for an unregistered project.`
172
+ );
173
+ }
174
+ return null;
175
+ }
176
+
177
+ // ── claude code engine ───────────────────────────────────────────────────────
178
+
179
+ function claudeProjectsDir(opts) {
180
+ return path.join(homeDir(opts), ".claude", "projects");
181
+ }
182
+
183
+ function claudeReadTitle(file) {
184
+ let title = null;
185
+ let lastPrompt = null;
186
+ let text;
187
+ try {
188
+ text = fs.readFileSync(file, "utf8");
189
+ } catch {
190
+ return null;
191
+ }
192
+ for (const line of text.split("\n")) {
193
+ if (!line.includes('"aiTitle"') && !line.includes('"lastPrompt"')) continue;
194
+ let d;
195
+ try {
196
+ d = JSON.parse(line);
197
+ } catch {
198
+ continue;
199
+ }
200
+ if (d.type === "ai-title" && d.aiTitle) title = d.aiTitle;
201
+ else if (d.type === "last-prompt" && d.lastPrompt) lastPrompt = d.lastPrompt;
202
+ }
203
+ return title || lastPrompt || null;
204
+ }
205
+
206
+ // Decode a Claude project folder name back to a cwd-like path. The encoding is
207
+ // lossy (every non-alphanumeric becomes "-"), so this returns the encoded name
208
+ // when no registered APX project maps back to a real cwd.
209
+ function claudeDecodeProject(encoded, opts) {
210
+ const known = readApxProjects(opts);
211
+ const hit = known.find((p) => encodeClaudeProjectPath(p.path) === encoded);
212
+ return hit ? hit.path : null;
213
+ }
214
+
215
+ const claudeEngine = {
216
+ id: "claude",
217
+ label: "Claude Code",
218
+ implemented: true,
219
+ detect(opts) {
220
+ const dir = claudeProjectsDir(opts);
221
+ return fs.existsSync(dir)
222
+ ? { available: true }
223
+ : { available: false, reason: `${dir} not found` };
224
+ },
225
+ // Locate <id>.jsonl across every Claude project folder. Used by
226
+ // `apx session resume <id>` so the user doesn't need to know the cwd.
227
+ findSessionById(id, opts) {
228
+ const root = claudeProjectsDir(opts);
229
+ if (!fs.existsSync(root)) return null;
230
+ for (const name of fs.readdirSync(root)) {
231
+ const file = path.join(root, name, `${id}.jsonl`);
232
+ if (fs.existsSync(file)) {
233
+ return {
234
+ engine: "claude",
235
+ id,
236
+ path: file,
237
+ cwd: claudeDecodeProject(name, opts) || name,
238
+ mtime: sessionTimestamp(file),
239
+ title: claudeReadTitle(file) || "(sin título)",
240
+ };
241
+ }
242
+ }
243
+ return null;
244
+ },
245
+ // Read the full JSONL transcript. Returns raw text plus a tail trimmed to
246
+ // tailBytes (default 64 KB) so callers can show "last N bytes" without
247
+ // loading huge logs into memory.
248
+ readSession(meta, { tailBytes = 64 * 1024 } = {}) {
249
+ if (!meta?.path || !fs.existsSync(meta.path)) {
250
+ return { found: false };
251
+ }
252
+ const raw = fs.readFileSync(meta.path, "utf8");
253
+ return {
254
+ found: true,
255
+ raw,
256
+ tail: raw.length > tailBytes ? raw.slice(-tailBytes) : raw,
257
+ size: raw.length,
258
+ format: "jsonl",
259
+ };
260
+ },
261
+ listProjects(opts) {
262
+ const root = claudeProjectsDir(opts);
263
+ const known = new Map(
264
+ readApxProjects(opts).map((p) => [encodeClaudeProjectPath(p.path), p])
265
+ );
266
+ const out = [];
267
+ for (const name of fs.readdirSync(root)) {
268
+ const dir = path.join(root, name);
269
+ let files;
270
+ try {
271
+ files = fs.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
272
+ } catch {
273
+ continue;
274
+ }
275
+ if (files.length === 0) continue;
276
+ const matched = known.get(name);
277
+ out.push({
278
+ key: matched ? matched.name : name,
279
+ dir: matched ? matched.path : null,
280
+ label: matched ? matched.path : name,
281
+ count: files.length,
282
+ mtime: Math.max(...files.map((f) => sessionTimestamp(path.join(dir, f)))),
283
+ });
284
+ }
285
+ return out.sort((a, b) => b.mtime - a.mtime);
286
+ },
287
+ listSessions(dir, opts) {
288
+ const folder = path.join(
289
+ claudeProjectsDir(opts),
290
+ encodeClaudeProjectPath(dir)
291
+ );
292
+ if (!fs.existsSync(folder)) return { found: false, location: folder };
293
+ const sessions = [];
294
+ for (const f of fs.readdirSync(folder)) {
295
+ if (!f.endsWith(".jsonl")) continue;
296
+ const file = path.join(folder, f);
297
+ sessions.push({
298
+ id: f.slice(0, -6),
299
+ mtime: sessionTimestamp(file),
300
+ title: claudeReadTitle(file) || "(sin título)",
301
+ path: file,
302
+ });
303
+ }
304
+ sessions.sort((a, b) => b.mtime - a.mtime);
305
+ return { found: true, location: folder, sessions };
306
+ },
307
+ continueHint() {
308
+ return `claude --continue (run from the project directory)`;
309
+ },
310
+ resumeHint(id) {
311
+ return `claude -p --resume ${id} "your prompt"`;
312
+ },
313
+ };
314
+
315
+ // ── codex engine ─────────────────────────────────────────────────────────────
316
+
317
+ function codexSessionsDir(opts) {
318
+ return path.join(homeDir(opts), ".codex", "sessions");
319
+ }
320
+
321
+ // Codex stores titles in ~/.codex/session_index.jsonl keyed by session id.
322
+ function codexTitleIndex(opts) {
323
+ const file = path.join(homeDir(opts), ".codex", "session_index.jsonl");
324
+ const map = new Map();
325
+ let text;
326
+ try {
327
+ text = fs.readFileSync(file, "utf8");
328
+ } catch {
329
+ return map;
330
+ }
331
+ for (const line of text.split("\n")) {
332
+ if (!line.trim()) continue;
333
+ try {
334
+ const d = JSON.parse(line);
335
+ if (d.id && d.thread_name) map.set(d.id, d.thread_name);
336
+ } catch {}
337
+ }
338
+ return map;
339
+ }
340
+
341
+ // Walk ~/.codex/sessions/YYYY/MM/DD/ collecting rollout-*.jsonl files and
342
+ // reading their session_meta header (first line) for id + cwd. Prefers the
343
+ // internal timestamp over mtime so backups don't scramble the order.
344
+ function codexScanRollouts(opts) {
345
+ const root = codexSessionsDir(opts);
346
+ const found = [];
347
+ const walk = (dir) => {
348
+ let entries;
349
+ try {
350
+ entries = fs.readdirSync(dir, { withFileTypes: true });
351
+ } catch {
352
+ return;
353
+ }
354
+ for (const e of entries) {
355
+ const full = path.join(dir, e.name);
356
+ if (e.isDirectory()) walk(full);
357
+ else if (e.name.startsWith("rollout-") && e.name.endsWith(".jsonl")) {
358
+ const head = readHead(full);
359
+ const id = (head.match(/"id":"([^"]+)"/) || [])[1];
360
+ const cwd = (head.match(/"cwd":"([^"]+)"/) || [])[1];
361
+ if (id) found.push({ id, cwd: cwd || null, mtime: sessionTimestamp(full) });
362
+ }
363
+ }
364
+ };
365
+ walk(root);
366
+ return found;
367
+ }
368
+
369
+ // Scan rollouts but also keep the absolute path so resume-by-id can read the
370
+ // file straight off disk. Old codexScanRollouts dropped the path; this helper
371
+ // keeps it.
372
+ function codexScanRolloutsWithPath(opts) {
373
+ const root = codexSessionsDir(opts);
374
+ const found = [];
375
+ const walk = (dir) => {
376
+ let entries;
377
+ try {
378
+ entries = fs.readdirSync(dir, { withFileTypes: true });
379
+ } catch {
380
+ return;
381
+ }
382
+ for (const e of entries) {
383
+ const full = path.join(dir, e.name);
384
+ if (e.isDirectory()) walk(full);
385
+ else if (e.name.startsWith("rollout-") && e.name.endsWith(".jsonl")) {
386
+ const head = readHead(full);
387
+ const id = (head.match(/"id":"([^"]+)"/) || [])[1];
388
+ const cwd = (head.match(/"cwd":"([^"]+)"/) || [])[1];
389
+ if (id)
390
+ found.push({
391
+ id,
392
+ cwd: cwd || null,
393
+ mtime: sessionTimestamp(full),
394
+ path: full,
395
+ });
396
+ }
397
+ }
398
+ };
399
+ walk(root);
400
+ return found;
401
+ }
402
+
403
+ const codexEngine = {
404
+ id: "codex",
405
+ label: "Codex",
406
+ implemented: true,
407
+ detect(opts) {
408
+ const dir = codexSessionsDir(opts);
409
+ return fs.existsSync(dir)
410
+ ? { available: true }
411
+ : { available: false, reason: `${dir} not found` };
412
+ },
413
+ findSessionById(id, opts) {
414
+ const hit = codexScanRolloutsWithPath(opts).find((r) => r.id === id);
415
+ if (!hit) return null;
416
+ const titles = codexTitleIndex(opts);
417
+ return {
418
+ engine: "codex",
419
+ id,
420
+ path: hit.path,
421
+ cwd: hit.cwd,
422
+ mtime: hit.mtime,
423
+ title: titles.get(id) || "(sin título)",
424
+ };
425
+ },
426
+ readSession(meta, { tailBytes = 64 * 1024 } = {}) {
427
+ if (!meta?.path || !fs.existsSync(meta.path)) {
428
+ return { found: false };
429
+ }
430
+ const raw = fs.readFileSync(meta.path, "utf8");
431
+ return {
432
+ found: true,
433
+ raw,
434
+ tail: raw.length > tailBytes ? raw.slice(-tailBytes) : raw,
435
+ size: raw.length,
436
+ format: "jsonl",
437
+ };
438
+ },
439
+ listProjects(opts) {
440
+ const byCwd = new Map();
441
+ for (const r of codexScanRollouts(opts)) {
442
+ if (!r.cwd) continue;
443
+ const cur = byCwd.get(r.cwd) || { count: 0, mtime: 0 };
444
+ cur.count++;
445
+ if (r.mtime > cur.mtime) cur.mtime = r.mtime;
446
+ byCwd.set(r.cwd, cur);
447
+ }
448
+ return [...byCwd.entries()]
449
+ .map(([cwd, v]) => ({
450
+ key: cwd,
451
+ dir: cwd,
452
+ label: cwd,
453
+ count: v.count,
454
+ mtime: v.mtime,
455
+ }))
456
+ .sort((a, b) => b.mtime - a.mtime);
457
+ },
458
+ listSessions(dir, opts) {
459
+ const titles = codexTitleIndex(opts);
460
+ const sessions = codexScanRolloutsWithPath(opts)
461
+ .filter((r) => r.cwd === dir)
462
+ .map((r) => ({
463
+ id: r.id,
464
+ mtime: r.mtime,
465
+ title: titles.get(r.id) || "(sin título)",
466
+ path: r.path,
467
+ }))
468
+ .sort((a, b) => b.mtime - a.mtime);
469
+ return { found: sessions.length > 0, location: dir, sessions };
470
+ },
471
+ continueHint() {
472
+ return `codex resume --last`;
473
+ },
474
+ resumeHint(id) {
475
+ return `codex exec resume ${id} "your prompt" (interactive: codex resume ${id})`;
476
+ },
477
+ };
478
+
479
+ // ── apx engine (default) ─────────────────────────────────────────────────────
480
+
481
+ function parseFrontmatter(text) {
482
+ if (!text.startsWith("---\n")) return {};
483
+ const end = text.indexOf("\n---", 4);
484
+ if (end === -1) return {};
485
+ const fm = {};
486
+ for (const line of text.slice(4, end).split("\n")) {
487
+ const m = line.match(/^([a-zA-Z_]+):\s*(.*)$/);
488
+ if (m) fm[m[1]] = m[2].trim();
489
+ }
490
+ return fm;
491
+ }
492
+
493
+ // APX sessions are .md with ISO timestamps in frontmatter — prefer those over
494
+ // mtime for the same backup-safety reason the JSONL engines do.
495
+ function apxSessionTimestamp(fm, file) {
496
+ for (const field of ["completed", "started"]) {
497
+ const v = fm?.[field];
498
+ if (!v || typeof v !== "string") continue;
499
+ const t = Date.parse(v);
500
+ if (!Number.isNaN(t)) return t;
501
+ }
502
+ return safeStatMtime(file);
503
+ }
504
+
505
+ function apxStorageRoot(opts) {
506
+ return path.join(homeDir(opts), ".apx", "projects");
507
+ }
508
+
509
+ const apxEngine = {
510
+ id: "apx",
511
+ label: "APX",
512
+ implemented: true,
513
+ detect() {
514
+ return { available: true };
515
+ },
516
+ // Walk every registered APX project looking for a session file whose
517
+ // frontmatter `id:` or filename (without .md) equals the given id.
518
+ findSessionById(id, opts) {
519
+ const projects = readApxProjects(opts);
520
+ for (const proj of projects) {
521
+ if (!proj.apxId) continue;
522
+ const agentsDir = path.join(apxStorageRoot(opts), proj.apxId, "agents");
523
+ if (!fs.existsSync(agentsDir)) continue;
524
+ for (const slug of fs.readdirSync(agentsDir)) {
525
+ const sdir = path.join(agentsDir, slug, "sessions");
526
+ let files;
527
+ try {
528
+ files = fs.readdirSync(sdir);
529
+ } catch {
530
+ continue;
531
+ }
532
+ for (const f of files) {
533
+ if (!f.endsWith(".md")) continue;
534
+ const file = path.join(sdir, f);
535
+ const baseId = f.slice(0, -3);
536
+ const fm = parseFrontmatter(fs.readFileSync(file, "utf8"));
537
+ if (fm.id === id || baseId === id) {
538
+ return {
539
+ engine: "apx",
540
+ id: fm.id || baseId,
541
+ path: file,
542
+ cwd: proj.path,
543
+ mtime: apxSessionTimestamp(fm, file),
544
+ title: fm.title || baseId,
545
+ agentSlug: slug,
546
+ apxId: proj.apxId,
547
+ projectName: proj.name,
548
+ externalSessionPath: fm.external_session_path || null,
549
+ };
550
+ }
551
+ }
552
+ }
553
+ }
554
+ return null;
555
+ },
556
+ // Read the APX session markdown. If the frontmatter points to an external
557
+ // transcript (the JSONL the underlying engine left behind), include its tail
558
+ // too — same data shape callers see for claude/codex direct reads.
559
+ readSession(meta, { tailBytes = 64 * 1024 } = {}) {
560
+ if (!meta?.path || !fs.existsSync(meta.path)) {
561
+ return { found: false };
562
+ }
563
+ const raw = fs.readFileSync(meta.path, "utf8");
564
+ const result = {
565
+ found: true,
566
+ raw,
567
+ tail: raw,
568
+ size: raw.length,
569
+ format: "markdown",
570
+ };
571
+ if (meta.externalSessionPath && fs.existsSync(meta.externalSessionPath)) {
572
+ const ext = fs.readFileSync(meta.externalSessionPath, "utf8");
573
+ result.external = {
574
+ path: meta.externalSessionPath,
575
+ raw: ext,
576
+ tail: ext.length > tailBytes ? ext.slice(-tailBytes) : ext,
577
+ size: ext.length,
578
+ format: "jsonl",
579
+ };
580
+ }
581
+ return result;
582
+ },
583
+ listProjects(opts) {
584
+ return readApxProjects(opts).map((p) => {
585
+ let count = 0;
586
+ let mtime = 0;
587
+ if (p.apxId) {
588
+ const agentsDir = path.join(apxStorageRoot(opts), p.apxId, "agents");
589
+ try {
590
+ for (const slug of fs.readdirSync(agentsDir)) {
591
+ const sdir = path.join(agentsDir, slug, "sessions");
592
+ try {
593
+ for (const f of fs.readdirSync(sdir)) {
594
+ if (!f.endsWith(".md")) continue;
595
+ count++;
596
+ const file = path.join(sdir, f);
597
+ const fm = parseFrontmatter(fs.readFileSync(file, "utf8"));
598
+ mtime = Math.max(mtime, apxSessionTimestamp(fm, file));
599
+ }
600
+ } catch {}
601
+ }
602
+ } catch {}
603
+ }
604
+ return { key: p.name, dir: p.path, label: p.path, count, mtime };
605
+ });
606
+ },
607
+ listSessions(dir, opts) {
608
+ let apxId = null;
609
+ try {
610
+ const pj = JSON.parse(
611
+ fs.readFileSync(path.join(dir, ".apc", "project.json"), "utf8")
612
+ );
613
+ apxId = pj.apx_id || null;
614
+ } catch {}
615
+ if (!apxId) return { found: false, location: dir };
616
+ const agentsDir = path.join(apxStorageRoot(opts), apxId, "agents");
617
+ if (!fs.existsSync(agentsDir)) return { found: false, location: agentsDir };
618
+ const sessions = [];
619
+ for (const slug of fs.readdirSync(agentsDir)) {
620
+ const sdir = path.join(agentsDir, slug, "sessions");
621
+ let files;
622
+ try {
623
+ files = fs.readdirSync(sdir);
624
+ } catch {
625
+ continue;
626
+ }
627
+ for (const f of files) {
628
+ if (!f.endsWith(".md")) continue;
629
+ const file = path.join(sdir, f);
630
+ const fm = parseFrontmatter(fs.readFileSync(file, "utf8"));
631
+ sessions.push({
632
+ id: fm.id || f.slice(0, -3),
633
+ mtime: apxSessionTimestamp(fm, file),
634
+ title: `[${slug}] ${fm.title || "(sin título)"}`,
635
+ path: file,
636
+ });
637
+ }
638
+ }
639
+ sessions.sort((a, b) => b.mtime - a.mtime);
640
+ return { found: sessions.length > 0, location: agentsDir, sessions };
641
+ },
642
+ continueHint() {
643
+ return `apx session list (run from the project directory)`;
644
+ },
645
+ resumeHint(id) {
646
+ return `apx session resume ${id}`;
647
+ },
648
+ };
649
+
650
+ // ── antigravity engine (detected, listing not implemented) ───────────────────
651
+
652
+ const antigravityEngine = {
653
+ id: "antigravity",
654
+ label: "Antigravity",
655
+ implemented: false,
656
+ detect(opts) {
657
+ const candidates = [
658
+ path.join(homeDir(opts), ".antigravity"),
659
+ path.join(
660
+ homeDir(opts),
661
+ "Library",
662
+ "Application Support",
663
+ "Antigravity"
664
+ ),
665
+ ];
666
+ const hit = candidates.find((c) => fs.existsSync(c));
667
+ return hit
668
+ ? { available: true }
669
+ : { available: false, reason: "Antigravity not installed" };
670
+ },
671
+ };
672
+
673
+ export const ENGINES = {
674
+ apx: apxEngine,
675
+ claude: claudeEngine,
676
+ codex: codexEngine,
677
+ antigravity: antigravityEngine,
678
+ };
679
+
680
+ // ── cross-engine helpers (used by `apx session resume <id>` etc.) ────────────
681
+
682
+ /**
683
+ * Search every implemented + detected engine for a session whose id matches.
684
+ * Returns an array of hits (0, 1, or more if the same id exists in multiple
685
+ * engines — callers should disambiguate via --engine).
686
+ */
687
+ export function findSessionAcrossEngines(id, opts = {}) {
688
+ const hits = [];
689
+ for (const engine of Object.values(ENGINES)) {
690
+ if (!engine.implemented || typeof engine.findSessionById !== "function") continue;
691
+ const detected = engine.detect(opts);
692
+ if (!detected.available) continue;
693
+ try {
694
+ const hit = engine.findSessionById(id, opts);
695
+ if (hit) hits.push(hit);
696
+ } catch {}
697
+ }
698
+ return hits;
699
+ }
700
+
701
+ /** Same as findSessionAcrossEngines but limited to one engine id. */
702
+ export function findSessionInEngine(engineId, id, opts = {}) {
703
+ const engine = ENGINES[engineId];
704
+ if (!engine) return null;
705
+ if (!engine.implemented || typeof engine.findSessionById !== "function") return null;
706
+ const detected = engine.detect(opts);
707
+ if (!detected.available) return null;
708
+ return engine.findSessionById(id, opts);
709
+ }
710
+
711
+ /**
712
+ * Enumerate every session across every detected+implemented engine, returning
713
+ * flat rows of { engine, id, title, mtime, cwd, path }. Used by `apx session
714
+ * find`. When `dir` is given, only that working directory is scanned (cheap);
715
+ * otherwise every project the engine knows about is walked.
716
+ *
717
+ * Caveat: an engine can only enumerate a project when it can resolve its cwd.
718
+ * Codex always records cwd; APX uses registered projects; Claude can only list
719
+ * folders that map back to a registered APX project (its folder names are a
720
+ * lossy encoding of the original path). Scope with --dir to reach the rest.
721
+ */
722
+ export function collectAllSessions(opts = {}, { dir = null, engineId = null } = {}) {
723
+ const out = [];
724
+ for (const engine of Object.values(ENGINES)) {
725
+ if (engineId && engine.id !== engineId) continue;
726
+ if (!engine.implemented || typeof engine.listSessions !== "function") continue;
727
+ if (!engine.detect(opts).available) continue;
728
+
729
+ const dirs = [];
730
+ if (dir) {
731
+ dirs.push(dir);
732
+ } else {
733
+ let projects = [];
734
+ try {
735
+ projects = engine.listProjects(opts) || [];
736
+ } catch {}
737
+ for (const p of projects) if (p.dir) dirs.push(p.dir);
738
+ }
739
+
740
+ for (const d of dirs) {
741
+ let res;
742
+ try {
743
+ res = engine.listSessions(d, opts);
744
+ } catch {
745
+ continue;
746
+ }
747
+ if (!res || !res.found) continue;
748
+ for (const s of res.sessions || []) {
749
+ out.push({
750
+ engine: engine.id,
751
+ id: s.id,
752
+ title: s.title || "",
753
+ mtime: s.mtime || 0,
754
+ cwd: d,
755
+ path: s.path || null,
756
+ });
757
+ }
758
+ }
759
+ }
760
+ return out;
761
+ }
762
+
763
+ // Read a session file off disk for content (deep) search. Cheap: we already
764
+ // have the absolute path from collectAllSessions, so no per-candidate rescan.
765
+ function sessionContainsText(row, needle) {
766
+ if (!row.path) return false;
767
+ let text;
768
+ try {
769
+ text = fs.readFileSync(row.path, "utf8");
770
+ } catch {
771
+ return false;
772
+ }
773
+ return text.toLowerCase().includes(needle);
774
+ }
775
+
776
+ export function cmdSessionFind(args, opts = {}) {
777
+ const query = (args._ || []).join(" ").trim();
778
+ if (!query) {
779
+ throw new Error(
780
+ 'apx session find: missing search text — e.g. apx session find "mejorar interfaz web"'
781
+ );
782
+ }
783
+ const needle = query.toLowerCase();
784
+ const deep = !!(args.flags.deep || args.flags.content);
785
+ const asJson = !!args.flags.json;
786
+ const engineFlag =
787
+ args.flags.engine && args.flags.engine !== true
788
+ ? String(args.flags.engine)
789
+ : null;
790
+ if (engineFlag && !ENGINES[engineFlag]) {
791
+ throw new Error(
792
+ `unknown engine "${engineFlag}" — valid engines: ${Object.keys(ENGINES).join(", ")}`
793
+ );
794
+ }
795
+ const limitFlag = args.flags.limit;
796
+ const limit =
797
+ limitFlag && limitFlag !== true ? parseInt(limitFlag, 10) : 20;
798
+
799
+ const dir = resolveTargetDir(args, opts);
800
+ const rows = collectAllSessions(opts, { dir, engineId: engineFlag });
801
+
802
+ const seen = new Set();
803
+ const matches = [];
804
+ for (const row of rows) {
805
+ const titleHit = String(row.title).toLowerCase().includes(needle);
806
+ let where = titleHit ? "title" : null;
807
+ if (!titleHit && deep && sessionContainsText(row, needle)) where = "content";
808
+ if (!where) continue;
809
+ const key = `${row.engine}:${row.id}`;
810
+ if (seen.has(key)) continue;
811
+ seen.add(key);
812
+ matches.push({ ...row, match: where });
813
+ }
814
+ matches.sort((a, b) => b.mtime - a.mtime);
815
+ const shown = matches.slice(0, limit);
816
+
817
+ if (asJson) {
818
+ console.log(JSON.stringify(shown, null, 2));
819
+ return;
820
+ }
821
+
822
+ if (matches.length === 0) {
823
+ console.log(`No sessions matching "${query}"${deep ? " (title + content)" : " (title)"}.`);
824
+ if (!deep) console.log("Tip: add --deep to search inside transcripts too.");
825
+ if (!dir) console.log("Tip: scope with --dir <path> or --project <name> to reach unregistered Claude projects.");
826
+ return;
827
+ }
828
+
829
+ console.log(
830
+ `${matches.length} match${matches.length === 1 ? "" : "es"} for "${query}"` +
831
+ (deep ? " (title + content)" : " (title)") +
832
+ (shown.length < matches.length ? ` — showing ${shown.length}` : "")
833
+ );
834
+ console.log("");
835
+ console.log(
836
+ `${"DATE".padEnd(12)} ${"ENGINE".padEnd(8)} ${"SESSION ID".padEnd(38)} TITLE`
837
+ );
838
+ console.log(
839
+ `${"─".repeat(12)} ${"─".repeat(8)} ${"─".repeat(38)} ${"─".repeat(30)}`
840
+ );
841
+ for (const m of shown) {
842
+ console.log(
843
+ `${fmtDate(m.mtime).padEnd(12)} ${String(m.engine).padEnd(8)} ${String(m.id).padEnd(38)} ${String(m.title).slice(0, 60)}`
844
+ );
845
+ }
846
+ console.log("");
847
+ console.log("Next:");
848
+ const top = shown[0];
849
+ console.log(` apx session summary ${top.id}`);
850
+ console.log(` apx session ask ${top.id} "your question"`);
851
+ console.log(` apx session resume ${top.id} --continue`);
852
+ }
853
+
854
+ // ── command ──────────────────────────────────────────────────────────────────
855
+
856
+ function printSessions(engine, dir, result, limit) {
857
+ if (!result.found) {
858
+ console.log(`(no ${engine.label} sessions for ${dir})`);
859
+ if (result.location) console.log(` looked in: ${result.location}`);
860
+ return;
861
+ }
862
+ let sessions = result.sessions;
863
+ if (limit && limit > 0) sessions = sessions.slice(0, limit);
864
+
865
+ console.log(`${engine.label} sessions for ${dir}`);
866
+ console.log(` ${result.location}`);
867
+ console.log("");
868
+ console.log(`${"DATE".padEnd(12)} ${"SESSION ID".padEnd(38)} TITLE`);
869
+ console.log(`${"─".repeat(12)} ${"─".repeat(38)} ${"─".repeat(40)}`);
870
+ for (const s of sessions) {
871
+ console.log(
872
+ `${fmtDate(s.mtime).padEnd(12)} ${String(s.id).padEnd(38)} ${String(
873
+ s.title
874
+ ).slice(0, 70)}`
875
+ );
876
+ }
877
+ console.log("");
878
+ console.log("Resume:");
879
+ if (engine.continueHint) console.log(` latest: ${engine.continueHint(dir)}`);
880
+ if (engine.resumeHint && sessions[0]) {
881
+ console.log(` specific: ${engine.resumeHint(sessions[0].id)}`);
882
+ }
883
+ }
884
+
885
+ function printProjects(engine, projects) {
886
+ if (projects.length === 0) {
887
+ console.log(`(no ${engine.label} projects found)`);
888
+ return;
889
+ }
890
+ console.log(`${engine.label} projects:`);
891
+ console.log("");
892
+ console.log(`${"SESSIONS".padEnd(9)} ${"LAST".padEnd(12)} PROJECT`);
893
+ console.log(`${"─".repeat(9)} ${"─".repeat(12)} ${"─".repeat(40)}`);
894
+ for (const p of projects) {
895
+ console.log(
896
+ `${String(p.count).padEnd(9)} ${fmtDate(p.mtime).padEnd(12)} ${p.label}`
897
+ );
898
+ }
899
+ console.log("");
900
+ console.log(
901
+ `Re-run with --project <name> or --dir <path> to list sessions of one project.`
902
+ );
903
+ }
904
+
905
+ // Run the single-engine list flow. Returns true if anything printed.
906
+ function listSingleEngine(engine, args, opts, { headerPrefix = "" } = {}) {
907
+ const detected = engine.detect(opts);
908
+ if (!detected.available) {
909
+ // Caller filters by detect() already in "all engines" mode; this path is
910
+ // hit only when --engine names something the user explicitly asked for.
911
+ console.log(`${headerPrefix}engine "${engine.id}" not available: ${detected.reason}`);
912
+ return false;
913
+ }
914
+ if (!engine.implemented) {
915
+ console.log(
916
+ `${headerPrefix}engine "${engine.id}" (${engine.label}) detected but listing not implemented yet.`
917
+ );
918
+ return false;
919
+ }
920
+
921
+ const dir = resolveTargetDir(args, opts);
922
+ const limitFlag = args.flags.limit || args.flags.last;
923
+ const limit = limitFlag && limitFlag !== true ? parseInt(limitFlag, 10) : null;
924
+
925
+ if (dir) {
926
+ printSessions(engine, dir, engine.listSessions(dir, opts), limit);
927
+ } else {
928
+ printProjects(engine, engine.listProjects(opts));
929
+ }
930
+ return true;
931
+ }
932
+
933
+ export function cmdSessionsList(args, opts = {}) {
934
+ const engineFlag = args.flags.engine;
935
+ if (engineFlag === true) {
936
+ throw new Error("--engine requires a value (apx, claude, codex, antigravity)");
937
+ }
938
+
939
+ // Explicit engine → behave exactly as before (single-engine view).
940
+ if (engineFlag) {
941
+ const engineId = String(engineFlag);
942
+ const engine = ENGINES[engineId];
943
+ if (!engine) {
944
+ throw new Error(
945
+ `unknown engine "${engineId}" — valid engines: ${Object.keys(ENGINES).join(", ")}`
946
+ );
947
+ }
948
+ listSingleEngine(engine, args, opts);
949
+ return;
950
+ }
951
+
952
+ // No --engine → iterate every engine present on the system. Detected-but-
953
+ // empty engines still get a heading with "(sin nada)" so the user sees what
954
+ // exists; engines not installed are silently skipped (no clutter).
955
+ let anyDetected = false;
956
+ let first = true;
957
+ for (const engine of Object.values(ENGINES)) {
958
+ const detected = engine.detect(opts);
959
+ if (!detected.available) continue;
960
+ anyDetected = true;
961
+ if (!first) console.log("");
962
+ first = false;
963
+ console.log(`══ ${engine.label} (${engine.id}) ══`);
964
+ if (!engine.implemented) {
965
+ console.log(" (detected — listing no soportado todavía)");
966
+ continue;
967
+ }
968
+ const dir = resolveTargetDir(args, opts);
969
+ const limitFlag = args.flags.limit || args.flags.last;
970
+ const limit =
971
+ limitFlag && limitFlag !== true ? parseInt(limitFlag, 10) : null;
972
+ if (dir) {
973
+ const result = engine.listSessions(dir, opts);
974
+ if (!result.found || (result.sessions || []).length === 0) {
975
+ console.log(" (sin nada)");
976
+ if (result.location) console.log(` looked in: ${result.location}`);
977
+ } else {
978
+ printSessions(engine, dir, result, limit);
979
+ }
980
+ } else {
981
+ const list = engine.listProjects(opts);
982
+ if (list.length === 0) {
983
+ console.log(" (sin nada)");
984
+ } else {
985
+ printProjects(engine, list);
986
+ }
987
+ }
988
+ }
989
+ if (!anyDetected) {
990
+ console.log("(no engines detected — install claude, codex, or run `apx init` somewhere)");
991
+ } else {
992
+ console.log("");
993
+ console.log(
994
+ "Tip: --engine <id> filters to one engine; --project <name> or --dir <path> drills into a project."
995
+ );
996
+ }
997
+ }