@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
@@ -0,0 +1,156 @@
1
+ // The one-line bubbles the desktop / Android pets show.
2
+ //
3
+ // WHY HERE, NOT IN EACH CLIENT. Desktop Electron and the Android overlay both
4
+ // subscribe to the same /api/events/ws feed. When each one invented its own
5
+ // filter they drifted: both treated the owner's own send (`direction: "in"`)
6
+ // as news, and skipped the thing the pet is for — an agent actually launching
7
+ // its closing message on Telegram, a group, or A2A. One function, attached to
8
+ // the frame as `notifications: string[]`, is what both surfaces render.
9
+ //
10
+ // SIGNAL, NOT DATA. A line names who spoke and where — on A2A, who spoke to
11
+ // whom. It never carries the body. Delivery rows may also bring a bounded
12
+ // `notify` headline the writer already chose (≤100 chars) — still a notice,
13
+ // not the message.
14
+ //
15
+ // EACH LINE CARRIES ITS CHANNEL. The text alone leaves a client with nothing to
16
+ // filter on: the phone has Telegram installed ON it, so an APX bubble about a
17
+ // Telegram reply is the same news twice, while the trip notice on the same
18
+ // phone is the only way that news arrives at all. So a notice is `{ text,
19
+ // channel }` and the surface decides which channels may ring it — the web has
20
+ // done that per device since lib/channels.ts; the APK could not, because what
21
+ // reached it was a bare string.
22
+
23
+ import { SUPERAGENT_ACTOR_ID } from "../constants/actors.js";
24
+ import { resolveAgentName } from "../identity/self.js";
25
+
26
+ const AGENT_FINAL_CHANNELS = new Set(["telegram", "group", "a2a"]);
27
+ const DELIVERY_VIA = new Set(["routine_delivery", "mobility_delivery"]);
28
+
29
+ /**
30
+ * The channels a BUBBLE can be about — not the channels APX speaks on.
31
+ *
32
+ * Five, and the list is closed by construction: three are agent finals
33
+ * (telegram / group / a2a) and two are deliveries that arrive with their own
34
+ * headline. A routine delivery is filed on `web` and a mobility one on
35
+ * telegram, but neither is news *about that channel* — "an errand on the way
36
+ * home" is not a Telegram message, and muting Telegram must not silence the
37
+ * car. So a delivery is tagged by what it IS, the same rule the `log` channel
38
+ * settled on core-side.
39
+ *
40
+ * A client shows this list as the choice; nothing else can ever ring.
41
+ */
42
+ export const NOTICE_CHANNELS = ["telegram", "group", "a2a", "routine", "mobility"];
43
+
44
+ function channelLabel(channel) {
45
+ if (channel === "telegram") return "Telegram";
46
+ if (channel === "group") return "Grupo";
47
+ if (channel === "a2a") return "A2A";
48
+ if (!channel) return "un canal";
49
+ return channel.charAt(0).toUpperCase() + channel.slice(1);
50
+ }
51
+
52
+ function speakerName(event) {
53
+ const author = String(event?.author || "").trim();
54
+ if (author && author !== "user" && author !== "owner" && !author.startsWith("@")) return author;
55
+ return String(event?.agent_slug || "").trim() || "agente";
56
+ }
57
+
58
+ /** A participant's name as a sentence should carry it.
59
+ *
60
+ * The super-agent is filed on the ledger under its ACTOR ID, so a bubble that
61
+ * printed the stored name said "a Super_agent" about the agent the owner calls
62
+ * Roby. An id is what the ledger needs to keep one thread per correspondent;
63
+ * it is not what a sentence about that correspondent says. Everyone else keeps
64
+ * the name they were addressed by — an a2a address is a slug written lowercase
65
+ * (`magui`), and "de magui a roby" reads as a log line rather than as news, so
66
+ * it gets a capital. A name that already carries its own casing (`Roby`,
67
+ * `iOS-bot`) is left exactly as its author wrote it. */
68
+ function peerLabel(name) {
69
+ const n = String(name || "").trim();
70
+ if (n === SUPERAGENT_ACTOR_ID) return resolveAgentName();
71
+ if (!n || n !== n.toLowerCase()) return n;
72
+ return n.charAt(0).toUpperCase() + n.slice(1);
73
+ }
74
+
75
+ /** An agent's closing message on Telegram / group / A2A — not a stream chunk,
76
+ * not a tool row, not the owner's own send, not a delivery that already has
77
+ * its own headline. */
78
+ export function isAgentFinalEvent(event) {
79
+ if (!event || event.direction !== "out") return false;
80
+ if (event.type && event.type !== "agent") return false;
81
+ if (!AGENT_FINAL_CHANNELS.has(event.channel)) return false;
82
+ if (event.streamed === true) return false;
83
+ if (DELIVERY_VIA.has(event.via)) return false;
84
+ return true;
85
+ }
86
+
87
+ /**
88
+ * @param {object[]} events the public events already on a "messages" frame
89
+ * @returns {{text: string, channel: string}[]}
90
+ * one notice per distinct agent×channel (plus any delivery
91
+ * headlines), in a stable order, each tagged with the channel a
92
+ * client filters on. See NOTICE_CHANNELS.
93
+ */
94
+ export function mascotNoticesFromEvents(events) {
95
+ const notices = [];
96
+ const list = Array.isArray(events) ? events : [];
97
+
98
+ for (const event of list) {
99
+ if (event?.via === "mobility_delivery") {
100
+ const notice = String(event.notify || "").trim();
101
+ if (notice) notices.push({ text: notice, channel: "mobility" });
102
+ }
103
+ }
104
+
105
+ const routineByAgent = new Map();
106
+ for (const event of list) {
107
+ if (!event || event.via !== "routine_delivery" || event.channel !== "web") continue;
108
+ if (!event.agent_slug || event.agent_slug === "super_agent") continue;
109
+ routineByAgent.set(event.agent_slug, event.notify || routineByAgent.get(event.agent_slug) || "");
110
+ }
111
+ for (const [agent, notify] of routineByAgent) {
112
+ const notice = String(notify || "").trim();
113
+ notices.push({
114
+ text: notice ? `${agent}: ${notice}` : `${agent} te dejó un mensaje`,
115
+ channel: "routine",
116
+ });
117
+ }
118
+
119
+ const finals = new Map();
120
+ for (const event of list) {
121
+ if (!isAgentFinalEvent(event)) continue;
122
+ const agent = speakerName(event);
123
+ // On A2A the pair IS the news. "martin respondió en A2A" names a channel the
124
+ // owner never opened and leaves out the only thing he wants to know — who
125
+ // reached who. The counterpart rides the event for exactly this line; when
126
+ // it is missing (an older row, a writer that set no `to`) the bubble falls
127
+ // back to naming the channel rather than inventing a recipient.
128
+ const to = event.channel === "a2a" ? String(event.to || "").trim() : "";
129
+ finals.set(`${event.channel}|${agent}|${to}`, { channel: event.channel, agent, to });
130
+ }
131
+ for (const { channel, agent, to } of finals.values()) {
132
+ notices.push({
133
+ text: to
134
+ ? `Nuevo mensaje de ${peerLabel(agent)} a ${peerLabel(to)}`
135
+ : `${agent} respondió en ${channelLabel(channel)}`,
136
+ channel,
137
+ });
138
+ }
139
+
140
+ return notices;
141
+ }
142
+
143
+ /**
144
+ * The same notices as bare lines.
145
+ *
146
+ * Still the frame's `notifications`, because an APK is installed software that
147
+ * updates when its owner gets around to it: a phone carrying last month's build
148
+ * reads this field and must keep working. Desktop reads it too — the pet there
149
+ * has no per-channel question to answer, one screen showing everything is the
150
+ * whole point of it.
151
+ *
152
+ * @returns {string[]}
153
+ */
154
+ export function mascotNotificationsFromEvents(events) {
155
+ return mascotNoticesFromEvents(events).map((notice) => notice.text);
156
+ }
@@ -10,12 +10,13 @@
10
10
  // (no Chromium needed).
