@agentprojectcontext/apx 1.81.0 → 1.89.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (838) hide show
  1. package/package.json +9 -8
  2. package/skills/apc-context/SKILL.md +14 -7
  3. package/skills/apx/SKILL.md +62 -2
  4. package/skills/apx-mcp/SKILL.md +42 -15
  5. package/src/core/agent/a2a/peers.js +161 -0
  6. package/src/core/agent/a2a/reply.js +379 -27
  7. package/src/core/agent/abort.js +25 -0
  8. package/src/core/agent/agent-model.js +58 -0
  9. package/src/core/agent/agent-tools.js +101 -0
  10. package/src/core/agent/author-line.js +110 -0
  11. package/src/core/agent/build-agent-system.js +52 -18
  12. package/src/core/agent/channels/voice-context.js +17 -2
  13. package/src/core/agent/closing-floor.js +117 -0
  14. package/src/core/agent/constants.js +119 -11
  15. package/src/core/agent/engine-call.js +56 -0
  16. package/src/core/agent/group/run-group-turn.js +218 -0
  17. package/src/core/agent/group/turn-resolver.js +165 -0
  18. package/src/core/agent/judge.js +138 -11
  19. package/src/core/agent/loop/side-effects.js +106 -3
  20. package/src/core/agent/memory.js +31 -18
  21. package/src/core/agent/model-capabilities.js +47 -0
  22. package/src/core/agent/model-router.js +11 -40
  23. package/src/core/agent/prompt-builder.js +47 -0
  24. package/src/core/agent/prompts/channels/a2a.md +12 -0
  25. package/src/core/agent/prompts/channels/code.md +3 -1
  26. package/src/core/agent/prompts/channels/telegram.md +2 -0
  27. package/src/core/agent/prompts/channels/web_code.md +1 -1
  28. package/src/core/agent/prompts/channels/whatsapp.md +37 -0
  29. package/src/core/agent/prompts/core/agent-base.md +2 -0
  30. package/src/core/agent/prompts/discipline/action.md +1 -0
  31. package/src/core/agent/prompts/discipline/two-segment.md +2 -1
  32. package/src/core/agent/prompts/modes/mobility.md +36 -0
  33. package/src/core/agent/retry.js +42 -0
  34. package/src/core/agent/run-agent.js +322 -25
  35. package/src/core/agent/run-turn.js +253 -0
  36. package/src/core/agent/self-memory.js +18 -52
  37. package/src/core/agent/skills/agent-skills.js +118 -0
  38. package/src/core/agent/skills/catalog.js +1 -1
  39. package/src/core/agent/skills/declared.js +13 -0
  40. package/src/core/agent/skills/index-store.js +8 -1
  41. package/src/core/agent/skills/inspector.js +20 -3
  42. package/src/core/agent/skills/loader.js +18 -3
  43. package/src/core/agent/skills/media.js +121 -0
  44. package/src/core/agent/skills/origin.js +61 -0
  45. package/src/core/agent/skills/sections.js +136 -0
  46. package/src/core/agent/super-agent.js +54 -14
  47. package/src/core/agent/tools/handlers/_calendar.js +50 -0
  48. package/src/core/agent/tools/handlers/add-mcp.js +103 -0
  49. package/src/core/agent/tools/handlers/asana-create-task.js +3 -1
  50. package/src/core/agent/tools/handlers/attach-media.js +56 -0
  51. package/src/core/agent/tools/handlers/calendar-create-event.js +38 -0
  52. package/src/core/agent/tools/handlers/calendar-find-slot.js +39 -0
  53. package/src/core/agent/tools/handlers/calendar-list-events.js +39 -0
  54. package/src/core/agent/tools/handlers/calendar-update-event.js +35 -0
  55. package/src/core/agent/tools/handlers/call-agent.js +14 -6
  56. package/src/core/agent/tools/handlers/call-runtime.js +27 -49
  57. package/src/core/agent/tools/handlers/comment-task.js +78 -0
  58. package/src/core/agent/tools/handlers/complete-task.js +60 -0
  59. package/src/core/agent/tools/handlers/configure-agent.js +70 -0
  60. package/src/core/agent/tools/handlers/create-agent.js +68 -0
  61. package/src/core/agent/tools/handlers/create-task.js +41 -3
  62. package/src/core/agent/tools/handlers/import-agent.js +5 -5
  63. package/src/core/agent/tools/handlers/list-mcp-tools.js +83 -0
  64. package/src/core/agent/tools/handlers/list-routines.js +46 -0
  65. package/src/core/agent/tools/handlers/list-tasks.js +8 -1
  66. package/src/core/agent/tools/handlers/mark-commitment.js +57 -0
  67. package/src/core/agent/tools/handlers/read-skill.js +64 -0
  68. package/src/core/agent/tools/handlers/remember-routine.js +2 -8
  69. package/src/core/agent/tools/handlers/remember.js +82 -6
  70. package/src/core/agent/tools/handlers/remove-agent.js +42 -0
  71. package/src/core/agent/tools/handlers/run-routine.js +94 -0
  72. package/src/core/agent/tools/handlers/run-shell.js +44 -2
  73. package/src/core/agent/tools/handlers/send-telegram.js +41 -19
  74. package/src/core/agent/tools/handlers/set-agent-prompt.js +44 -0
  75. package/src/core/agent/tools/handlers/view-media.js +69 -0
  76. package/src/core/agent/tools/handlers/write-agent-memory.js +52 -0
  77. package/src/core/agent/tools/helpers.js +36 -4
  78. package/src/core/agent/tools/names.js +64 -0
  79. package/src/core/agent/tools/registry-bridge.js +24 -1
  80. package/src/core/agent/tools/registry.js +79 -0
  81. package/src/core/agent/tools/tool-call-parser.js +136 -13
  82. package/src/core/agent/vision-bridge.js +69 -0
  83. package/src/core/apc/agent-identity.js +74 -0
  84. package/src/core/apc/agent-rename-refs.js +187 -0
  85. package/src/core/apc/agent-write.js +312 -0
  86. package/src/core/apc/agents-vault.js +1 -1
  87. package/src/core/apc/blob-keys.js +42 -0
  88. package/src/core/apc/frontmatter.js +166 -10
  89. package/src/core/apc/parser.js +33 -83
  90. package/src/core/apc/paths.js +4 -6
  91. package/src/core/apc/project-memory.js +44 -0
  92. package/src/core/apc/projects-helpers.js +33 -0
  93. package/src/core/apc/scaffold.js +36 -16
  94. package/src/core/channels/telegram/ask-callbacks.js +103 -0
  95. package/src/core/channels/telegram/dispatch.js +154 -30
  96. package/src/core/channels/telegram/helpers.js +59 -7
  97. package/src/core/channels/telegram/inbound/audio.js +26 -30
  98. package/src/core/channels/telegram/inbound/file.js +22 -32
  99. package/src/core/channels/telegram/inbound/photo.js +24 -28
  100. package/src/core/channels/telegram/progress-gate.js +76 -0
  101. package/src/core/channels/telegram/reply.js +151 -43
  102. package/src/core/channels/telegram/voice-note.js +150 -0
  103. package/src/core/config/index.js +53 -54
  104. package/src/core/config/paths.js +117 -31
  105. package/src/core/config/redact.js +89 -4
  106. package/src/core/config/secret-values.js +2 -4
  107. package/src/core/constants/actors.js +5 -0
  108. package/src/core/constants/channels.js +3 -1
  109. package/src/core/constants/task-categories.js +73 -0
  110. package/src/core/constants/task-fields.js +28 -0
  111. package/src/core/engines/_globs.js +33 -0
  112. package/src/core/engines/anthropic.js +19 -1
  113. package/src/core/engines/catalog.js +20 -0
  114. package/src/core/engines/gemini.js +84 -16
  115. package/src/core/engines/index.js +19 -3
  116. package/src/core/engines/mock.js +145 -1
  117. package/src/core/engines/openai-compatible.js +150 -15
  118. package/src/core/engines/presets.js +36 -9
  119. package/src/core/engines/zen.js +131 -0
  120. package/src/core/events/bus.js +140 -0
  121. package/src/core/events/mascot-notify.js +156 -0
  122. package/src/core/http-tools/browser.js +366 -36
  123. package/src/core/http-tools/catalog.js +206 -22
  124. package/src/core/http-tools/grep.js +62 -7
  125. package/src/core/http-tools/registry.js +3 -1
  126. package/src/core/i18n/en.js +34 -3
  127. package/src/core/i18n/es.js +36 -4
  128. package/src/core/i18n/index.js +5 -5
  129. package/src/core/i18n/pt.js +32 -3
  130. package/src/core/identity/self.js +14 -1
  131. package/src/core/images/engines/a1111.js +219 -0
  132. package/src/core/images/engines/index.js +187 -0
  133. package/src/core/images/engines/mock.js +74 -0
  134. package/src/core/images/engines/openai.js +130 -0
  135. package/src/core/images/engines/sdcpp.js +204 -0
  136. package/src/core/images/engines/shared.js +218 -0
  137. package/src/core/images/generate.js +260 -0
  138. package/src/core/integrations/catalog.js +8 -3
  139. package/src/core/integrations/plugins/_google-oauth.js +179 -0
  140. package/src/core/integrations/plugins/asana.js +7 -3
  141. package/src/core/integrations/plugins/calendar.js +404 -0
  142. package/src/core/integrations/store.js +2 -0
  143. package/src/core/memory/broker.js +16 -1
  144. package/src/core/memory/compactor.js +19 -3
  145. package/src/core/memory/consolidate.js +2 -2
  146. package/src/core/memory/dated-log.js +66 -0
  147. package/src/core/memory/embed-engines/custom.js +59 -0
  148. package/src/core/memory/embed-engines/gemini.js +9 -3
  149. package/src/core/memory/embed-engines/index.js +87 -15
  150. package/src/core/memory/embeddings.js +52 -24
  151. package/src/core/memory/index.js +13 -3
  152. package/src/core/memory/indexer.js +83 -27
  153. package/src/core/memory/prune.js +182 -0
  154. package/src/core/memory/store.js +22 -0
  155. package/src/core/memory/summarizer.js +72 -8
  156. package/src/core/mobility/answer.js +80 -0
  157. package/src/core/mobility/geofence.js +667 -0
  158. package/src/core/mobility/osm-route.js +282 -0
  159. package/src/core/mobility/preferences.js +91 -0
  160. package/src/core/mobility/state.js +245 -0
  161. package/src/core/mobility/trip-event.js +384 -0
  162. package/src/core/net/tailscale.js +168 -0
  163. package/src/core/profiles/bundled/secretary/PROFILE.md +32 -42
  164. package/src/core/profiles/bundled/secretary/config.schema.es.json +68 -0
  165. package/src/core/profiles/bundled/secretary/config.schema.json +30 -2
  166. package/src/core/profiles/bundled/secretary/profile.json +3 -1
  167. package/src/core/profiles/bundled/secretary/routines/a2a-sweep.json +20 -0
  168. package/src/core/profiles/bundled/secretary/routines/day-close.json +4 -1
  169. package/src/core/profiles/bundled/secretary/routines/day-open.json +7 -1
  170. package/src/core/profiles/bundled/secretary/routines/watch.json +13 -2
  171. package/src/core/profiles/lifecycle.js +243 -19
  172. package/src/core/profiles/paths.js +12 -0
  173. package/src/core/profiles/store.js +47 -0
  174. package/src/core/routines/active-runs.js +213 -0
  175. package/src/core/routines/delivery.js +612 -0
  176. package/src/core/routines/header.js +88 -0
  177. package/src/core/routines/index.js +26 -0
  178. package/src/core/routines/run-log.js +78 -0
  179. package/src/core/routines/runner.js +629 -66
  180. package/src/core/routines/signals.js +75 -0
  181. package/src/core/runtime-skills/apc-context/SKILL.md +14 -7
  182. package/src/core/runtime-skills/apx/SKILL.md +93 -1
  183. package/src/core/runtime-skills/apx-agency-agents/SKILL.md +2 -2
  184. package/src/core/runtime-skills/apx-agent/SKILL.md +134 -19
  185. package/src/core/runtime-skills/apx-commitment/SKILL.md +21 -11
  186. package/src/core/runtime-skills/apx-image/SKILL.md +60 -0
  187. package/src/core/runtime-skills/apx-integrations/SKILL.md +82 -0
  188. package/src/core/runtime-skills/apx-mcp/SKILL.md +45 -14
  189. package/src/core/runtime-skills/apx-mcp-builder/SKILL.md +4 -4
  190. package/src/core/runtime-skills/apx-profile/SKILL.md +27 -2
  191. package/src/core/runtime-skills/apx-project/SKILL.md +23 -2
  192. package/src/core/runtime-skills/apx-routine/SKILL.md +40 -17
  193. package/src/core/runtime-skills/apx-runtime/SKILL.md +124 -14
  194. package/src/core/runtime-skills/apx-sessions/SKILL.md +7 -6
  195. package/src/core/runtime-skills/apx-skill-builder/SKILL.md +15 -13
  196. package/src/core/runtime-skills/apx-task/SKILL.md +79 -26
  197. package/src/core/runtime-skills/apx-telegram/SKILL.md +12 -12
  198. package/src/core/runtime-skills/apx-transcribe/SKILL.md +56 -0
  199. package/src/core/runtime-skills/apx-voice/SKILL.md +27 -8
  200. package/src/core/runtime-skills/claude-code/SKILL.md +8 -0
  201. package/src/core/runtime-skills/openrouter/SKILL.md +8 -2
  202. package/src/core/runtimes/_spawn.js +9 -1
  203. package/src/core/runtimes/claude-code.js +11 -2
  204. package/src/core/runtimes/codex.js +44 -10
  205. package/src/core/runtimes/index.js +17 -2
  206. package/src/core/runtimes/opencode.js +88 -9
  207. package/src/core/runtimes/outcome.js +119 -0
  208. package/src/core/sessions/index.js +193 -1
  209. package/src/core/stores/agent-inbox.js +109 -23
  210. package/src/core/stores/code-sessions.js +21 -0
  211. package/src/core/stores/commitments.js +27 -3
  212. package/src/core/stores/conversations.js +220 -20
  213. package/src/core/stores/deliveries.js +177 -0
  214. package/src/core/stores/media-archive.js +228 -0
  215. package/src/core/stores/messages.js +1096 -112
  216. package/src/core/stores/organization.js +34 -0
  217. package/src/core/stores/project-memory.js +71 -0
  218. package/src/core/stores/routine-memory.js +16 -8
  219. package/src/core/stores/routines.js +27 -49
  220. package/src/core/stores/sessions.js +4 -8
  221. package/src/core/stores/tasks.js +212 -18
  222. package/src/core/stores/turn-record.js +209 -0
  223. package/src/core/tasks/columns.js +136 -0
  224. package/src/core/tasks/comment-turn.js +258 -0
  225. package/src/core/util/time.js +13 -0
  226. package/src/core/voice/engines/index.js +54 -1
  227. package/src/core/voice/engines/openai.js +50 -4
  228. package/src/core/voice/opus.js +67 -0
  229. package/src/core/voice/pronounceable.js +43 -0
  230. package/src/core/voice/transcription.js +4 -0
  231. package/src/core/voice/tts.js +114 -24
  232. package/src/host/daemon/active-turns.js +188 -0
  233. package/src/host/daemon/api/admin-config.js +9 -0
  234. package/src/host/daemon/api/agents.js +99 -90
  235. package/src/host/daemon/api/artifact-preview.js +7 -6
  236. package/src/host/daemon/api/artifacts.js +3 -2
  237. package/src/host/daemon/api/code.js +55 -9
  238. package/src/host/daemon/api/commitments.js +11 -0
  239. package/src/host/daemon/api/confirm.js +3 -2
  240. package/src/host/daemon/api/conversations.js +543 -35
  241. package/src/host/daemon/api/deck.js +9 -8
  242. package/src/host/daemon/api/deliveries.js +33 -0
  243. package/src/host/daemon/api/desktop.js +5 -4
  244. package/src/host/daemon/api/embeddings.js +15 -6
  245. package/src/host/daemon/api/engines.js +59 -8
  246. package/src/host/daemon/api/exec.js +437 -121
  247. package/src/host/daemon/api/groups.js +215 -0
  248. package/src/host/daemon/api/images.js +107 -0
  249. package/src/host/daemon/api/inbox.js +123 -2
  250. package/src/host/daemon/api/integrations.js +64 -2
  251. package/src/host/daemon/api/mcps.js +7 -6
  252. package/src/host/daemon/api/media.js +283 -0
  253. package/src/host/daemon/api/mobility.js +177 -0
  254. package/src/host/daemon/api/net.js +182 -0
  255. package/src/host/daemon/api/pairing.js +38 -5
  256. package/src/host/daemon/api/profiles.js +30 -2
  257. package/src/host/daemon/api/routines.js +36 -4
  258. package/src/host/daemon/api/runtimes.js +74 -39
  259. package/src/host/daemon/api/sessions-search.js +7 -2
  260. package/src/host/daemon/api/sessions.js +44 -2
  261. package/src/host/daemon/api/shared.js +127 -20
  262. package/src/host/daemon/api/skills.js +11 -4
  263. package/src/host/daemon/api/super-agent.js +384 -53
  264. package/src/host/daemon/api/tasks.js +180 -10
  265. package/src/host/daemon/api/telegram.js +11 -10
  266. package/src/host/daemon/api/thread-faces.js +159 -0
  267. package/src/host/daemon/api/top-level.js +3 -3
  268. package/src/host/daemon/api/transcribe.js +11 -10
  269. package/src/host/daemon/api/tts.js +97 -4
  270. package/src/host/daemon/api/turn-abort.js +23 -0
  271. package/src/host/daemon/api/turns.js +49 -0
  272. package/src/host/daemon/api/voice.js +5 -4
  273. package/src/host/daemon/api/web.js +98 -0
  274. package/src/host/daemon/api.js +39 -0
  275. package/src/host/daemon/delivery-sweep.js +58 -0
  276. package/src/host/daemon/desktop-ws.js +5 -23
  277. package/src/host/daemon/events-ws.js +273 -0
  278. package/src/host/daemon/index.js +59 -15
  279. package/src/host/daemon/plugins/desktop/index.js +17 -4
  280. package/src/host/daemon/plugins/telegram/index.js +78 -40
  281. package/src/host/daemon/pty-bridge.py +99 -0
  282. package/src/host/daemon/routines-scheduler.js +1 -0
  283. package/src/host/daemon/smoke.js +1 -2
  284. package/src/host/daemon/terminal-ws.js +132 -0
  285. package/src/host/daemon/tts-keepwarm.js +87 -0
  286. package/src/host/daemon/wakeup.js +11 -6
  287. package/src/host/daemon/whisper-server.js +44 -0
  288. package/src/host/daemon/whisper-server.py +70 -13
  289. package/src/host/daemon/ws-auth.js +28 -0
  290. package/src/interfaces/android/app/build.gradle +42 -0
  291. package/src/interfaces/android/app/proguard-rules.pro +4 -0
  292. package/src/interfaces/android/app/src/main/AndroidManifest.xml +139 -0
  293. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/AlertScreen.java +139 -0
  294. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/AndroidAutoDetector.java +106 -0
  295. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ApxCarAppService.java +57 -0
  296. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ApxPreferences.java +165 -0
  297. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarAlertStore.java +84 -0
  298. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarMessageActionReceiver.java +47 -0
  299. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarMessageNotification.java +152 -0
  300. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DaemonAddress.java +35 -0
  301. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DaemonClient.java +339 -0
  302. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DeviceLocation.java +38 -0
  303. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ErrandScreen.java +127 -0
  304. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MainActivity.java +872 -0
  305. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsNavigationDetector.java +63 -0
  306. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsNavigationListenerService.java +453 -0
  307. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsShareIntentParser.java +93 -0
  308. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotBlobCatalog.java +66 -0
  309. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotOverlayService.java +448 -0
  310. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotView.java +249 -0
  311. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MessageFrameParser.java +240 -0
  312. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/NotifyChannels.java +69 -0
  313. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ProximityActionReceiver.java +78 -0
  314. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ProximityNotification.java +161 -0
  315. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/StartupReceiver.java +57 -0
  316. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TravelEventGate.java +62 -0
  317. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TravelStatusBanner.java +116 -0
  318. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripLocationService.java +272 -0
  319. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripPlacesSheet.java +203 -0
  320. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripScreen.java +182 -0
  321. package/src/interfaces/android/app/src/main/res/drawable/app_background.xml +12 -0
  322. package/src/interfaces/android/app/src/main/res/drawable/ic_apx_app.xml +10 -0
  323. package/src/interfaces/android/app/src/main/res/drawable/ic_apx_launcher_foreground.xml +12 -0
  324. package/src/interfaces/android/app/src/main/res/drawable/ic_apx_notification.xml +22 -0
  325. package/src/interfaces/android/app/src/main/res/drawable/ic_trip_car.xml +37 -0
  326. package/src/interfaces/android/app/src/main/res/drawable-nodpi/apx_logo.png +0 -0
  327. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_amatista.png +0 -0
  328. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_aqua.png +0 -0
  329. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_brasa.png +0 -0
  330. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_campana.png +0 -0
  331. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_caracol.png +0 -0
  332. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_carbon.png +0 -0
  333. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cobalto.png +0 -0
  334. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cometa.png +0 -0
  335. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_coral.png +0 -0
  336. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cubi.png +0 -0
  337. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_eclipse.png +0 -0
  338. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_faro.png +0 -0
  339. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_gajo.png +0 -0
  340. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_iris.png +0 -0
  341. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_kiwi.png +0 -0
  342. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_laguna.png +0 -0
  343. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_lila.png +0 -0
  344. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_menta.png +0 -0
  345. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_nimbo.png +0 -0
  346. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_noche.png +0 -0
  347. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_onyx.png +0 -0
  348. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_orbita.png +0 -0
  349. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_ovni.png +0 -0
  350. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_papa.png +0 -0
  351. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_parche.png +0 -0
  352. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_peon.png +0 -0
  353. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_perla.png +0 -0
  354. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_pino.png +0 -0
  355. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_quad.png +0 -0
  356. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_rubi.png +0 -0
  357. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_saturno.png +0 -0
  358. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_trebol.png +0 -0
  359. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_trino.png +0 -0
  360. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_volcan.png +0 -0
  361. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_zafiro.png +0 -0
  362. package/src/interfaces/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
  363. package/src/interfaces/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
  364. package/src/interfaces/android/app/src/main/res/raw/apx_notification.mp3 +0 -0
  365. package/src/interfaces/android/app/src/main/res/values/colors.xml +4 -0
  366. package/src/interfaces/android/app/src/main/res/values/strings.xml +25 -0
  367. package/src/interfaces/android/app/src/main/res/values/styles.xml +10 -0
  368. package/src/interfaces/android/app/src/main/res/values-v31/styles.xml +14 -0
  369. package/src/interfaces/android/app/src/main/res/xml/automotive_app_desc.xml +9 -0
  370. package/src/interfaces/android/app/src/main/res/xml/network_security_config.xml +10 -0
  371. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/AndroidAutoDetectorTest.java +85 -0
  372. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/CarAlertStoreTest.java +104 -0
  373. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/DaemonAddressTest.java +23 -0
  374. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MapsNavigationDetectorTest.java +69 -0
  375. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MapsShareIntentParserTest.java +31 -0
  376. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MessageFrameParserTest.java +180 -0
  377. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/TravelEventGateTest.java +64 -0
  378. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/TripPlacesSheetTest.java +66 -0
  379. package/src/interfaces/android/build.gradle +3 -0
  380. package/src/interfaces/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  381. package/src/interfaces/android/gradle/wrapper/gradle-wrapper.properties +9 -0
  382. package/src/interfaces/android/gradle.properties +3 -0
  383. package/src/interfaces/android/gradlew +248 -0
  384. package/src/interfaces/android/gradlew.bat +82 -0
  385. package/src/interfaces/android/settings.gradle +18 -0
  386. package/src/interfaces/cli/commands/a2a.js +145 -4
  387. package/src/interfaces/cli/commands/agent.js +247 -22
  388. package/src/interfaces/cli/commands/code.js +1 -1
  389. package/src/interfaces/cli/commands/commitment.js +5 -0
  390. package/src/interfaces/cli/commands/config.js +85 -6
  391. package/src/interfaces/cli/commands/exec.js +90 -1
  392. package/src/interfaces/cli/commands/image.js +314 -0
  393. package/src/interfaces/cli/commands/mcp.js +87 -23
  394. package/src/interfaces/cli/commands/memory.js +35 -22
  395. package/src/interfaces/cli/commands/panel.js +94 -0
  396. package/src/interfaces/cli/commands/profile.js +14 -0
  397. package/src/interfaces/cli/commands/project.js +29 -0
  398. package/src/interfaces/cli/commands/routine.js +45 -10
  399. package/src/interfaces/cli/commands/runtime.js +30 -7
  400. package/src/interfaces/cli/commands/session.js +90 -38
  401. package/src/interfaces/cli/commands/sessions.js +35 -2
  402. package/src/interfaces/cli/commands/skills.js +15 -9
  403. package/src/interfaces/cli/commands/status.js +2 -3
  404. package/src/interfaces/cli/commands/task.js +54 -5
  405. package/src/interfaces/cli/commands/telegram.js +12 -4
  406. package/src/interfaces/cli/commands/transcribe.js +177 -0
  407. package/src/interfaces/cli/help/index.js +311 -72
  408. package/src/interfaces/cli/http.js +61 -13
  409. package/src/interfaces/cli/index.js +1 -1
  410. package/src/interfaces/cli/routes/agent.js +5 -4
  411. package/src/interfaces/cli/routes/commitment.js +3 -2
  412. package/src/interfaces/cli/routes/config.js +7 -2
  413. package/src/interfaces/cli/routes/image.js +11 -0
  414. package/src/interfaces/cli/routes/index.js +2 -0
  415. package/src/interfaces/cli/routes/log.js +1 -1
  416. package/src/interfaces/cli/routes/memory.js +3 -2
  417. package/src/interfaces/cli/routes/panel.js +15 -2
  418. package/src/interfaces/cli/routes/profile.js +3 -2
  419. package/src/interfaces/cli/routes/transcribe.js +10 -0
  420. package/src/interfaces/cli/stdin.js +29 -0
  421. package/src/interfaces/desktop/assets/blobs/amatista.png +0 -0
  422. package/src/interfaces/desktop/assets/blobs/aqua.png +0 -0
  423. package/src/interfaces/desktop/assets/blobs/brasa.png +0 -0
  424. package/src/interfaces/desktop/assets/blobs/campana.png +0 -0
  425. package/src/interfaces/desktop/assets/blobs/caracol.png +0 -0
  426. package/src/interfaces/desktop/assets/blobs/carbon.png +0 -0
  427. package/src/interfaces/desktop/assets/blobs/cobalto.png +0 -0
  428. package/src/interfaces/desktop/assets/blobs/cometa.png +0 -0
  429. package/src/interfaces/desktop/assets/blobs/coral.png +0 -0
  430. package/src/interfaces/desktop/assets/blobs/cubi.png +0 -0
  431. package/src/interfaces/desktop/assets/blobs/eclipse.png +0 -0
  432. package/src/interfaces/desktop/assets/blobs/faro.png +0 -0
  433. package/src/interfaces/desktop/assets/blobs/gajo.png +0 -0
  434. package/src/interfaces/desktop/assets/blobs/iris.png +0 -0
  435. package/src/interfaces/desktop/assets/blobs/kiwi.png +0 -0
  436. package/src/interfaces/desktop/assets/blobs/laguna.png +0 -0
  437. package/src/interfaces/desktop/assets/blobs/lila.png +0 -0
  438. package/src/interfaces/desktop/assets/blobs/menta.png +0 -0
  439. package/src/interfaces/desktop/assets/blobs/nimbo.png +0 -0
  440. package/src/interfaces/desktop/assets/blobs/noche.png +0 -0
  441. package/src/interfaces/desktop/assets/blobs/onyx.png +0 -0
  442. package/src/interfaces/desktop/assets/blobs/orbita.png +0 -0
  443. package/src/interfaces/desktop/assets/blobs/ovni.png +0 -0
  444. package/src/interfaces/desktop/assets/blobs/papa.png +0 -0
  445. package/src/interfaces/desktop/assets/blobs/parche.png +0 -0
  446. package/src/interfaces/desktop/assets/blobs/peon.png +0 -0
  447. package/src/interfaces/desktop/assets/blobs/perla.png +0 -0
  448. package/src/interfaces/desktop/assets/blobs/pino.png +0 -0
  449. package/src/interfaces/desktop/assets/blobs/quad.png +0 -0
  450. package/src/interfaces/desktop/assets/blobs/rubi.png +0 -0
  451. package/src/interfaces/desktop/assets/blobs/saturno.png +0 -0
  452. package/src/interfaces/desktop/assets/blobs/trebol.png +0 -0
  453. package/src/interfaces/desktop/assets/blobs/trino.png +0 -0
  454. package/src/interfaces/desktop/assets/blobs/volcan.png +0 -0
  455. package/src/interfaces/desktop/assets/blobs/zafiro.png +0 -0
  456. package/src/interfaces/desktop/assets/notification.mp3 +0 -0
  457. package/src/interfaces/desktop/main.js +473 -29
  458. package/src/interfaces/desktop/mascot-blobs.js +41 -0
  459. package/src/interfaces/desktop/mascot-preload.js +32 -0
  460. package/src/interfaces/desktop/mascot.css +186 -0
  461. package/src/interfaces/desktop/mascot.html +40 -0
  462. package/src/interfaces/desktop/mascot.js +163 -0
  463. package/src/interfaces/desktop/preload.js +10 -0
  464. package/src/interfaces/desktop/renderer.js +308 -48
  465. package/src/interfaces/desktop/style.css +34 -0
  466. package/src/interfaces/mcp-server/index.js +87 -0
  467. package/src/interfaces/tui/_shims/util-locale.ts +0 -2
  468. package/src/interfaces/tui/app.tsx +0 -6
  469. package/src/interfaces/tui/attach.ts +0 -1
  470. package/src/interfaces/tui/context/sdk-apx.tsx +0 -4
  471. package/src/interfaces/tui/plugin/api.tsx +0 -3
  472. package/src/interfaces/tui/plugin/runtime.ts +0 -3
  473. package/src/interfaces/tui/thread.ts +0 -16
  474. package/src/interfaces/web/README.md +22 -14
  475. package/src/interfaces/web/dist/assets/claude-XtpLmGtF.webp +0 -0
  476. package/src/interfaces/web/dist/assets/codex-DExPUgvh.webp +0 -0
  477. package/src/interfaces/web/dist/assets/index-BEoRgIqd.css +32 -0
  478. package/src/interfaces/web/dist/assets/index-BEoRgIqd.css.br +0 -0
  479. package/src/interfaces/web/dist/assets/index-BEoRgIqd.css.gz +0 -0
  480. package/src/interfaces/web/dist/assets/index-C6fXHc1p.js +1074 -0
  481. package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.br +0 -0
  482. package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.gz +0 -0
  483. package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map +1 -0
  484. package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map.br +0 -0
  485. package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map.gz +0 -0
  486. package/src/interfaces/web/dist/favicon/dark/site.webmanifest +12 -6
  487. package/src/interfaces/web/dist/favicon/white/site.webmanifest +12 -6
  488. package/src/interfaces/web/dist/index.html +22 -6
  489. package/src/interfaces/web/dist/index.html.br +0 -0
  490. package/src/interfaces/web/dist/index.html.gz +0 -0
  491. package/src/interfaces/web/dist/manifest.webmanifest +25 -0
  492. package/src/interfaces/web/dist/modules/blobs/amatista.png +0 -0
  493. package/src/interfaces/web/dist/modules/blobs/aqua.png +0 -0
  494. package/src/interfaces/web/dist/modules/blobs/brasa.png +0 -0
  495. package/src/interfaces/web/dist/modules/blobs/campana.png +0 -0
  496. package/src/interfaces/web/dist/modules/blobs/caracol.png +0 -0
  497. package/src/interfaces/web/dist/modules/blobs/carbon.png +0 -0
  498. package/src/interfaces/web/dist/modules/blobs/cobalto.png +0 -0
  499. package/src/interfaces/web/dist/modules/blobs/cometa.png +0 -0
  500. package/src/interfaces/web/dist/modules/blobs/coral.png +0 -0
  501. package/src/interfaces/web/dist/modules/blobs/cubi.png +0 -0
  502. package/src/interfaces/web/dist/modules/blobs/eclipse.png +0 -0
  503. package/src/interfaces/web/dist/modules/blobs/faro.png +0 -0
  504. package/src/interfaces/web/dist/modules/blobs/gajo.png +0 -0
  505. package/src/interfaces/web/dist/modules/blobs/iris.png +0 -0
  506. package/src/interfaces/web/dist/modules/blobs/kiwi.png +0 -0
  507. package/src/interfaces/web/dist/modules/blobs/laguna.png +0 -0
  508. package/src/interfaces/web/dist/modules/blobs/lila.png +0 -0
  509. package/src/interfaces/web/dist/modules/blobs/menta.png +0 -0
  510. package/src/interfaces/web/dist/modules/blobs/nimbo.png +0 -0
  511. package/src/interfaces/web/dist/modules/blobs/noche.png +0 -0
  512. package/src/interfaces/web/dist/modules/blobs/onyx.png +0 -0
  513. package/src/interfaces/web/dist/modules/blobs/orbita.png +0 -0
  514. package/src/interfaces/web/dist/modules/blobs/ovni.png +0 -0
  515. package/src/interfaces/web/dist/modules/blobs/papa.png +0 -0
  516. package/src/interfaces/web/dist/modules/blobs/parche.png +0 -0
  517. package/src/interfaces/web/dist/modules/blobs/peon.png +0 -0
  518. package/src/interfaces/web/dist/modules/blobs/perla.png +0 -0
  519. package/src/interfaces/web/dist/modules/blobs/pino.png +0 -0
  520. package/src/interfaces/web/dist/modules/blobs/quad.png +0 -0
  521. package/src/interfaces/web/dist/modules/blobs/rubi.png +0 -0
  522. package/src/interfaces/web/dist/modules/blobs/saturno.png +0 -0
  523. package/src/interfaces/web/dist/modules/blobs/trebol.png +0 -0
  524. package/src/interfaces/web/dist/modules/blobs/trino.png +0 -0
  525. package/src/interfaces/web/dist/modules/blobs/volcan.png +0 -0
  526. package/src/interfaces/web/dist/modules/blobs/zafiro.png +0 -0
  527. package/src/interfaces/web/dist/sw.js +106 -0
  528. package/src/interfaces/web/dist/sw.js.br +0 -0
  529. package/src/interfaces/web/dist/sw.js.gz +0 -0
  530. package/src/interfaces/web/eslint.config.js +83 -0
  531. package/src/interfaces/web/index.html +20 -4
  532. package/src/interfaces/web/package-lock.json +1651 -1280
  533. package/src/interfaces/web/package.json +9 -10
  534. package/src/interfaces/web/pnpm-lock.yaml +867 -869
  535. package/src/interfaces/web/public/favicon/dark/site.webmanifest +12 -6
  536. package/src/interfaces/web/public/favicon/white/site.webmanifest +12 -6
  537. package/src/interfaces/web/public/manifest.webmanifest +25 -0
  538. package/src/interfaces/web/public/modules/blobs/amatista.png +0 -0
  539. package/src/interfaces/web/public/modules/blobs/aqua.png +0 -0
  540. package/src/interfaces/web/public/modules/blobs/brasa.png +0 -0
  541. package/src/interfaces/web/public/modules/blobs/campana.png +0 -0
  542. package/src/interfaces/web/public/modules/blobs/caracol.png +0 -0
  543. package/src/interfaces/web/public/modules/blobs/carbon.png +0 -0
  544. package/src/interfaces/web/public/modules/blobs/cobalto.png +0 -0
  545. package/src/interfaces/web/public/modules/blobs/cometa.png +0 -0
  546. package/src/interfaces/web/public/modules/blobs/coral.png +0 -0
  547. package/src/interfaces/web/public/modules/blobs/cubi.png +0 -0
  548. package/src/interfaces/web/public/modules/blobs/eclipse.png +0 -0
  549. package/src/interfaces/web/public/modules/blobs/faro.png +0 -0
  550. package/src/interfaces/web/public/modules/blobs/gajo.png +0 -0
  551. package/src/interfaces/web/public/modules/blobs/iris.png +0 -0
  552. package/src/interfaces/web/public/modules/blobs/kiwi.png +0 -0
  553. package/src/interfaces/web/public/modules/blobs/laguna.png +0 -0
  554. package/src/interfaces/web/public/modules/blobs/lila.png +0 -0
  555. package/src/interfaces/web/public/modules/blobs/menta.png +0 -0
  556. package/src/interfaces/web/public/modules/blobs/nimbo.png +0 -0
  557. package/src/interfaces/web/public/modules/blobs/noche.png +0 -0
  558. package/src/interfaces/web/public/modules/blobs/onyx.png +0 -0
  559. package/src/interfaces/web/public/modules/blobs/orbita.png +0 -0
  560. package/src/interfaces/web/public/modules/blobs/ovni.png +0 -0
  561. package/src/interfaces/web/public/modules/blobs/papa.png +0 -0
  562. package/src/interfaces/web/public/modules/blobs/parche.png +0 -0
  563. package/src/interfaces/web/public/modules/blobs/peon.png +0 -0
  564. package/src/interfaces/web/public/modules/blobs/perla.png +0 -0
  565. package/src/interfaces/web/public/modules/blobs/pino.png +0 -0
  566. package/src/interfaces/web/public/modules/blobs/quad.png +0 -0
  567. package/src/interfaces/web/public/modules/blobs/rubi.png +0 -0
  568. package/src/interfaces/web/public/modules/blobs/saturno.png +0 -0
  569. package/src/interfaces/web/public/modules/blobs/trebol.png +0 -0
  570. package/src/interfaces/web/public/modules/blobs/trino.png +0 -0
  571. package/src/interfaces/web/public/modules/blobs/volcan.png +0 -0
  572. package/src/interfaces/web/public/modules/blobs/zafiro.png +0 -0
  573. package/src/interfaces/web/public/sw.js +106 -0
  574. package/src/interfaces/web/src/App.tsx +106 -10
  575. package/src/interfaces/web/src/assets/cli/claude.webp +0 -0
  576. package/src/interfaces/web/src/assets/cli/codex.webp +0 -0
  577. package/src/interfaces/web/src/assets/cli/cursor.svg +1 -0
  578. package/src/interfaces/web/src/assets/cli/opencode.png +0 -0
  579. package/src/interfaces/web/src/components/Combobox.tsx +201 -0
  580. package/src/interfaces/web/src/components/MobileHint.tsx +95 -0
  581. package/src/interfaces/web/src/components/MobileLinkDialog.tsx +156 -0
  582. package/src/interfaces/web/src/components/ModelCombobox.tsx +21 -113
  583. package/src/interfaces/web/src/components/{routines/ReadOnlyBlock.tsx → ReadOnlyBlock.tsx} +13 -4
  584. package/src/interfaces/web/src/components/Roby.tsx +5 -3
  585. package/src/interfaces/web/src/components/RobyBubble.tsx +23 -5
  586. package/src/interfaces/web/src/components/RowMenu.tsx +46 -0
  587. package/src/interfaces/web/src/components/TimezoneSelect.tsx +4 -1
  588. package/src/interfaces/web/src/components/Toast.tsx +50 -14
  589. package/src/interfaces/web/src/components/UiSelect.tsx +12 -5
  590. package/src/interfaces/web/src/components/agents/AgentAvatar.tsx +171 -0
  591. package/src/interfaces/web/src/components/agents/AgentFormFields.tsx +42 -11
  592. package/src/interfaces/web/src/components/agents/AgentModelBadge.tsx +157 -0
  593. package/src/interfaces/web/src/components/agents/AgentModelSelect.tsx +57 -0
  594. package/src/interfaces/web/src/components/agents/AgentSkillsPicker.tsx +115 -0
  595. package/src/interfaces/web/src/components/agents/BlobAvatar.tsx +50 -0
  596. package/src/interfaces/web/src/components/agents/blobPresets.ts +50 -0
  597. package/src/interfaces/web/src/components/agents/modelCatalog.ts +66 -0
  598. package/src/interfaces/web/src/components/chat/ActionGroup.tsx +162 -0
  599. package/src/interfaces/web/src/components/chat/AskAnswersCard.tsx +4 -3
  600. package/src/interfaces/web/src/components/chat/AskQuestionsCard.tsx +1 -1
  601. package/src/interfaces/web/src/components/chat/Attachment.tsx +220 -0
  602. package/src/interfaces/web/src/components/chat/ChatList.tsx +226 -51
  603. package/src/interfaces/web/src/components/chat/ChatRowActivity.tsx +45 -0
  604. package/src/interfaces/web/src/components/chat/Composer.tsx +672 -23
  605. package/src/interfaces/web/src/components/chat/ComposerCommands.tsx +175 -0
  606. package/src/interfaces/web/src/components/chat/ComposerSuggest.tsx +215 -0
  607. package/src/interfaces/web/src/components/chat/ContextBar.tsx +133 -65
  608. package/src/interfaces/web/src/components/chat/InlineAskPanel.tsx +107 -47
  609. package/src/interfaces/web/src/components/chat/MessageBubble.tsx +460 -119
  610. package/src/interfaces/web/src/components/chat/MessageList.tsx +165 -18
  611. package/src/interfaces/web/src/components/chat/ReasoningBlock.tsx +58 -0
  612. package/src/interfaces/web/src/components/chat/SessionPicker.tsx +182 -0
  613. package/src/interfaces/web/src/components/chat/SkillTrace.tsx +183 -0
  614. package/src/interfaces/web/src/components/chat/ToolCall.tsx +11 -11
  615. package/src/interfaces/web/src/components/code/CodeContextTab.tsx +87 -53
  616. package/src/interfaces/web/src/components/code/CodeFileTree.tsx +11 -52
  617. package/src/interfaces/web/src/components/code/CodeFileViewer.tsx +5 -4
  618. package/src/interfaces/web/src/components/code/CodeProjectPicker.tsx +31 -7
  619. package/src/interfaces/web/src/components/code/CodeSessionList.tsx +32 -11
  620. package/src/interfaces/web/src/components/code/CodeSidePanel.tsx +33 -3
  621. package/src/interfaces/web/src/components/code/CodeTerminal.tsx +5 -4
  622. package/src/interfaces/web/src/components/code/NewCodeSessionDialog.tsx +164 -0
  623. package/src/interfaces/web/src/components/commitments/CommitmentDetail.tsx +162 -0
  624. package/src/interfaces/web/src/components/commitments/CommitmentFormDialog.tsx +158 -0
  625. package/src/interfaces/web/src/components/commitments/CommitmentList.tsx +194 -0
  626. package/src/interfaces/web/src/components/commitments/commitmentState.tsx +46 -0
  627. package/src/interfaces/web/src/components/common/BulkActionBar.tsx +60 -0
  628. package/src/interfaces/web/src/components/common/ConfirmDialog.tsx +4 -1
  629. package/src/interfaces/web/src/components/common/SelectCheckbox.tsx +40 -0
  630. package/src/interfaces/web/src/components/common/TabNav.tsx +1 -1
  631. package/src/interfaces/web/src/components/cron/CronPicker.tsx +1 -1
  632. package/src/interfaces/web/src/components/files/FileBrowser.tsx +1 -1
  633. package/src/interfaces/web/src/components/files/FileTree.tsx +6 -4
  634. package/src/interfaces/web/src/components/files/FileViewer.tsx +9 -5
  635. package/src/interfaces/web/src/components/files/MarkdownPreview.tsx +45 -9
  636. package/src/interfaces/web/src/components/images/ImageDefaultsCard.tsx +93 -0
  637. package/src/interfaces/web/src/components/images/ImageProviderList.tsx +142 -0
  638. package/src/interfaces/web/src/components/images/ImageProviderModal.tsx +263 -0
  639. package/src/interfaces/web/src/components/images/ImageTestCard.tsx +142 -0
  640. package/src/interfaces/web/src/components/inbox/ChannelFilter.tsx +178 -0
  641. package/src/interfaces/web/src/components/inbox/InboxList.tsx +77 -81
  642. package/src/interfaces/web/src/components/inbox/InboxRowItem.tsx +140 -0
  643. package/src/interfaces/web/src/components/integrations/ComingSoonPlugin.tsx +2 -2
  644. package/src/interfaces/web/src/components/integrations/PluginConnect.tsx +208 -30
  645. package/src/interfaces/web/src/components/integrations/PluginToolsSection.tsx +1 -1
  646. package/src/interfaces/web/src/components/layout/ProjectAvatar.tsx +39 -24
  647. package/src/interfaces/web/src/components/layout/ProjectSidebar.tsx +253 -58
  648. package/src/interfaces/web/src/components/memory/MemoryBrowser.tsx +94 -47
  649. package/src/interfaces/web/src/components/routines/ExecutionsList.tsx +202 -90
  650. package/src/interfaces/web/src/components/routines/RoutineDetail.tsx +28 -6
  651. package/src/interfaces/web/src/components/routines/RoutineEditor.tsx +16 -5
  652. package/src/interfaces/web/src/components/routines/RoutineList.tsx +49 -9
  653. package/src/interfaces/web/src/components/routines/VarTextarea.tsx +1 -1
  654. package/src/interfaces/web/src/components/routines/runChat.ts +121 -0
  655. package/src/interfaces/web/src/components/sessions/SessionDetail.tsx +148 -0
  656. package/src/interfaces/web/src/components/sessions/SessionTerminal.tsx +98 -0
  657. package/src/interfaces/web/src/components/settings/AccessPanel.tsx +205 -0
  658. package/src/interfaces/web/src/components/settings/DefaultRouterCard.tsx +246 -101
  659. package/src/interfaces/web/src/components/settings/DesktopSettingsPanel.tsx +36 -2
  660. package/src/interfaces/web/src/components/settings/DevicesPanel.tsx +19 -6
  661. package/src/interfaces/web/src/components/settings/EmbedProviderList.tsx +274 -0
  662. package/src/interfaces/web/src/components/settings/EnginesPanel.tsx +26 -6
  663. package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +118 -119
  664. package/src/interfaces/web/src/components/settings/NudgePanel.tsx +4 -3
  665. package/src/interfaces/web/src/components/settings/PairDeviceDialog.tsx +15 -4
  666. package/src/interfaces/web/src/components/settings/PanelPrefs.tsx +374 -0
  667. package/src/interfaces/web/src/components/settings/ProfilePanel.tsx +70 -2
  668. package/src/interfaces/web/src/components/settings/RoutingPanel.tsx +2 -1
  669. package/src/interfaces/web/src/components/settings/SkillsInspectorPanel.tsx +102 -43
  670. package/src/interfaces/web/src/components/settings/SkillsManager.tsx +76 -21
  671. package/src/interfaces/web/src/components/settings/SkillsSettings.tsx +10 -3
  672. package/src/interfaces/web/src/components/settings/SuperAgentPanel.tsx +8 -0
  673. package/src/interfaces/web/src/components/settings/TelegramChannelsPanel.tsx +11 -2
  674. package/src/interfaces/web/src/components/settings/TelegramContactsPanel.tsx +19 -8
  675. package/src/interfaces/web/src/components/settings/TelegramRolesPanel.tsx +12 -2
  676. package/src/interfaces/web/src/components/settings/WebPanel.tsx +22 -31
  677. package/src/interfaces/web/src/components/settings/providers/ProviderCard.tsx +15 -3
  678. package/src/interfaces/web/src/components/settings/providers/ProviderModal.tsx +97 -66
  679. package/src/interfaces/web/src/components/settings/providers/ProviderTestDialog.tsx +150 -0
  680. package/src/interfaces/web/src/components/settings/providers/typeStyles.ts +67 -25
  681. package/src/interfaces/web/src/components/settings/providers/types.ts +3 -0
  682. package/src/interfaces/web/src/components/tasks/TaskBoard.tsx +201 -0
  683. package/src/interfaces/web/src/components/tasks/TaskColumnsDialog.tsx +243 -0
  684. package/src/interfaces/web/src/components/tasks/TaskComments.tsx +167 -0
  685. package/src/interfaces/web/src/components/tasks/TaskDetail.tsx +335 -0
  686. package/src/interfaces/web/src/components/tasks/TaskFormDialog.tsx +406 -0
  687. package/src/interfaces/web/src/components/tasks/TaskList.tsx +258 -0
  688. package/src/interfaces/web/src/components/tasks/TaskSubtasks.tsx +126 -0
  689. package/src/interfaces/web/src/components/tasks/columns.ts +51 -0
  690. package/src/interfaces/web/src/components/tasks/taskStatus.tsx +159 -34
  691. package/src/interfaces/web/src/components/tasks/taskViewPrefs.ts +73 -0
  692. package/src/interfaces/web/src/components/tasks/useTaskColumns.ts +31 -0
  693. package/src/interfaces/web/src/components/ui/chat-input.tsx +136 -12
  694. package/src/interfaces/web/src/components/ui/context-menu.tsx +15 -198
  695. package/src/interfaces/web/src/components/ui/dialog.tsx +3 -2
  696. package/src/interfaces/web/src/components/ui/filter-chips.tsx +4 -0
  697. package/src/interfaces/web/src/components/ui/popover.tsx +14 -49
  698. package/src/interfaces/web/src/components/ui/sheet.tsx +2 -1
  699. package/src/interfaces/web/src/components/ui/spinner.tsx +2 -1
  700. package/src/interfaces/web/src/components/ui.tsx +62 -23
  701. package/src/interfaces/web/src/components/voice/VoiceProviderList.tsx +2 -1
  702. package/src/interfaces/web/src/components/voice/VoiceProviderModal.tsx +66 -8
  703. package/src/interfaces/web/src/components/voice/VoiceQvoxInstallCard.tsx +63 -0
  704. package/src/interfaces/web/src/components/voice/VoiceQvoxStatusCard.tsx +51 -0
  705. package/src/interfaces/web/src/components/voice/VoiceSttCard.tsx +4 -3
  706. package/src/interfaces/web/src/components/voice/VoiceTestCard.tsx +38 -4
  707. package/src/interfaces/web/src/constants/index.ts +1 -0
  708. package/src/interfaces/web/src/hooks/useChannelPrefs.ts +39 -0
  709. package/src/interfaces/web/src/hooks/useChat.ts +1092 -85
  710. package/src/interfaces/web/src/hooks/useChatActivity.ts +24 -0
  711. package/src/interfaces/web/src/hooks/useInbox.ts +26 -4
  712. package/src/interfaces/web/src/hooks/useLiveMessages.ts +16 -0
  713. package/src/interfaces/web/src/hooks/useOllamaModels.ts +79 -0
  714. package/src/interfaces/web/src/hooks/useRecorder.ts +198 -0
  715. package/src/interfaces/web/src/hooks/useTokenBootstrap.ts +23 -6
  716. package/src/interfaces/web/src/i18n/en.ts +832 -175
  717. package/src/interfaces/web/src/i18n/es.ts +841 -188
  718. package/src/interfaces/web/src/lib/api/agents.ts +23 -4
  719. package/src/interfaces/web/src/lib/api/code.ts +17 -0
  720. package/src/interfaces/web/src/lib/api/commitments.ts +7 -1
  721. package/src/interfaces/web/src/lib/api/conversations.ts +38 -11
  722. package/src/interfaces/web/src/lib/api/embeddings.ts +3 -0
  723. package/src/interfaces/web/src/lib/api/engines.ts +14 -0
  724. package/src/interfaces/web/src/lib/api/groups.ts +93 -0
  725. package/src/interfaces/web/src/lib/api/images.ts +193 -0
  726. package/src/interfaces/web/src/lib/api/inbox.ts +29 -5
  727. package/src/interfaces/web/src/lib/api/integrations.ts +9 -0
  728. package/src/interfaces/web/src/lib/api/media.ts +126 -0
  729. package/src/interfaces/web/src/lib/api/net.ts +44 -0
  730. package/src/interfaces/web/src/lib/api/profiles.ts +12 -0
  731. package/src/interfaces/web/src/lib/api/projects.ts +9 -1
  732. package/src/interfaces/web/src/lib/api/routines.ts +9 -1
  733. package/src/interfaces/web/src/lib/api/sessions.ts +18 -0
  734. package/src/interfaces/web/src/lib/api/skills.ts +8 -0
  735. package/src/interfaces/web/src/lib/api/super_agent.ts +3 -0
  736. package/src/interfaces/web/src/lib/api/tasks.ts +46 -6
  737. package/src/interfaces/web/src/lib/api/tools.ts +2 -0
  738. package/src/interfaces/web/src/lib/api/transcribe.ts +31 -0
  739. package/src/interfaces/web/src/lib/api/turns.ts +20 -0
  740. package/src/interfaces/web/src/lib/api/voice.ts +72 -2
  741. package/src/interfaces/web/src/lib/api.ts +3 -0
  742. package/src/interfaces/web/src/lib/channels.ts +214 -0
  743. package/src/interfaces/web/src/lib/chat-activity.ts +175 -0
  744. package/src/interfaces/web/src/lib/chat-prefs.ts +48 -0
  745. package/src/interfaces/web/src/lib/code-context.ts +0 -2
  746. package/src/interfaces/web/src/lib/http.ts +51 -17
  747. package/src/interfaces/web/src/lib/inbox-selection.ts +29 -0
  748. package/src/interfaces/web/src/lib/live.ts +252 -0
  749. package/src/interfaces/web/src/lib/net.ts +211 -0
  750. package/src/interfaces/web/src/lib/notify.ts +331 -0
  751. package/src/interfaces/web/src/lib/projectNav.ts +40 -0
  752. package/src/interfaces/web/src/lib/pwa.ts +115 -0
  753. package/src/interfaces/web/src/lib/qvox.ts +24 -0
  754. package/src/interfaces/web/src/lib/slug.ts +3 -0
  755. package/src/interfaces/web/src/lib/tone.ts +150 -0
  756. package/src/interfaces/web/src/main.tsx +15 -4
  757. package/src/interfaces/web/src/screens/ApxAdminScreen.tsx +33 -11
  758. package/src/interfaces/web/src/screens/InboxScreen.tsx +126 -71
  759. package/src/interfaces/web/src/screens/ProjectScreen.tsx +8 -4
  760. package/src/interfaces/web/src/screens/SettingsScreen.tsx +7 -4
  761. package/src/interfaces/web/src/screens/base/AgentDefaultsTab.tsx +30 -9
  762. package/src/interfaces/web/src/screens/base/CommitmentsTab.tsx +150 -168
  763. package/src/interfaces/web/src/screens/base/LogsTab.tsx +8 -7
  764. package/src/interfaces/web/src/screens/base/SessionsTab.tsx +99 -37
  765. package/src/interfaces/web/src/screens/base/WorkspacesTab.tsx +1 -1
  766. package/src/interfaces/web/src/screens/mobile/MobileChat.tsx +85 -0
  767. package/src/interfaces/web/src/screens/mobile/MobileChatList.tsx +244 -0
  768. package/src/interfaces/web/src/screens/mobile/MobileCommitments.tsx +350 -0
  769. package/src/interfaces/web/src/screens/mobile/MobileScreen.tsx +138 -0
  770. package/src/interfaces/web/src/screens/mobile/MobileTabBar.tsx +105 -0
  771. package/src/interfaces/web/src/screens/mobile/MobileTasks.tsx +407 -0
  772. package/src/interfaces/web/src/screens/mobile/NewChatSheet.tsx +313 -0
  773. package/src/interfaces/web/src/screens/mobile/mobileList.tsx +194 -0
  774. package/src/interfaces/web/src/screens/mobile/routes.ts +239 -0
  775. package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +135 -64
  776. package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +0 -1
  777. package/src/interfaces/web/src/screens/modules/ImagesScreen.tsx +172 -0
  778. package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +36 -4
  779. package/src/interfaces/web/src/screens/project/AgentBrainGraph.tsx +117 -30
  780. package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +537 -92
  781. package/src/interfaces/web/src/screens/project/AgentsTab.tsx +344 -93
  782. package/src/interfaces/web/src/screens/project/ArtifactsTab.tsx +1 -1
  783. package/src/interfaces/web/src/screens/project/ChatTab.tsx +1160 -94
  784. package/src/interfaces/web/src/screens/project/IntegrationsTab.tsx +3 -2
  785. package/src/interfaces/web/src/screens/project/McpsTab.tsx +62 -14
  786. package/src/interfaces/web/src/screens/project/Overview.tsx +36 -15
  787. package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +93 -8
  788. package/src/interfaces/web/src/screens/project/SkillsTab.tsx +4 -1
  789. package/src/interfaces/web/src/screens/project/StructureTab.tsx +5 -4
  790. package/src/interfaces/web/src/screens/project/TasksTab.tsx +351 -129
  791. package/src/interfaces/web/src/screens/project/VarsTab.tsx +17 -5
  792. package/src/interfaces/web/src/styles.css +106 -31
  793. package/src/interfaces/web/src/types/daemon.ts +246 -2
  794. package/src/interfaces/web/src/vite-env.d.ts +20 -0
  795. package/src/interfaces/tui/plugin/command-shim.ts +0 -109
  796. package/src/interfaces/web/components.json +0 -25
  797. package/src/interfaces/web/dist/assets/index-CvEoGtTf.js +0 -849
  798. package/src/interfaces/web/dist/assets/index-CvEoGtTf.js.map +0 -1
  799. package/src/interfaces/web/dist/assets/index-DzBBXFaO.css +0 -1
  800. package/src/interfaces/web/src/components/tasks/TaskDetailPanel.tsx +0 -142
  801. package/src/interfaces/web/src/components/ui/accordion.tsx +0 -72
  802. package/src/interfaces/web/src/components/ui/alert-dialog.tsx +0 -187
  803. package/src/interfaces/web/src/components/ui/alert.tsx +0 -76
  804. package/src/interfaces/web/src/components/ui/aspect-ratio.tsx +0 -22
  805. package/src/interfaces/web/src/components/ui/avatar.tsx +0 -107
  806. package/src/interfaces/web/src/components/ui/breadcrumb.tsx +0 -125
  807. package/src/interfaces/web/src/components/ui/button-group.tsx +0 -87
  808. package/src/interfaces/web/src/components/ui/calendar.tsx +0 -221
  809. package/src/interfaces/web/src/components/ui/card.tsx +0 -103
  810. package/src/interfaces/web/src/components/ui/carousel.tsx +0 -242
  811. package/src/interfaces/web/src/components/ui/chart.tsx +0 -371
  812. package/src/interfaces/web/src/components/ui/checkbox.tsx +0 -29
  813. package/src/interfaces/web/src/components/ui/collapsible.tsx +0 -19
  814. package/src/interfaces/web/src/components/ui/combobox.tsx +0 -295
  815. package/src/interfaces/web/src/components/ui/command.tsx +0 -196
  816. package/src/interfaces/web/src/components/ui/direction.tsx +0 -4
  817. package/src/interfaces/web/src/components/ui/drawer.tsx +0 -134
  818. package/src/interfaces/web/src/components/ui/empty.tsx +0 -104
  819. package/src/interfaces/web/src/components/ui/field.tsx +0 -236
  820. package/src/interfaces/web/src/components/ui/hover-card.tsx +0 -51
  821. package/src/interfaces/web/src/components/ui/input-otp.tsx +0 -85
  822. package/src/interfaces/web/src/components/ui/item.tsx +0 -201
  823. package/src/interfaces/web/src/components/ui/menubar.tsx +0 -280
  824. package/src/interfaces/web/src/components/ui/native-select.tsx +0 -61
  825. package/src/interfaces/web/src/components/ui/navigation-menu.tsx +0 -168
  826. package/src/interfaces/web/src/components/ui/pagination.tsx +0 -130
  827. package/src/interfaces/web/src/components/ui/progress.tsx +0 -83
  828. package/src/interfaces/web/src/components/ui/radio-group.tsx +0 -36
  829. package/src/interfaces/web/src/components/ui/resizable.tsx +0 -50
  830. package/src/interfaces/web/src/components/ui/scroll-area.tsx +0 -53
  831. package/src/interfaces/web/src/components/ui/sidebar.tsx +0 -726
  832. package/src/interfaces/web/src/components/ui/slider.tsx +0 -52
  833. package/src/interfaces/web/src/components/ui/sonner.tsx +0 -49
  834. package/src/interfaces/web/src/components/ui/table.tsx +0 -116
  835. package/src/interfaces/web/src/components/ui/toggle-group.tsx +0 -87
  836. package/src/interfaces/web/src/components/ui/toggle.tsx +0 -45
  837. package/src/interfaces/web/src/hooks/use-mobile.ts +0 -19
  838. package/src/interfaces/web/src/screens/base/GlobalTasksTab.tsx +0 -161