11
11
  //
12
12
  // Endpoints (mounted at /api/tools/browser by api.js):
13
- // POST /navigate { url, launch_options?, allow_dangerous? }
14
- // POST /screenshot { selector?, full_page?, width?, height?, encoded? }
15
- // POST /click { selector }
16
- // POST /type { selector, text, clear? }
17
- // POST /select { selector, value }
18
- // POST /hover { selector }
13
+ // POST /navigate { url, launch_options?, allow_dangerous?, snapshot? }
14
+ // POST /snapshot { selector?, interactive_only?, max_nodes? }
15
+ // POST /screenshot { selector?, ref?, full_page?, width?, height?, encoded? }
16
+ // POST /click { selector | ref, snapshot? }
17
+ // POST /type { selector | ref, text, clear?, snapshot? }
18
+ // POST /select { selector | ref, value, snapshot? }
19
+ // POST /hover { selector | ref }
19
20
  // POST /evaluate { code }
20
21
  // POST /get_text { selector? }
21
22
  // POST /get_content { selector? } // raw innerHTML
@@ -35,6 +36,8 @@ const _consoleLogs = [];
35
36
 
36
37
  const MAX_SCREENSHOT_BYTES = 2 * 1024 * 1024; // 2MB
37
38
  const MAX_CONTENT_CHARS = 1 * 1024 * 1024; // 1MB