@@ -20,12 +20,11 @@
20
20
  // },
21
21
  // ...
22
22
  // ],
23
- // // legacy single-channel keys (used only when channels[] is absent/empty):
24
- // "bot_token": "",
25
- // "chat_id": "",
26
- // "route_to_agent": "",
23
+ // "route_to_agent": "", // default for channels that omit it
27
24
  // "poll_interval_ms": 1500
28
25
  // }
26
+ // With channels[] empty, one implicit "default" channel is polled using
27
+ // BOT_TELEGRAM_TOKEN / TELEGRAM_CHAT_ID from the environment.
29
28
 
30
29
  // This poller is intentionally thin: per-update logic lives in core/channels/
31
30
  // telegram/ — dispatch (inbound routing), reply (the super-agent turn),
@@ -49,10 +48,56 @@ import { handleUpdate } from "#core/channels/telegram/dispatch.js";
49
48
  import { handleCallbackQuery, startAskFlow, maybeConsumeAskTextAnswer } from "#core/channels/telegram/ask-callbacks.js";
50
49
  import { sendMessage, sendChatAction, editMessageReplyMarkup, answerCallbackQuery, getUpdates } from "#core/channels/telegram/api.js";
51
50
  import { sendPhoto, sendVoice, sendDocument, sendAudio } from "#core/channels/telegram/media.js";