39
+ const MAX_SNAPSHOT_NODES = 400;
40
+ const MAX_SNAPSHOT_CHARS = 40 * 1024;
38
41
 
39
42
  // Args we always pass for stability + reduced attack surface.
40
43
  const SECURITY_ARGS = [
@@ -228,11 +231,328 @@ async function onPage(fn) {
228
231
  return withContextRetry(() => fn(page));
229
232
  }
230
233
 
234
+ // ---------------------------------------------------------------------------
235
+ // Accessibility snapshot + refs
236
+ // ---------------------------------------------------------------------------
237
+ //
238
+ // Why this exists. A model driving Puppeteer by CSS selector has to invent the
239
+ // selector out of browser_get_content's raw HTML — a megabyte of markup to find
240
+ // one button, and a wrong guess most of the time. Snapshot walks the RENDERED
241
+ // DOM instead and returns what a screen reader would announce: role, accessible
242
+ // name, state, one line per element, with every control stamped `ref_N`. The
243
+ // action tools take `{ ref }`, so the model clicks what it read rather than
244
+ // what it inferred.
245
+ //
246
+ // Refs live in the page as `data-apx-ref` attributes and die with it. A
247
+ // navigation or a re-render invalidates them; the action tools then say so by
248
+ // name instead of failing on a mystery selector.
249
+
250
+ // Runs INSIDE the page — must stay self-contained (page.evaluate stringifies
251
+ // it, so it can close over nothing from this module).
252
+ function collectA11yNodes({ rootSelector, interactiveOnly, maxNodes }) {
253
+ const SKIP_TAGS = new Set(["SCRIPT", "STYLE", "NOSCRIPT", "TEMPLATE", "HEAD", "SVG", "PATH", "IFRAME"]);
254
+ // Controls whose subtree the walk does not enter: their accessible name
255
+ // already carries the inner text, so descending only duplicates it.
256
+ const LEAF_TAGS = new Set(["A", "BUTTON", "INPUT", "SELECT", "TEXTAREA", "SUMMARY"]);
257
+ const INTERACTIVE_ROLES = new Set([
258
+ "button", "link", "checkbox", "radio", "tab", "menuitem", "menuitemcheckbox",
259
+ "menuitemradio", "option", "switch", "combobox", "textbox", "searchbox",
260
+ "slider", "spinbutton", "treeitem",
261
+ ]);
262
+ const TAG_ROLES = {
263
+ A: "link", BUTTON: "button", SELECT: "combobox", TEXTAREA: "textbox",
264
+ SUMMARY: "button", LABEL: "label", IMG: "img", FORM: "form", NAV: "navigation",
265
+ MAIN: "main", HEADER: "banner", FOOTER: "contentinfo", ASIDE: "complementary",
266
+ DIALOG: "dialog", TABLE: "table", TR: "row", ARTICLE: "article",
267
+ H1: "heading", H2: "heading", H3: "heading", H4: "heading", H5: "heading", H6: "heading",
268
+ };
269
+ // Emitted without a ref: they carry no action, they carry the grouping that
270
+ // tells one "Delete" apart from the next.
271
+ const LANDMARK_ROLES = new Set([
272
+ "navigation", "main", "banner", "contentinfo", "complementary", "dialog",
273
+ "form", "search", "region", "article", "table", "row", "tablist",
274
+ ]);
275
+
276
+ const nodes = [];
277
+ let refSeq = 0;
278
+ let truncated = false;
279
+
280
+ // A fresh snapshot retires the previous generation of refs, so a stale ref
281
+ // can never silently resolve to a different element after a re-render.
282
+ for (const el of document.querySelectorAll("[data-apx-ref]")) el.removeAttribute("data-apx-ref");
283
+
284
+ const root = rootSelector ? document.querySelector(rootSelector) : document.body;
285
+ if (!root) return { error: `Element not found: ${rootSelector}` };
286
+
287
+ const squash = (t, cap) => {
288
+ const v = String(t || "").replace(/\s+/g, " ").trim();
289
+ return v.length > cap ? v.slice(0, cap) + "…" : v;
290
+ };
291
+
292
+ function roleOf(el) {
293
+ const explicit = (el.getAttribute("role") || "").trim().toLowerCase();
294
+ if (explicit) return explicit.split(/\s+/)[0];
295
+ const tag = el.tagName;
296
+ if (tag === "INPUT") {
297
+ const t = (el.getAttribute("type") || "text").toLowerCase();
298
+ if (t === "checkbox") return "checkbox";
299
+ if (t === "radio") return "radio";
300
+ if (t === "submit" || t === "button" || t === "reset" || t === "image") return "button";
301
+ if (t === "range") return "slider";
302
+ if (t === "number") return "spinbutton";
303
+ if (t === "search") return "searchbox";
304
+ return "textbox";
305
+ }
306
+ if (tag === "A") return el.hasAttribute("href") ? "link" : "";
307
+ return TAG_ROLES[tag] || "";
308
+ }
309
+
310
+ function visible(el) {
311
+ if (el.hasAttribute("hidden")) return false;
312
+ if (el.getAttribute("aria-hidden") === "true") return false;
313
+ if (el.tagName === "INPUT" && (el.getAttribute("type") || "").toLowerCase() === "hidden") return false;
314
+ if (!el.getClientRects().length) return false;
315
+ const cs = getComputedStyle(el);
316
+ return !(cs.visibility === "hidden" || cs.display === "none" || cs.opacity === "0");
317
+ }
318
+
319
+ function nameOf(el) {
320
+ const aria = el.getAttribute("aria-label");
321
+ if (aria && aria.trim()) return squash(aria, 120);
322
+ const by = el.getAttribute("aria-labelledby");
323
+ if (by) {
324
+ const joined = by.split(/\s+/)
325
+ .map((id) => document.getElementById(id))
326
+ .filter(Boolean)
327
+ .map((n) => squash(n.innerText || n.textContent, 80))
328
+ .join(" ");
329
+ if (joined.trim()) return squash(joined, 120);
330
+ }
331
+ if (el.tagName === "IMG") return squash(el.getAttribute("alt"), 120);
332
+ if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.tagName === "SELECT") {
333
+ if (el.labels && el.labels.length) {
334
+ const l = squash(el.labels[0].innerText || el.labels[0].textContent, 80);
335
+ if (l) return l;
336
+ }
337
+ return squash(
338
+ el.getAttribute("placeholder") || el.getAttribute("title") || el.getAttribute("name"),
339
+ 120
340
+ );
341
+ }
342
+ return squash(el.innerText || el.textContent, 120) || squash(el.getAttribute("title"), 120);
343
+ }
344
+
345
+ function isInteractive(el, role) {
346
+ const tag = el.tagName;
347
+ if (tag === "A") return el.hasAttribute("href");
348
+ if (LEAF_TAGS.has(tag)) return true;
349
+ if (el.isContentEditable) return true;
350
+ if (INTERACTIVE_ROLES.has(role)) return true;
351
+ const ti = el.getAttribute("tabindex");
352
+ if (ti !== null && ti !== "-1") return true;
353
+ return el.hasAttribute("onclick");
354
+ }
355
+
356
+ // Text owned by THIS element (its direct text-node children), so each run of
357
+ // page copy is attributed to exactly one node and never repeated up the tree.
358
+ function directText(el) {
359
+ let out = "";
360
+ for (const n of el.childNodes) if (n.nodeType === 3) out += n.nodeValue;
361
+ return squash(out, 300);
362
+ }
363
+
364
+ function walk(el, depth, parentName) {
365
+ if (nodes.length >= maxNodes) { truncated = true; return; }
366
+ if (SKIP_TAGS.has(el.tagName)) return;
367
+ if (!visible(el)) return;
368
+
369
+ const role = roleOf(el);
370
+ const interactive = isInteractive(el, role);
371
+ let emitted = false;
372
+ let ownName = parentName;
373
+
374
+ if (interactive) {
375
+ const ref = `ref_${++refSeq}`;
376
+ el.setAttribute("data-apx-ref", ref);
377
+ const name = nameOf(el);
378
+ const node = { depth, ref, role: role || "generic", name };
379
+ const type = el.tagName === "INPUT" ? (el.getAttribute("type") || "text").toLowerCase() : null;
380
+ if (type && type !== "text") node.type = type;
381
+ if (el.tagName === "A") {
382
+ const href = el.getAttribute("href");
383
+ if (href) node.href = squash(href, 120);
384
+ }
385
+ // A password field's value is never worth echoing back into a transcript.
386
+ const stateOnly = type === "checkbox" || type === "radio";
387
+ if (!stateOnly && type !== "password" && (el.tagName === "INPUT" || el.tagName === "TEXTAREA") && el.value) {
388
+ node.value = squash(el.value, 60);
389
+ }
390
+ if (el.tagName === "SELECT" && el.value) node.value = squash(el.value, 60);
391
+ if (el.checked) node.checked = true;
392
+ if (el.disabled || el.getAttribute("aria-disabled") === "true") node.disabled = true;
393
+ if (el.required) node.required = true;
394
+ const expanded = el.getAttribute("aria-expanded");
395
+ if (expanded !== null) node.expanded = expanded === "true";
396
+ if (el.getAttribute("aria-selected") === "true") node.selected = true;
397
+ nodes.push(node);
398
+ emitted = true;
399
+ ownName = name;
400
+ } else if (!interactiveOnly && LANDMARK_ROLES.has(role)) {
401
+ const label = squash(el.getAttribute("aria-label"), 80);
402
+ nodes.push(label ? { depth, role, name: label } : { depth, role });
403
+ emitted = true;
404
+ } else if (!interactiveOnly && role === "heading") {
405
+ const level = /^H[1-6]$/.test(el.tagName)
406
+ ? Number(el.tagName[1])
407
+ : Number(el.getAttribute("aria-level")) || null;
408
+ const name = squash(el.innerText || el.textContent, 160);
409
+ const node = { depth, role: "heading", name };
410
+ if (level) node.level = level;
411
+ nodes.push(node);
412
+ emitted = true;
413
+ ownName = name;
414
+ }
415
+
416
+ if (!interactiveOnly && !(el.tagName === "LABEL" && el.control)) {
417
+ const own = directText(el);
418
+ // Skip copy already spoken by the control that encloses it.
419
+ if (own && own.length > 1 && own !== ownName && own !== parentName) {
420
+ if (nodes.length >= maxNodes) truncated = true;
421
+ else nodes.push({ depth: emitted ? depth + 1 : depth, role: "text", name: own });
422
+ }
423
+ }
424
+
425
+ if (LEAF_TAGS.has(el.tagName)) return;
426
+ const childDepth = emitted ? depth + 1 : depth;
427
+ for (const child of el.children) walk(child, childDepth, ownName);
428
+ }
429
+
430
+ walk(root, 0, "");
431
+ return { url: location.href, title: document.title, nodes, truncated };
432
+ }
433
+
434
+ /**
435
+ * A structural node with no name and no children says nothing — layout tables
436
+ * alone can emit dozens of them. Drop it: a node is empty when the next node is
437
+ * not deeper than it is.
438
+ */
439
+ export function pruneEmptyContainers(nodes) {
440
+ const list = nodes || [];
441
+ return list.filter((n, i) => {
442
+ if (n.ref || n.name) return true;
443
+ const next = list[i + 1];
444
+ return !!next && (Number(next.depth) || 0) > (Number(n.depth) || 0);
445
+ });
446
+ }
447
+
448
+ /** Render collected nodes as the indented, screen-reader-shaped text the model reads. */
449
+ export function renderSnapshot(nodes, { maxChars = MAX_SNAPSHOT_CHARS } = {}) {
450
+ const lines = [];
451
+ let chars = 0;
452
+ let clipped = 0;
453
+ for (const n of pruneEmptyContainers(nodes)) {
454
+ const pad = " ".repeat(Math.max(0, Math.min(Number(n.depth) || 0, 12)));
455
+ let line = `${pad}- ${n.role || "generic"}`;
456
+ if (n.name) line += ` ${JSON.stringify(n.name)}`;
457
+ if (n.ref) line += ` [${n.ref}]`;
458
+ const meta = [];
459
+ if (n.level) meta.push(`level=${n.level}`);
460
+ if (n.type) meta.push(`type=${n.type}`);
461
+ if (n.href) meta.push(`href=${n.href}`);
462
+ if (n.value) meta.push(`value=${JSON.stringify(n.value)}`);
463
+ if (n.checked) meta.push("checked");
464
+ if (n.selected) meta.push("selected");
465
+ if (n.expanded !== undefined) meta.push(`expanded=${n.expanded}`);
466
+ if (n.disabled) meta.push("disabled");
467
+ if (n.required) meta.push("required");
468
+ if (meta.length) line += ` {${meta.join(" ")}}`;
469
+ if (chars + line.length + 1 > maxChars) { clipped++; continue; }
470
+ chars += line.length + 1;
471
+ lines.push(line);
472
+ }
473
+ if (clipped) lines.push(`…(${clipped} more nodes omitted — narrow with selector or interactive_only)`);
474
+ return lines.join("\n");
475
+ }
476
+
477
+ /**
478
+ * The CSS selector an action tool should act on, from either addressing mode.
479
+ * `ref` wins when both are given; neither is an error the model can fix.
480
+ */
481
+ export function resolveTarget({ ref, selector } = {}) {
482
+ if (ref !== undefined && ref !== null && String(ref).trim() !== "") {
483
+ const id = String(ref).trim();
484
+ if (!/^ref_\d+$/.test(id)) {
485
+ throw new Error(`invalid ref "${ref}" — refs look like "ref_12" and come from browser_snapshot`);
486
+ }
487
+ return `[data-apx-ref="${id}"]`;
488
+ }
489
+ if (selector !== undefined && selector !== null && String(selector).trim() !== "") {
490
+ return String(selector);
491
+ }
492
+ return null;
493
+ }
494
+
495
+ function requireTarget({ ref, selector }) {
496
+ const target = resolveTarget({ ref, selector });
497
+ if (!target) throw new Error("ref or selector required — call browser_snapshot first and act on a ref");
498
+ return target;
499
+ }
500
+
501
+ // Wait for the element, translating a missing ref into the one instruction
502
+ // that actually unblocks the model: take a new snapshot.
503
+ async function waitForTarget(page, target, ref, timeout = 10000) {
504
+ try {
505
+ await page.waitForSelector(target, { timeout });
506
+ } catch (e) {
507
+ if (ref) {
508
+ throw new Error(
509
+ `${ref} is no longer on the page — the DOM changed since the last browser_snapshot. ` +
510
+ `Call browser_snapshot again and use a fresh ref.`
511
+ );
512
+ }
513
+ throw e;
514
+ }
515
+ }
516
+
517
+ // Actions accept `snapshot: true` to return the post-action page state in the
518
+ // same round trip, which is what keeps a multi-step flow from costing one extra
519
+ // tool call per click.
520
+ async function maybeSnapshot(want) {
521
+ if (!want) return undefined;
522
+ try {
523
+ const s = await browser_snapshot();
524
+ return s.snapshot;
525
+ } catch {
526
+ return undefined;
527
+ }
528
+ }
529
+
530
+ export async function browser_snapshot({ selector, interactive_only = false, max_nodes } = {}) {
531
+ return onPage(async (page) => {
532
+ const cap = Math.min(Number(max_nodes) || MAX_SNAPSHOT_NODES, 1500);
533
+ const res = await page.evaluate(collectA11yNodes, {
534
+ rootSelector: selector ?? null,
535
+ interactiveOnly: !!interactive_only,
536
+ maxNodes: cap,
537
+ });
538
+ if (res?.error) throw new Error(res.error);
539
+ const snapshot = renderSnapshot(res.nodes);
540
+ return {
541
+ ok: true,
542
+ url: res.url,
543
+ title: res.title,
544
+ nodes: res.nodes.length,
545
+ truncated: !!res.truncated,
546
+ snapshot,
547
+ };
548
+ });
549
+ }
550
+
231
551
  // ---------------------------------------------------------------------------