51
+ import { archiveOutboundMedia, outboundMediaMeta } from "#core/stores/media-archive.js";
52
52
  export { sendPhoto, sendVoice, sendDocument, sendAudio };
53
53
 
54
54
  const nowIso = () => new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
55
55
 
56
+ /**
57
+ * Record a photo/voice/document/audio the agent just SENT, with the file on it.
58
+ *
59
+ * Two bugs lived in the four copies of this that used to be inline below.
60
+ *
61
+ * `type` was the media kind ("photo", "voice", …), and the ledger's type is a
62
+ * five-value enum (core/stores/messages.js: user | agent | tool | system |
63
+ * compact). `inferMessageType` dropped the unknown value in silence and fell
64
+ * through to "outbound ⇒ agent", so the row was written — just not as anything
65
+ * that said a file was involved. The kind belongs in meta, where
66
+ * `mediaFromMeta` reads it; `type` says who spoke.
67
+ *
68
+ * And the meta named no file at all, so a thread had nothing to render: the
69
+ * caption alone, or the bare placeholder `[photo]` when the send had none. The
70
+ * bytes are archived first (media-archive.js) because a path outside
71
+ * ~/.apx/media is one the media endpoint must refuse — the photo the user
72
+ * already has on Telegram would still read "attachment failed" on the web.
73
+ */
74
+ function logSentMedia({ poller, chat_id, author, kind, body, source, filename, mime, duration }) {
75
+ const archived = archiveOutboundMedia(source, { filename, mime });
76
+ appendGlobalMessage({
77
+ channel: CHANNELS.TELEGRAM,
78
+ direction: "out",
79
+ type: "agent",
80
+ actor_id: SUPERAGENT_ACTOR_ID,
81
+ actor_kind: "superagent",
82
+ // Same attribution `send()` writes. Without it the row is an agent turn
83
+ // that names no agent, and the thread cannot say who sent the file.
84
+ agent_slug: SUPERAGENT_ACTOR_ID,
85
+ author,
86
+ body,
87
+ meta: {
88
+ chat_id: chat_id || resolveChatId(poller.channel),
89
+ tg_channel: poller.channel.name,
90
+ // A send by public URL has no bytes of ours to keep, so it gets no
91
+ // attachment — but the row should still say what went out. Names only:
92
+ // `mediaFromMeta` needs a path before it offers a card, so this can never
93
+ // put a player on screen with nothing behind it.
94
+ ...(filename ? { file_name: filename } : {}),
95
+ ...(mime ? { mime_type: mime } : {}),
96
+ ...outboundMediaMeta(kind, archived, { duration }),
97
+ },
98
+ });
99
+ }
100
+
56
101
  // ---------- per-channel poller ----------------------------------------------