232
552
  // Tool implementations
233
553
  // ---------------------------------------------------------------------------
234
554
 
235
- export async function browser_navigate({ url, launch_options, allow_dangerous, wait_until } = {}) {
555
+ export async function browser_navigate({ url, launch_options, allow_dangerous, wait_until, snapshot } = {}) {
236
556
  if (!url) throw new Error("url required");
237
557
  const page = await ensureBrowser({ launch_options, allow_dangerous });
238
558
 
@@ -272,16 +592,19 @@ export async function browser_navigate({ url, launch_options, allow_dangerous, w
272
592
  title = "";
273
593
  }
274
594
 
595
+ const snap = await maybeSnapshot(snapshot);
275
596
  return {
276
597
  ok: true,
277
598
  url: page.url(),
278
599
  status: response?.status() ?? null,
279
600
  title,
280
601
  wait_until: response ? (preferred) : null,
602
+ ...(snap === undefined ? {} : { snapshot: snap }),
281
603
  };
282
604
  }
283
605
 
284
- export async function browser_screenshot({ selector, full_page = false, width, height, encoded = false, save_path, save_to_tmp = false } = {}) {
606
+ export async function browser_screenshot({ selector, ref, full_page = false, width, height, encoded = false, save_path, save_to_tmp = false } = {}) {
607
+ const target = resolveTarget({ ref, selector });
285
608
  const page = await ensureBrowser();
286
609
  if (width || height) {
287
610
  await page.setViewport({
@@ -291,10 +614,10 @@ export async function browser_screenshot({ selector, full_page = false, width, h
291
614
  }
292
615
 
293
616
  const buf = await withContextRetry(async () => {
294
- const target = selector ? await page.$(selector) : null;
295
- if (selector && !target) throw new Error(`Element not found: ${selector}`);
296
- return target
297
- ? await target.screenshot({ type: "png", encoding: "base64" })
617
+ const handle = target ? await page.$(target) : null;
618
+ if (target && !handle) throw new Error(`Element not found: ${ref || selector}`);
619
+ return handle
620
+ ? await handle.screenshot({ type: "png", encoding: "base64" })
298
621
  : await page.screenshot({ type: "png", encoding: "base64", fullPage: !!full_page });
299
622
  });
300
623
 
@@ -331,49 +654,55 @@ export async function browser_screenshot({ selector, full_page = false, width, h
331
654
  };
332
655
  }
333
656
 
334
- export async function browser_click({ selector } = {}) {
335
- if (!selector) throw new Error("selector required");
336
- return onPage(async (page) => {
337
- await page.waitForSelector(selector, { timeout: 10000 });
338
- await page.click(selector);
657
+ export async function browser_click({ selector, ref, snapshot } = {}) {
658
+ const target = requireTarget({ ref, selector });
659
+ const res = await onPage(async (page) => {
660
+ await waitForTarget(page, target, ref);
661
+ await page.click(target);
339
662
  await page.waitForNetworkIdle({ timeout: 5000 }).catch(() => {});
340
- return { ok: true, selector, url: page.url() };
663
+ return { ok: true, ref: ref ?? null, selector: selector ?? null, url: page.url() };
341
664
  });
665
+ const snap = await maybeSnapshot(snapshot);
666
+ return snap === undefined ? res : { ...res, snapshot: snap };
342
667
  }
343
668
 
344
- export async function browser_type({ selector, text, clear = true } = {}) {
345
- if (!selector) throw new Error("selector required");
669
+ export async function browser_type({ selector, ref, text, clear = true, snapshot } = {}) {
670
+ const target = requireTarget({ ref, selector });
346
671
  if (text === undefined) throw new Error("text required");
347
- return onPage(async (page) => {
348
- await page.waitForSelector(selector, { timeout: 10000 });
349
- await page.focus(selector);
672
+ const res = await onPage(async (page) => {
673
+ await waitForTarget(page, target, ref);
674
+ await page.focus(target);
350
675
  if (clear) {
351
676
  await page.keyboard.down("Control");
352
677
  await page.keyboard.press("KeyA");
353
678
  await page.keyboard.up("Control");
354
679
  await page.keyboard.press("Backspace");
355
680
  }
356
- await page.type(selector, String(text), { delay: 20 });
357
- return { ok: true, selector, typed: String(text).length };
681
+ await page.type(target, String(text), { delay: 20 });
682
+ return { ok: true, ref: ref ?? null, selector: selector ?? null, typed: String(text).length };
358
683
  });
684
+ const snap = await maybeSnapshot(snapshot);
685
+ return snap === undefined ? res : { ...res, snapshot: snap };
359
686
  }
360
687
 
361
- export async function browser_select({ selector, value } = {}) {
362
- if (!selector) throw new Error("selector required");
688
+ export async function browser_select({ selector, ref, value, snapshot } = {}) {
689
+ const target = requireTarget({ ref, selector });
363
690
  if (value === undefined) throw new Error("value required");
364
- return onPage(async (page) => {
365
- await page.waitForSelector(selector, { timeout: 10000 });
366
- await page.select(selector, String(value));
367
- return { ok: true, selector, value };
691
+ const res = await onPage(async (page) => {
692
+ await waitForTarget(page, target, ref);
693
+ await page.select(target, String(value));
694
+ return { ok: true, ref: ref ?? null, selector: selector ?? null, value };
368
695
  });
696
+ const snap = await maybeSnapshot(snapshot);
697
+ return snap === undefined ? res : { ...res, snapshot: snap };
369
698
  }
370
699
 
371
- export async function browser_hover({ selector } = {}) {
372
- if (!selector) throw new Error("selector required");
700
+ export async function browser_hover({ selector, ref } = {}) {
701
+ const target = requireTarget({ ref, selector });
373
702
  return onPage(async (page) => {
374
- await page.waitForSelector(selector, { timeout: 10000 });
375
- await page.hover(selector);
376
- return { ok: true, selector };
703
+ await waitForTarget(page, target, ref);
704
+ await page.hover(target);
705
+ return { ok: true, ref: ref ?? null, selector: selector ?? null };
377
706
  });
378
707
  }
379
708
 
@@ -511,6 +840,7 @@ export function buildBrowserRouter(express) {
511
840
  };
512
841
 
513
842
  router.post("/navigate", wrap(browser_navigate));
843
+ router.post("/snapshot", wrap(browser_snapshot));
514
844
  router.post("/screenshot", wrap(browser_screenshot));
515
845
  router.post("/click", wrap(browser_click));
516
846
  router.post("/type", wrap(browser_type));