57
102
 
58
103
  class ChannelPoller {
@@ -64,9 +109,7 @@ class ChannelPoller {
64
109
  this.plugins = plugins;
65
110
  this.registries = registries;
66
111
  this.state = loadState();
67
- this.offset =
68
- this.state.channels?.[channel.name]?.offset ??
69
- (channel.name === "default" ? this.state._legacy_offset || 0 : 0);
112
+ this.offset = this.state.channels?.[channel.name]?.offset ?? 0;
70
113
  this.polling = false;
71
114
  this.lastError = null;
72
115
  this.lastUpdateAt = null;
@@ -116,6 +159,12 @@ class ChannelPoller {
116
159
 
117
160
  stop() {
118
161
  this.polling = false;
162
+ // Kill in-flight turns so a restart doesn't leave a zombie run that still
163
+ // holds the chat (and so `apx daemon restart` actually interrupts Telegram).
164
+ for (const ctrl of this.activeRequests.values()) {
165
+ try { ctrl.abort(); } catch { /* already aborted */ }
166
+ }
167
+ this.activeRequests.clear();
119
168
  }
120
169
 
121
170
  async _loop() {
@@ -127,6 +176,9 @@ class ChannelPoller {
127
176
  // A successful poll clears any stale error so status reflects recovery.
128
177
  this.lastError = null;
129
178
  for (const u of updates) {
179
+ // handleUpdate logs inbound + spawns the model turn; it must NOT
180
+ // await the super-agent. Awaiting the whole run froze getUpdates,
181
+ // so a newer message could never abort the one in flight.
130
182
  await this._handleUpdate(u);
131
183
  this.offset = u.update_id + 1;
132
184
  this._saveOffset();
@@ -192,7 +244,12 @@ class ChannelPoller {
192
244
  async _typing(chat_id) {
193
245
  const token = resolveBotToken(this.channel);
194
246
  if (!token || !chat_id) return;
195
- try { await sendChatAction(token, chat_id); } catch { /* best-effort */ }
247
+ try {
248
+ await sendChatAction(token, chat_id);
249
+ } catch (e) {
250
+ // A silent typing failure looks exactly like a frozen agent to the owner.
251
+ this.log(`telegram[${this.channel.name}] sendChatAction failed: ${e.message}`);
252
+ }
196
253
  }
197
254
 
198
255
  // Returns a stop() fn; pings the typing indicator every 4s until called.
@@ -318,6 +375,7 @@ export default {
318
375
  async send({ channel: channelName, chat_id, text, reply_markup, author = resolveAgentName(config), meta: extraMeta }) {
319
376
  const p = pickPoller(pollers, channelName);
320
377
  const result = await p._send({ chat_id, text, reply_markup });
378
+ // attribution-exempt: relay primitive — send() ships text the caller composed; a caller that spent tokens passes model/usage via `meta`.
321
379
  appendGlobalMessage({
322
380
  channel: CHANNELS.TELEGRAM,
323
381
  direction: "out",
@@ -345,15 +403,10 @@ export default {
345
403
  async sendPhoto({ channel: channelName, chat_id, photo, caption, parse_mode, author = resolveAgentName(config) }) {
346
404
  const p = pickPoller(pollers, channelName);
347
405
  const result = await p._sendPhoto({ chat_id, photo, caption, parse_mode });
348
- appendGlobalMessage({
349
- channel: CHANNELS.TELEGRAM,
350
- direction: "out",
351
- type: "photo",
352
- actor_id: SUPERAGENT_ACTOR_ID,
353
- actor_kind: "superagent",
354
- author,
406
+ logSentMedia({
407
+ poller: p, chat_id, author, kind: "photo",
355
408
  body: caption || "[photo]",
356
- meta: { chat_id: chat_id || resolveChatId(p.channel), tg_channel: p.channel.name },
409
+ source: photo,
357
410
  });
358
411
  return result;
359
412
  },
@@ -365,15 +418,10 @@ export default {
365
418
  async sendVoice({ channel: channelName, chat_id, audio, caption, duration, author = resolveAgentName(config) }) {
366
419
  const p = pickPoller(pollers, channelName);
367
420
  const result = await p._sendVoice({ chat_id, audio, caption, duration });
368
- appendGlobalMessage({
369
- channel: CHANNELS.TELEGRAM,
370
- direction: "out",
371
- type: "voice",
372
- actor_id: SUPERAGENT_ACTOR_ID,
373
- actor_kind: "superagent",
374
- author,
421
+ logSentMedia({
422
+ poller: p, chat_id, author, kind: "audio",
375
423
  body: caption || "[voice]",
376
- meta: { chat_id: chat_id || resolveChatId(p.channel), tg_channel: p.channel.name },
424
+ source: audio, mime: "audio/ogg", duration,
377
425
  });
378
426
  return result;
379
427
  },
@@ -385,15 +433,10 @@ export default {
385
433
  async sendDocument({ channel: channelName, chat_id, document, caption, filename, mime_type, author = resolveAgentName(config) }) {
386
434
  const p = pickPoller(pollers, channelName);
387
435
  const result = await p._sendDocument({ chat_id, document, caption, filename, mime_type });
388
- appendGlobalMessage({
389
- channel: CHANNELS.TELEGRAM,
390
- direction: "out",
391
- type: "document",
392
- actor_id: SUPERAGENT_ACTOR_ID,
393
- actor_kind: "superagent",
394
- author,
436
+ logSentMedia({
437
+ poller: p, chat_id, author, kind: "document",
395
438
  body: caption || `[document${filename ? " " + filename : ""}]`,
396
- meta: { chat_id: chat_id || resolveChatId(p.channel), tg_channel: p.channel.name, filename, mime_type },
439
+ source: document, filename, mime: mime_type,
397
440
  });
398
441
  return result;
399
442
  },
@@ -405,15 +448,10 @@ export default {
405
448
  async sendAudio({ channel: channelName, chat_id, audio, caption, title, performer, author = resolveAgentName(config) }) {
406
449
  const p = pickPoller(pollers, channelName);
407
450
  const result = await p._sendAudio({ chat_id, audio, caption, title, performer });
408
- appendGlobalMessage({
409
- channel: CHANNELS.TELEGRAM,
410
- direction: "out",
411
- type: "audio",
412
- actor_id: SUPERAGENT_ACTOR_ID,
413
- actor_kind: "superagent",
414
- author,
451
+ logSentMedia({
452
+ poller: p, chat_id, author, kind: "audio",
415
453
  body: caption || title || "[audio]",
416
- meta: { chat_id: chat_id || resolveChatId(p.channel), tg_channel: p.channel.name },
454
+ source: audio, filename: title ? `${title}.mp3` : undefined, mime: "audio/mpeg",
417
455
  });
418
456
  return result;
419
457
  },
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env python3
2
+ """Run a command on a pseudo-terminal and relay it over stdin/stdout.
3
+
4
+ The coding CLIs APX resumes — claude, codex, opencode — are terminal programs:
5
+ they draw an alt-screen UI, read keys in raw mode, and ask the tty how wide it
6
+ is. A plain pipe gives them none of that, so they either refuse to start or
7
+ render into nothing. Something has to allocate a real pty.
8
+
9
+ The two obvious candidates don't fit. macOS `script(1)` calls tcgetattr on its
10
+ own stdin and exits when that isn't a terminal, which is exactly our case (the
11
+ daemon feeds it a pipe). `node-pty` would work, but it is a native module, and
12
+ APX installs globally through npm onto machines that may have no compiler.
13
+ Python's pty module is already load-bearing for the voice stack, costs nothing
14
+ extra here, and is a few lines.
15
+
16
+ usage: pty-bridge.py <rows> <cols> <command> [args...]
17
+
18
+ Exits with the child's status, or 1 if it was killed by a signal. Closing our
19
+ stdin does not end the session — the child decides when it is done.
20
+ """
21
+
22
+ import fcntl
23
+ import os
24
+ import pty
25
+ import select
26
+ import struct
27
+ import sys
28
+ import termios
29
+
30
+ BUF = 65536
31
+
32
+
33
+ def main():
34
+ if len(sys.argv) < 4:
35
+ sys.stderr.write("usage: pty-bridge.py <rows> <cols> <command> [args...]\n")
36
+ return 2
37
+
38
+ rows, cols = int(sys.argv[1]), int(sys.argv[2])
39
+ argv = sys.argv[3:]
40
+
41
+ pid, master = pty.fork()
42
+ if pid == 0:
43
+ # Child: becomes the CLI. execvp only returns on failure, and the
44
+ # message has to reach the pty (our stderr is the pty now) so the user
45
+ # sees "command not found" in the terminal instead of a blank panel.
46
+ try:
47
+ os.execvp(argv[0], argv)
48
+ except OSError as e:
49
+ sys.stderr.write("apx: cannot run %s: %s\r\n" % (argv[0], e))
50
+ sys.stderr.flush()
51
+ os._exit(127)
52
+
53
+ # Tell the child how big its window is before it draws anything.
54
+ try:
55
+ fcntl.ioctl(master, termios.TIOCSWINSZ, struct.pack("HHHH", rows, cols, 0, 0))
56
+ except OSError:
57
+ pass
58
+
59
+ stdin_open = True
60
+ try:
61
+ while True:
62
+ watch = [master] + ([sys.stdin.fileno()] if stdin_open else [])
63
+ try:
64
+ ready, _, _ = select.select(watch, [], [])
65
+ except InterruptedError:
66
+ continue
67
+
68
+ if master in ready:
69
+ try:
70
+ data = os.read(master, BUF)
71
+ except OSError:
72
+ break # child closed the pty — the session is over
73
+ if not data:
74
+ break
75
+ os.write(sys.stdout.fileno(), data)
76
+
77
+ if stdin_open and sys.stdin.fileno() in ready:
78
+ try:
79
+ data = os.read(sys.stdin.fileno(), BUF)
80
+ except OSError:
81
+ data = b""
82
+ if data:
83
+ os.write(master, data)
84
+ else:
85
+ # Our side hung up. Stop watching stdin, but keep relaying
86
+ # the child's output until it exits on its own.
87
+ stdin_open = False
88
+ finally:
89
+ try:
90
+ os.close(master)
91
+ except OSError:
92
+ pass
93
+
94
+ _, status = os.waitpid(pid, 0)
95
+ return os.WEXITSTATUS(status) if os.WIFEXITED(status) else 1
96
+
97
+
98
+ if __name__ == "__main__":
99
+ sys.exit(main())
@@ -52,6 +52,7 @@ export class RoutineScheduler {
52
52
  plugins: this.plugins,
53
53
  registries: this.registries,
54
54
  globalConfig: this.globalConfig,
55
+ trigger: "schedule",
55
56
  },
56
57
  r
57
58
  );
@@ -15,8 +15,7 @@ import { readAgents } from "#core/apc/parser.js";
15
15
  const __filename = fileURLToPath(import.meta.url);
16
16
  const __dirname = path.dirname(__filename);
17
17
 
18
- // Smoke now lives at src/host/daemon/smoke.js — one level deeper than the
19
- // legacy src/daemon/smoke.js. Adjust the example-project lookup accordingly:
18
+ // Example-project lookup, relative to src/host/daemon/:
20
19
  // ../../../examples/my-first-project ← repo-local examples (if any)
21
20
  // ../../../../apc/examples/my-first-project ← sibling apc/ repo
22
21
  const EXAMPLE_CANDIDATES = [
@@ -0,0 +1,132 @@
1
+ // One WebSocket, one terminal, one session.
2
+ //
3
+ // The Sessions list can tell you a conversation exists and hand you the command
4
+ // that reopens it, but pasting that command somewhere else is a context switch
5
+ // away from the thing you were reading. This channel closes the gap: the daemon
6
+ // runs the session's own CLI on a real pty and relays it to a terminal in the
7
+ // web UI.
8
+ //
9
+ // Deliberately NOT a shell. The socket says which session to reopen — engine +
10
+ // id — and the daemon derives the command from the engine that owns it
11
+ // (see resumeArgvFor). A client cannot ask for an arbitrary command, so the
12
+ // channel's blast radius is "the CLIs APX already knows how to launch" rather
13
+ // than "anything on the machine". Whatever the user then types INTO claude or
14
+ // opencode is between them and that tool, exactly as in their own terminal.
15
+ //
16
+ // The wire protocol is the absence of one: every frame is bytes. Client frames
17
+ // are keystrokes for the pty; server frames are output to draw. Status lines
18
+ // from APX itself are written into the same stream, which is why they carry a
19
+ // [apx] prefix — there is no side channel to confuse them with.
20
+ import { spawn } from "node:child_process";
21
+ import fs from "node:fs";
22
+ import os from "node:os";
23
+ import path from "node:path";
24
+ import { fileURLToPath } from "node:url";
25
+ import { apiPath } from "./api/prefix.js";
26
+ import { findSessionAcrossEngines, findSessionInEngine, resumeArgvFor } from "#core/sessions/index.js";
27
+
28
+ /** The terminal channel's upgrade path. Lives under /api like every other route. */
29
+ export const TERMINAL_WS_PATH = apiPath("/terminal/ws");
30
+
31
+ const BRIDGE = path.join(path.dirname(fileURLToPath(import.meta.url)), "pty-bridge.py");
32
+
33
+ /** Path-gate: is this upgrade for the terminal WS channel? */
34
+ export function isTerminalUpgradePath(url) {
35
+ let pathname = url || "";
36
+ try { pathname = new URL(url, "http://localhost").pathname; } catch { /* keep raw */ }
37
+ return pathname === TERMINAL_WS_PATH;
38
+ }
39
+
40
+ /** Terminal geometry, clamped: a bad number here misdraws the whole session. */
41
+ function readSize(params) {
42
+ const n = (key, dflt, min, max) => {
43
+ const v = Number(params.get(key));
44
+ return Number.isFinite(v) && v >= min && v <= max ? Math.round(v) : dflt;
45
+ };
46
+ return { rows: n("rows", 30, 4, 200), cols: n("cols", 100, 20, 500) };
47
+ }
48
+
49
+ /**
50
+ * Resolve which command reopens the session named on the query string, and
51
+ * where to run it. Returns a `problem` instead of throwing — the socket is
52
+ * already open, so every failure has to be something we can print in it.
53
+ */
54
+ export function resolveTerminalTarget(params, { home = os.homedir() } = {}) {
55
+ const id = String(params.get("id") || "");
56
+ const engineParam = String(params.get("engine") || "");
57
+ if (!id) return { problem: "no session id given" };
58
+
59
+ let meta = null;
60
+ try {
61
+ meta = engineParam ? findSessionInEngine(engineParam, id) : (findSessionAcrossEngines(id)[0] || null);
62
+ } catch { meta = null; }
63
+
64
+ // An engine we were told about is enough to build the command: a session the
65
+ // engine hasn't flushed to disk yet still deserves to open.
66
+ const engine = engineParam || meta?.engine || null;
67
+ const argv = engine ? resumeArgvFor(engine, id) : null;
68
+ if (!argv) {
69
+ return { problem: engine ? `engine "${engine}" cannot reopen a session from the terminal` : "unknown session" };
70
+ }
71
+
72
+ // Run where the conversation happened, so relative paths in it still mean
73
+ // what they meant. Engines that don't record a cwd land in the home dir.
74
+ const cwd = meta?.cwd && fs.existsSync(meta.cwd) ? meta.cwd : home;
75
+ return { argv, cwd, engine, id };
76
+ }
77
+
78
+ /**
79
+ * Attach a live terminal to `ws`. Spawns the pty bridge, relays bytes both
80
+ * ways, and makes sure neither side can outlive the other: closing the socket
81
+ * kills the CLI, and the CLI exiting closes the socket.
82
+ */
83
+ export function startTerminalSession(ws, req, { python = "python3", home = os.homedir() } = {}) {
84
+ const say = (line) => { try { if (ws.readyState === 1) ws.send(Buffer.from(`\r\n[apx] ${line}\r\n`)); } catch {} };
85
+
86
+ let params;
87
+ try { params = new URL(req.url || "", "http://localhost").searchParams; } catch { params = new URLSearchParams(); }
88
+
89
+ const target = resolveTerminalTarget(params, { home });
90
+ if (target.problem) {
91
+ say(target.problem);
92
+ try { ws.close(); } catch {}
93
+ return null;
94
+ }
95
+
96
+ const { rows, cols } = readSize(params);
97
+ let child;
98
+ try {
99
+ child = spawn(python, [BRIDGE, String(rows), String(cols), ...target.argv], {
100
+ cwd: target.cwd,
101
+ stdio: ["pipe", "pipe", "pipe"],
102
+ });
103
+ } catch (e) {
104
+ say(`could not start a terminal: ${e.message}`);
105
+ try { ws.close(); } catch {}
106
+ return null;
107
+ }
108
+
109
+ say(`${target.argv.join(" ")} (${target.cwd})`);
110
+
111
+ child.on("error", (e) => {
112
+ // python3 missing is the realistic case, and it is worth naming: without it
113
+ // there is no pty, and the panel would otherwise just sit there empty.
114
+ say(`terminal unavailable: ${e.message}`);
115
+ try { ws.close(); } catch {}
116
+ });
117
+ child.stdout.on("data", (chunk) => { try { if (ws.readyState === 1) ws.send(chunk); } catch {} });
118
+ child.stderr.on("data", (chunk) => { try { if (ws.readyState === 1) ws.send(chunk); } catch {} });
119
+ child.on("close", (code) => {
120
+ say(`session ended (exit ${code ?? "?"})`);
121
+ try { ws.close(); } catch {}
122
+ });
123
+
124
+ ws.on("message", (raw) => {
125
+ try { child.stdin.write(Buffer.isBuffer(raw) ? raw : Buffer.from(String(raw))); } catch {}
126
+ });
127
+ const stop = () => { try { child.kill("SIGTERM"); } catch {} };
128
+ ws.on("close", stop);
129
+ ws.on("error", stop);
130
+
131
+ return child;
132
+ }
@@ -0,0 +1,87 @@
1
+ // Keeps a self-hosted voice engine's weights resident, the same way
2
+ // whisper-server.js does for transcription.
3
+ //
4
+ // The problem is not loading — the engine reports `load 0.0s` throughout. On a
5
+ // machine short on RAM macOS compresses the model's pages out from under a
6
+ // process that is merely idle, and the next generation pays to decompress
7
+ // several gigabytes before it can emit a single token. Measured on this M4 Pro
8
+ // with Qwen3-TTS: 1.5s after two minutes idle, 24.5s after nine.
9
+ //
10
+ // The desktop already asks for a warm-up when the microphone opens, which is
11
+ // the right idea and not enough on its own: an utterance lasts three seconds
12
+ // and the decompression takes twenty, so the reply's own synthesis queues
13
+ // behind a warm-up that is still running. Paying it on a timer instead means
14
+ // it is never on the path of a turn at all.
15
+ //
16
+ // Only ever pointed at an engine the user runs themselves — see isSelfHosted.
17
+ // A periodic ping at a metered cloud endpoint would quietly bill for silence.
18
+ import { warmupTts } from "#core/voice/tts.js";
19
+ import { resolveTtsCandidates } from "#core/voice/engines/index.js";
20
+ import { readConfig } from "#core/config/index.js";
21
+
22
+ // Nine minutes was cold and two and a half was fine, so the default sits well
23
+ // inside the window rather than close to its edge — the ping is cheap and a
24
+ // missed one costs twenty seconds.
25
+ export const DEFAULT_KEEP_WARM_MINUTES = 3;
26
+
27
+ let _timer = null;
28
+
29
+ /**
30
+ * Whether an engine runs on this machine or the local network, and so costs
31
+ * nothing to poke. Anything reached over the public internet is somebody's
32
+ * metered API, whatever it is nominally called.
33
+ */
34
+ export function isSelfHosted(baseUrl) {
35
+ let host;
36
+ try { host = new URL(String(baseUrl)).hostname.toLowerCase(); } catch { return false; }
37
+ if (host === "localhost" || host.endsWith(".localhost") || host.endsWith(".local")) return true;
38
+ if (host === "::1" || host === "0.0.0.0") return true;
39
+ if (/^127\./.test(host)) return true;
40
+ if (/^10\./.test(host)) return true;
41
+ if (/^192\.168\./.test(host)) return true;
42
+ if (/^172\.(1[6-9]|2\d|3[01])\./.test(host)) return true; // 172.16/12
43
+ return false;
44
+ }
45
+
46
+ /**
47
+ * The engine a keep-warm ping would reach, or null when pinging it would be
48
+ * wrong: nothing configured, no warm-up support, or a remote/metered endpoint.
49
+ */
50
+ export async function keepWarmTarget(globalConfig) {
51
+ const cfg = globalConfig || readConfig() || {};
52
+ const [first] = await resolveTtsCandidates({ globalConfig: cfg });
53
+ if (!first) return null;
54
+ if (typeof first.adapter?.warmup !== "function") return null;
55
+ if (!isSelfHosted(first.engineConfig?.base_url)) return null;
56
+ return first;
57
+ }
58
+
59
+ export async function startTtsKeepWarm(log = console.log) {
60
+ stopTtsKeepWarm();
61
+ try {
62
+ const cfg = readConfig() || {};
63
+ const ttsCfg = cfg?.voice?.tts || {};
64
+ if (ttsCfg.keep_warm === false) return;
65
+ const target = await keepWarmTarget(cfg);
66
+ if (!target) return;
67
+
68
+ const minutes = Number(ttsCfg.keep_warm_minutes ?? DEFAULT_KEEP_WARM_MINUTES) || DEFAULT_KEEP_WARM_MINUTES;
69
+ const everyMs = Math.max(60_000, minutes * 60_000);
70
+ const ping = () => {
71
+ warmupTts({ globalConfig: readConfig() || {} })
72
+ .then((r) => { if (!r.ok) log(`tts: keep-warm failed — ${r.error}`); })
73
+ .catch(() => {});
74
+ };
75
+ ping();
76
+ _timer = setInterval(ping, everyMs);
77
+ _timer.unref?.();
78
+ log(`tts: keep-warm every ${Math.round(everyMs / 60_000)} min (${target.provider})`);
79
+ } catch (e) {
80
+ log(`tts: keep-warm not started — ${e?.message || e}`);
81
+ }
82
+ }
83
+
84
+ export function stopTtsKeepWarm() {
85
+ if (_timer) clearInterval(_timer);
86
+ _timer = null;
87
+ }
@@ -3,6 +3,7 @@ import fetch from "node-fetch";
3
3
  import { readIdentity, writeIdentity } from "#core/identity/index.js";
4
4
  import { resolveProvider, getAdapter } from "#core/engines/index.js";
5
5
  import { canNudge, recordNudge, nudgeFeedbackKeyboard } from "#core/nudge/index.js";
6
+ import { resolveChannels, resolveBotToken, resolveChatId } from "#core/channels/telegram/helpers.js";
6
7
 
7
8
  const WAKEUP_COOLDOWN_MS = 30 * 60 * 1000; // 30 min
8
9
 
@@ -13,7 +14,7 @@ const ISO_TO_LANGUAGE = {
13
14
  };
14
15
 
15
16
  // Exported for unit testing.
16
- // Priority: config.user.language (ISO 639-1) → identity.language (legacy) → system LANG env.
17
+ // Priority: config.user.language (ISO 639-1) → identity.language → system LANG env.
17
18
  export function detectLanguage(identity, config) {
18
19
  const cfgLang = config?.user?.language;
19
20
  if (cfgLang) return ISO_TO_LANGUAGE[cfgLang.toLowerCase()] || cfgLang;
@@ -67,8 +68,12 @@ export async function triggerWakeup(config, log) {
67
68
  const identity = readIdentity();
68
69
  if (!identity) return;
69
70
 
70
- const tg = config.telegram;
71
- if (!tg?.enabled || !tg?.bot_token || !tg?.chat_id) return;
71
+ if (!config?.telegram?.enabled) return;
72
+ const channel = resolveChannels(config)[0];
73
+ if (!channel) return;
74
+ const botToken = resolveBotToken(channel);
75
+ const chatId = resolveChatId(channel);
76
+ if (!botToken || !chatId) return;
72
77
 
73
78
  // Cooldown check
74
79
  if (identity.last_wakeup) {
@@ -91,10 +96,10 @@ export async function triggerWakeup(config, log) {
91
96
  try {
92
97
  const message = await generateMessage(identity, config);
93
98
  const text = message || `${identity.agent_name} online. Ready.`;
94
- await sendTelegram(tg.bot_token, tg.chat_id, text, nudgeFeedbackKeyboard(gate.nudge_id));
95
- recordNudge(gate, { chat_id: tg.chat_id, preview: text });
99
+ await sendTelegram(botToken, chatId, text, nudgeFeedbackKeyboard(gate.nudge_id));
100
+ recordNudge(gate, { chat_id: chatId, preview: text });
96
101
  writeIdentity({ last_wakeup: new Date().toISOString() });
97
- log?.(`wakeup: sent to Telegram chat ${tg.chat_id}`);
102
+ log?.(`wakeup: sent to Telegram chat ${chatId}`);
98
103
  } catch (e) {
99
104
  log?.(`wakeup: failed — ${e.message}`);
100
105
  }
@@ -239,6 +239,50 @@ export async function warmupWhisper() {
239
239
  }
240
240
  }
241
241
 
242
+ // ── Keep-warm ───────────────────────────────────────────────────────────────
243
+ //
244
+ // Loading large-v3-turbo costs ~10s, and it is paid by whoever speaks first
245
+ // after the weights fall out of resident memory. That used to be the user:
246
+ // the desktop window warms on open, but `/warmup` holds the model lock while
247
+ // it loads, so an utterance started seconds later queued behind it — which is
248
+ // exactly the ~11s first-transcription stall in the logs, against ~0.9s for
249
+ // every one after it.
250
+ //
251
+ // The window can't own this, because it is closed most of the day and the model
252
+ // goes cold in between. The daemon can: it pings /warmup on a cycle shorter
253
+ // than the server's idle timeout, so the weights stay hot and the timer stays
254
+ // reset for as long as the daemon is up.
255
+ //
256
+ // Turn it off with transcription.local.keep_warm = false, and the idle watchdog
257
+ // takes over: the server exits after idle_minutes and gives the RAM back, at
258
+ // the cost of a cold first utterance.
259
+ let _keepWarmTimer = null;
260
+
261
+ export function startWhisperKeepWarm(log = console.log) {
262
+ stopWhisperKeepWarm();
263
+ return getConfig().then((cfg) => {
264
+ if (cfg.provider === "openai" || cfg.provider === "custom") return;
265
+ if (cfg.local.keep_warm === false) return;
266
+ const idleMin = Number(cfg.local.idle_minutes ?? DEFAULT_LOCAL.idle_minutes) || 10;
267
+ // Comfortably inside the idle window, and never a busy-loop on a tiny one.
268
+ const everyMs = Math.max(60_000, (idleMin - 2) * 60_000);
269
+ const ping = () => {
270
+ warmupWhisper()
271
+ .then((r) => { if (!r.ok) log(`whisper: keep-warm failed — ${r.error}`); })
272
+ .catch(() => {});
273
+ };
274
+ ping();
275
+ _keepWarmTimer = setInterval(ping, everyMs);
276
+ _keepWarmTimer.unref?.();
277
+ log(`whisper: keep-warm every ${Math.round(everyMs / 60_000)} min (idle timeout ${idleMin} min)`);
278
+ }).catch(() => {});
279
+ }
280
+
281
+ export function stopWhisperKeepWarm() {
282
+ if (_keepWarmTimer) clearInterval(_keepWarmTimer);
283
+ _keepWarmTimer = null;
284
+ }
285
+
242
286
  export async function shutdownWhisperServer() {
243
287
  if (_serverProcess) {
244
288
  try { _serverProcess.kill(); } catch {}