@agentprojectcontext/apx 1.80.2 → 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 +134 -0
  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
@@ -8,16 +8,21 @@
8
8
  // + register it in PLUGIN_SERVICES (open/closed) — no API/route changes.
9
9
  //
10
10
  // Scope of this catalog (per product decision): Asana, GitHub, Obsidian,
11
- // WhatsApp. Telegram is intentionally absent — it's a channel, configured under
12
- // its own surface, not a service plugin. Transcription lives with the desktop
13
- // STT stack. Obsidian is path-based (a local Vault) rather than token-based.
11
+ // Calendar, WhatsApp. Telegram is intentionally absent — it's a channel,
12
+ // configured under its own surface, not a service plugin. Transcription lives
13
+ // with the desktop STT stack. Obsidian is path-based (a local Vault) rather than
14
+ // token-based, and Calendar is user-OAuth-based (auth: "oauth") — see
15
+ // plugins/calendar.js for why it acts as you (invites + Meet) instead of as a
16
+ // service account.
14
17
  import { asanaPlugin } from "./plugins/asana.js";
18
+ import { calendarPlugin } from "./plugins/calendar.js";
15
19
  import { githubPlugin } from "./plugins/github.js";
16
20
  import { obsidianPlugin } from "./plugins/obsidian.js";
17
21
 
18
22
  // slug -> live plugin service (must implement the lifecycle contract).
19
23
  export const PLUGIN_SERVICES = Object.freeze({
20
24
  asana: asanaPlugin,
25
+ calendar: calendarPlugin,
21
26
  github: githubPlugin,
22
27
  obsidian: obsidianPlugin,
23
28
  });
@@ -0,0 +1,179 @@
1
+ // Google OAuth2 for user-delegated integrations (Calendar today).
2
+ //
3
+ // Why this exists — and why it replaced the service account:
4
+ //
5
+ // A service account acts as ITSELF. It can read a shared calendar and create
6
+ // events on it, but Google blocks it from inviting other people or minting a
7
+ // Meet link unless the whole account lives inside a Google Workspace domain
8
+ // with Domain-Wide Delegation — a thing a personal @gmail.com simply does not
9
+ // have. So "agendá una reunión con Carlos y mandale el Meet" was impossible.
10
+ //
11
+ // User OAuth acts AS YOU. You consent once in the browser, Google hands back a
12
+ // refresh token, and from then on APX creates events, sends invitations, and
13
+ // creates Meet links on your own calendar — because it is you doing it. The
14
+ // price is a one-time OAuth client (client_id + secret) created in Google Cloud
15
+ // Console, and that is the only console step left: no key file, no manual
16
+ // calendar sharing, no Workspace.
17
+ //
18
+ // The flow: build a consent URL → the browser round-trips → Google redirects to
19
+ // our callback with a `code` → we exchange it for a refresh token → we cache
20
+ // short-lived access tokens in memory and refresh them as needed. ~1 file of
21
+ // node:crypto + fetch, no Google SDK.
22
+ import crypto from "node:crypto";
23
+
24
+ export const AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
25
+ export const TOKEN_URL = "https://oauth2.googleapis.com/token";
26
+
27
+ // The path Google redirects the browser back to. Kept scope/project-agnostic —
28
+ // everything the callback needs travels in the signed `state`, so ONE redirect
29
+ // URI is registered in the console and never changes. Mounted under /api by the
30
+ // daemon (see api/prefix.js), so the full URL is `<origin>/api/integrations/oauth/callback`.
31
+ export const CALLBACK_PATH = "/api/integrations/oauth/callback";
32
+
33
+ /** The redirect URI to register in the console and to send on every exchange. */
34
+ export function callbackUrl(origin) {
35
+ return `${String(origin || "").replace(/\/$/, "")}${CALLBACK_PATH}`;
36
+ }
37
+
38
+ // ─── state: signed, so the unauthenticated callback can't be forged ──────────
39
+ //
40
+ // The callback bypasses bearer auth (Google's browser redirect carries no
41
+ // token), so anyone could hit it. We defend it by signing the `state` we put in
42
+ // the consent URL with a per-process key: a callback whose state doesn't verify
43
+ // is rejected. The key is ephemeral on purpose — a daemon restart invalidates
44
+ // any consent link older than one boot, which is fine for a 10-minute flow.
45
+ const STATE_KEY = crypto.randomBytes(32);
46
+ const STATE_TTL_MS = 10 * 60_000;
47
+
48
+ const b64url = (buf) =>
49
+ Buffer.from(buf).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
50
+ const b64urlJson = (obj) => b64url(JSON.stringify(obj));
51
+ const fromB64url = (s) => Buffer.from(s.replace(/-/g, "+").replace(/_/g, "/"), "base64");
52
+
53
+ /** Sign a small state payload (slug, pid, scope, origin) into an opaque token. */
54
+ export function signState(payload) {
55
+ const body = b64urlJson({ ...payload, exp: Date.now() + STATE_TTL_MS });
56
+ const sig = b64url(crypto.createHmac("sha256", STATE_KEY).update(body).digest());
57
+ return `${body}.${sig}`;
58
+ }
59
+
60
+ /** Verify + decode a state token, or return null if forged/expired/malformed. */
61
+ export function verifyState(token) {
62
+ const [body, sig] = String(token || "").split(".");
63
+ if (!body || !sig) return null;
64
+ const expected = b64url(crypto.createHmac("sha256", STATE_KEY).update(body).digest());
65
+ // Constant-time compare — the lengths match by construction (same HMAC).
66
+ if (sig.length !== expected.length || !crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
67
+ return null;
68
+ }
69
+ let data;
70
+ try {
71
+ data = JSON.parse(fromB64url(body).toString("utf8"));
72
+ } catch {
73
+ return null;
74
+ }
75
+ if (!data || typeof data.exp !== "number" || data.exp < Date.now()) return null;
76
+ return data;
77
+ }
78
+
79
+ // ─── consent URL ─────────────────────────────────────────────────────────────
80
+
81
+ /**
82
+ * The URL to send the browser to. `access_type=offline` + `prompt=consent`
83
+ * guarantee a refresh token comes back every time (Google omits it on repeat
84
+ * consents otherwise, which would silently break reconnects).
85
+ */
86
+ export function buildAuthUrl({ clientId, redirectUri, scope, state }) {
87
+ const u = new URL(AUTH_URL);
88
+ u.searchParams.set("client_id", clientId);
89
+ u.searchParams.set("redirect_uri", redirectUri);
90
+ u.searchParams.set("response_type", "code");
91
+ u.searchParams.set("scope", scope);
92
+ u.searchParams.set("access_type", "offline");
93
+ u.searchParams.set("prompt", "consent");
94
+ u.searchParams.set("include_granted_scopes", "true");
95
+ u.searchParams.set("state", state);
96
+ return u.toString();
97
+ }
98
+
99
+ // ─── token exchange + refresh ────────────────────────────────────────────────
100
+
101
+ async function tokenRequest(params, { fetchImpl = fetch } = {}) {
102
+ const res = await fetchImpl(TOKEN_URL, {
103
+ method: "POST",
104
+ headers: { "content-type": "application/x-www-form-urlencoded" },
105
+ body: new URLSearchParams(params).toString(),
106
+ });
107
+ const data = await res.json().catch(() => ({}));
108
+ if (!res.ok) {
109
+ const detail = data.error_description || data.error || `HTTP ${res.status}`;
110
+ throw new Error(`Google rechazó el intercambio de token: ${detail}`);
111
+ }
112
+ return data;
113
+ }
114
+
115
+ /** First exchange: authorization code → { refresh_token, access_token, email }. */
116
+ export async function exchangeCode({ clientId, clientSecret, code, redirectUri }, opts = {}) {
117
+ const data = await tokenRequest(
118
+ {
119
+ grant_type: "authorization_code",
120
+ code,
121
+ client_id: clientId,
122
+ client_secret: clientSecret,
123
+ redirect_uri: redirectUri,
124
+ },
125
+ opts,
126
+ );
127
+ if (!data.refresh_token) {
128
+ throw new Error(
129
+ "Google no devolvió un refresh token. Revocá el acceso de APX en myaccount.google.com/permissions y volvé a conectar (el flujo fuerza el consentimiento).",
130
+ );
131
+ }
132
+ return {
133
+ refresh_token: data.refresh_token,
134
+ access_token: data.access_token || null,
135
+ expires_in: Number(data.expires_in) || 3600,
136
+ email: emailFromIdToken(data.id_token),
137
+ };
138
+ }
139
+
140
+ // Access tokens last an hour and cost a round-trip; cache in memory keyed by the
141
+ // refresh token, so several tool calls in one turn don't each re-mint one.
142
+ const accessCache = new Map();
143
+
144
+ export function clearAccessCache() {
145
+ accessCache.clear();
146
+ }
147
+
148
+ /** A valid access token for a refresh token, minted or served from cache. */
149
+ export async function accessTokenFor({ clientId, clientSecret, refreshToken }, opts = {}) {
150
+ const hit = accessCache.get(refreshToken);
151
+ if (hit && hit.expires_at - 60_000 > Date.now()) return hit.access_token;
152
+ const data = await tokenRequest(
153
+ {
154
+ grant_type: "refresh_token",
155
+ refresh_token: refreshToken,
156
+ client_id: clientId,
157
+ client_secret: clientSecret,
158
+ },
159
+ opts,
160
+ );
161
+ if (!data.access_token) throw new Error("Google no devolvió un access token al refrescar.");
162
+ accessCache.set(refreshToken, {
163
+ access_token: data.access_token,
164
+ expires_at: Date.now() + (Number(data.expires_in) || 3600) * 1000,
165
+ });
166
+ return data.access_token;
167
+ }
168
+
169
+ /** Best-effort account email, decoded from the id_token payload (no verify). */
170
+ export function emailFromIdToken(idToken) {
171
+ const seg = String(idToken || "").split(".")[1];
172
+ if (!seg) return null;
173
+ try {
174
+ const claims = JSON.parse(fromB64url(seg).toString("utf8"));
175
+ return claims.email || null;
176
+ } catch {
177
+ return null;
178
+ }
179
+ }
@@ -93,21 +93,25 @@ export async function listProjects(token, workspaceGid) {
93
93
  export async function listTasks(token, projectGid, completed = false) {
94
94
  const result = await request(token, "GET", `/projects/${projectGid}/tasks`, {
95
95
  params: {
96
- opt_fields: "gid,name,completed,due_on,assignee.name,notes,permalink_url",
96
+ opt_fields: "gid,name,completed,due_on,assignee.name,notes,permalink_url,memberships.section.name,memberships.section.gid",
97
97
  completed_since: completed ? "" : "now",
98
98
  },
99
99
  });
100
100
  return result?.data || [];
101
101
  }
102
102
 
103
- export async function createTask(token, { workspaceGid, name, notes = "", projectGid, assignee, dueOn } = {}) {
103
+ export async function createTask(token, { workspaceGid, name, notes = "", projectGid, sectionGid, assignee, dueOn } = {}) {
104
104
  const payload = { name, workspace: workspaceGid };
105
105
  if (notes) payload.notes = notes;
106
106
  if (projectGid) payload.projects = [projectGid];
107
107
  if (assignee) payload.assignee = assignee;
108
108
  if (dueOn) payload.due_on = dueOn;
109
109
  const result = await request(token, "POST", "/tasks", { payload });
110
- return result?.data || {};
110
+ const task = result?.data || {};
111
+ if (sectionGid && task.gid) {
112
+ await request(token, "POST", `/sections/${sectionGid}/addTask`, { payload: { task: task.gid } });
113
+ }
114
+ return task;
111
115
  }
112
116
 
113
117
  export async function updateTask(token, taskGid, { name, notes, completed, dueOn, assignee } = {}) {
@@ -0,0 +1,404 @@
1
+ // Google Calendar integration plugin — user OAuth, so an agent can act AS you.
2
+ //
3
+ // This plugin used to authenticate with a service account: paste a JSON key,
4
+ // share your calendar with a robot email, done. It worked for reading and for
5
+ // creating plain events, but a service account acts as ITSELF, and Google bars
6
+ // it from inviting other people or creating a Meet link without Domain-Wide
7
+ // Delegation — a Workspace feature a personal @gmail.com does not have. So
8
+ // "agendá con Carlos y mandale el Meet" was simply impossible.
9
+ //
10
+ // User OAuth acts as YOU. You consent once in the browser and Google hands back
11
+ // a refresh token; from then on APX reads your agenda, creates and moves events,
12
+ // SENDS INVITATIONS, and creates Meet links — because it is you doing it, on your
13
+ // own calendar. The only setup left is a one-time OAuth client in Google Cloud
14
+ // Console (client_id + secret). No key file, no calendar sharing, no Workspace.
15
+ //
16
+ // The OAuth mechanics (consent URL, code exchange, refresh, state signing) live
17
+ // in ./_google-oauth.js. This file is the calendar REST client + the plugin
18
+ // lifecycle the daemon and web panel drive.
19
+ import crypto from "node:crypto";
20
+ import {
21
+ buildAuthUrl,
22
+ callbackUrl,
23
+ signState,
24
+ exchangeCode,
25
+ accessTokenFor,
26
+ } from "./_google-oauth.js";
27
+
28
+ const API = "https://www.googleapis.com/calendar/v3";
29
+
30
+ // Full calendar when the owner allows writes (create/move events, invite people,
31
+ // mint Meet links, free/busy); read-only otherwise. `openid email` rides along
32
+ // so we can show which account is connected. Kept broad-but-standard on purpose:
33
+ // narrower per-feature scopes make invites and free/busy fragile for no real gain
34
+ // on a single-user tool.
35
+ export const SCOPE_READ = "openid email https://www.googleapis.com/auth/calendar.readonly";
36
+ export const SCOPE_WRITE = "openid email https://www.googleapis.com/auth/calendar";
37
+
38
+ function scopeFor(config) {
39
+ return config?.write_access ? SCOPE_WRITE : SCOPE_READ;
40
+ }
41
+
42
+ // ─── access tokens ────────────────────────────────────────────────────────────
43
+
44
+ /** A live access token for the stored connection, or a clear error. */
45
+ export async function getAccessToken(config = {}, opts = {}) {
46
+ const { client_id, client_secret, refresh_token } = config || {};
47
+ if (!client_id || !client_secret) {
48
+ throw new Error("Falta el OAuth client (client_id / client_secret). Cargalos en el panel.");
49
+ }
50
+ if (!refresh_token) {
51
+ throw new Error("El calendario no está autorizado todavía. Conectá con Google en el panel.");
52
+ }
53
+ return accessTokenFor({ clientId: client_id, clientSecret: client_secret, refreshToken: refresh_token }, opts);
54
+ }
55
+
56
+ // ─── REST client ────────────────────────────────────────────────────────────
57
+
58
+ async function call(config, urlPath, { method = "GET", query, body, fetchImpl = fetch } = {}) {
59
+ const token = await getAccessToken(config, { fetchImpl });
60
+ const url = new URL(API + urlPath);
61
+ for (const [k, v] of Object.entries(query || {})) {
62
+ if (v !== undefined && v !== null && v !== "") url.searchParams.set(k, String(v));
63
+ }
64
+ const res = await fetchImpl(url.toString(), {
65
+ method,
66
+ headers: {
67
+ authorization: `Bearer ${token}`,
68
+ ...(body ? { "content-type": "application/json" } : {}),
69
+ },
70
+ ...(body ? { body: JSON.stringify(body) } : {}),
71
+ });
72
+
73
+ const data = await res.json().catch(() => ({}));
74
+ if (!res.ok) {
75
+ const msg = data?.error?.message || `HTTP ${res.status}`;
76
+ if (res.status === 401 || res.status === 403) {
77
+ throw new Error(`${msg} — puede que haga falta reconectar con Google en el panel.`);
78
+ }
79
+ throw new Error(msg);
80
+ }
81
+ return data;
82
+ }
83
+
84
+ /** Calendars the connected account can see — used only for the account probe. */
85
+ export async function listCalendars(config, opts = {}) {
86
+ const data = await call(config, "/users/me/calendarList", { ...opts });
87
+ return (data.items || []).map((c) => ({
88
+ id: c.id,
89
+ summary: c.summary || c.id,
90
+ timeZone: c.timeZone || null,
91
+ accessRole: c.accessRole || null,
92
+ primary: !!c.primary,
93
+ }));
94
+ }
95
+
96
+ /** One event, flattened to what a prompt actually needs. */
97
+ function flattenEvent(e) {
98
+ return {
99
+ id: e.id,
100
+ title: e.summary || "(sin título)",
101
+ start: e.start?.dateTime || e.start?.date || null,
102
+ end: e.end?.dateTime || e.end?.date || null,
103
+ all_day: !!e.start?.date,
104
+ location: e.location || null,
105
+ attendees: (e.attendees || []).map((a) => a.email).filter(Boolean),
106
+ status: e.status || null,
107
+ link: e.htmlLink || null,
108
+ meet_link: e.hangoutLink || null,
109
+ };
110
+ }
111
+
112
+ export async function listEvents(config, { calendarId = "primary", timeMin, timeMax, q, maxResults = 25 } = {}, opts = {}) {
113
+ const data = await call(config, `/calendars/${encodeURIComponent(calendarId)}/events`, {
114
+ query: { timeMin, timeMax, q, maxResults, singleEvents: true, orderBy: "startTime" },
115
+ ...opts,
116
+ });
117
+ return (data.items || []).map(flattenEvent);
118
+ }
119
+
120
+ /**
121
+ * Create an event. Because we act as the user now, two things that were
122
+ * impossible with a service account just work:
123
+ * - attendees get a real invitation (`sendUpdates=all`)
124
+ * - `meet: true` mints a Google Meet link (`conferenceData` + v1)
125
+ */
126
+ export async function createEvent(
127
+ config,
128
+ { calendarId = "primary", title, start, end, description, location, attendees, meet = false } = {},
129
+ opts = {},
130
+ ) {
131
+ const hasAttendees = Array.isArray(attendees) && attendees.length > 0;
132
+ const body = {
133
+ summary: title,
134
+ description: description || undefined,
135
+ location: location || undefined,
136
+ start: { dateTime: start },
137
+ end: { dateTime: end },
138
+ ...(hasAttendees ? { attendees: attendees.map((email) => ({ email })) } : {}),
139
+ ...(meet
140
+ ? {
141
+ conferenceData: {
142
+ createRequest: {
143
+ requestId: crypto.randomUUID(),
144
+ conferenceSolutionKey: { type: "hangoutsMeet" },
145
+ },
146
+ },
147
+ }
148
+ : {}),
149
+ };
150
+ const data = await call(config, `/calendars/${encodeURIComponent(calendarId)}/events`, {
151
+ method: "POST",
152
+ body,
153
+ query: {
154
+ ...(meet ? { conferenceDataVersion: 1 } : {}),
155
+ ...(hasAttendees ? { sendUpdates: "all" } : {}),
156
+ },
157
+ ...opts,
158
+ });
159
+ return flattenEvent(data);
160
+ }
161
+
162
+ export async function updateEvent(config, { calendarId = "primary", eventId, ...fields } = {}, opts = {}) {
163
+ const body = {};
164
+ if (fields.title !== undefined) body.summary = fields.title;
165
+ if (fields.description !== undefined) body.description = fields.description;
166
+ if (fields.location !== undefined) body.location = fields.location;
167
+ if (fields.start !== undefined) body.start = { dateTime: fields.start };
168
+ if (fields.end !== undefined) body.end = { dateTime: fields.end };
169
+ const hasAttendees = Array.isArray(fields.attendees) && fields.attendees.length > 0;
170
+ if (fields.attendees !== undefined) body.attendees = (fields.attendees || []).map((email) => ({ email }));
171
+ const data = await call(config, `/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(eventId)}`, {
172
+ method: "PATCH",
173
+ body,
174
+ query: { ...(hasAttendees ? { sendUpdates: "all" } : {}) },
175
+ ...opts,
176
+ });
177
+ return flattenEvent(data);
178
+ }
179
+
180
+ /**
181
+ * The first gaps of at least `minutes` between timeMin and timeMax, from
182
+ * Google's freeBusy view. Pure arithmetic once the busy blocks are in.
183
+ */
184
+ export async function findSlots(config, { calendarId = "primary", timeMin, timeMax, minutes = 30, limit = 5 } = {}, opts = {}) {
185
+ const token = await getAccessToken(config, opts);
186
+ const fetchImpl = opts.fetchImpl || fetch;
187
+ const res = await fetchImpl(`${API}/freeBusy`, {
188
+ method: "POST",
189
+ headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
190
+ body: JSON.stringify({ timeMin, timeMax, items: [{ id: calendarId }] }),
191
+ });
192
+ const data = await res.json().catch(() => ({}));
193
+ if (!res.ok) throw new Error(data?.error?.message || `HTTP ${res.status}`);
194
+
195
+ const busy = (data.calendars?.[calendarId]?.busy || [])
196
+ .map((b) => [Date.parse(b.start), Date.parse(b.end)])
197
+ .filter(([s, e]) => Number.isFinite(s) && Number.isFinite(e))
198
+ .sort((a, b) => a[0] - b[0]);
199
+
200
+ const needed = minutes * 60_000;
201
+ const slots = [];
202
+ let cursor = Date.parse(timeMin);
203
+ const end = Date.parse(timeMax);
204
+
205
+ for (const [bStart, bEnd] of busy) {
206
+ if (bStart - cursor >= needed) {
207
+ slots.push({ start: new Date(cursor).toISOString(), end: new Date(bStart).toISOString() });
208
+ if (slots.length >= limit) return slots;
209
+ }
210
+ cursor = Math.max(cursor, bEnd);
211
+ }
212
+ if (end - cursor >= needed) {
213
+ slots.push({ start: new Date(cursor).toISOString(), end: new Date(end).toISOString() });
214
+ }
215
+ return slots.slice(0, limit);
216
+ }
217
+
218
+ // ─── plugin lifecycle ───────────────────────────────────────────────────────
219
+
220
+ function asBool(v, fallback = false) {
221
+ if (v === undefined || v === null) return fallback;
222
+ return v === true || v === "true" || v === "on" || v === 1 || v === "1";
223
+ }
224
+
225
+ export const calendarPlugin = {
226
+ slug: "calendar",
227
+ name: "Google Calendar",
228
+ type: "calendar",
229
+ description:
230
+ "Conectá tu Google Calendar con OAuth para que los agentes lean tu agenda, agenden, inviten y armen Meet",
231
+ auth: "oauth",
232
+ tools: [
233
+ { slug: "calendar_list_events", desc: "Ver qué hay en la agenda" },
234
+ { slug: "calendar_find_slot", desc: "Buscar huecos libres" },
235
+ { slug: "calendar_create_event", desc: "Agendar un evento (con invitados y Meet)" },
236
+ { slug: "calendar_update_event", desc: "Mover o editar un evento" },
237
+ ],
238
+ // Structure only — display text lives in web i18n (integrations.calendar.*).
239
+ ui: {
240
+ accent: "sky",
241
+ // Presence of `oauth` tells the web component to run the consent flow:
242
+ // save client_id/secret, then a "Conectar con Google" button. `redirectPath`
243
+ // is the URI the user registers in the console (shown in the UI).
244
+ oauth: { action: "authorize", redirectPath: "/api/integrations/oauth/callback" },
245
+ configFields: [
246
+ {
247
+ key: "client_id",
248
+ type: "text",
249
+ placeholder: "123-abc.apps.googleusercontent.com",
250
+ help_url: "https://console.cloud.google.com/apis/credentials",
251
+ help_url_label: "console.cloud.google.com",
252
+ },
253
+ { key: "client_secret", type: "password", placeholder: "GOCSPX-…" },
254
+ { key: "write_access", type: "toggle", default: true },
255
+ { key: "meet", type: "toggle", default: true },
256
+ ],
257
+ connectedFields: ["account_email", "calendar_name"],
258
+ },
259
+
260
+ // Save the OAuth client + preferences. This never mints tokens — authorization
261
+ // happens in the browser (authorize action → callback → completeOAuth).
262
+ configure(record, body = {}) {
263
+ const prev = record?.config || {};
264
+ const clientId = String(body.client_id ?? prev.client_id ?? "").trim();
265
+ const clientSecret = String(body.client_secret ?? prev.client_secret ?? "").trim();
266
+
267
+ // A live connection flipping a preference (write/meet) shouldn't need the
268
+ // secret re-typed — merge over what's stored.
269
+ const config = {
270
+ ...(clientId ? { client_id: clientId } : {}),
271
+ ...(clientSecret ? { client_secret: clientSecret } : {}),
272
+ write_access: asBool(body.write_access, prev.write_access ?? true),
273
+ meet: asBool(body.meet, prev.meet ?? true),
274
+ };
275
+
276
+ if (!clientId && !prev.client_id) {
277
+ throw new Error("Cargá el client_id del OAuth client de Google.");
278
+ }
279
+
280
+ const patch = { name: this.name, type: this.type, description: this.description, config };
281
+ // A changed write scope needs a re-consent (the granted scope no longer
282
+ // matches). Everything else keeps the current connection.
283
+ if (config.write_access !== prev.write_access && prev.refresh_token) {
284
+ patch.status = "pending_validation";
285
+ patch.config.needs_reauth = true;
286
+ }
287
+ return { patch };
288
+ },
289
+
290
+ /**
291
+ * Build the Google consent URL. Called by the web panel (authorize action);
292
+ * `ctx.origin` is the browser origin, so the redirect URI matches what the
293
+ * user registered and what the callback reconstructs.
294
+ */
295
+ buildAuthorizeUrl(record, { origin, pid, scope } = {}) {
296
+ const config = record?.config || {};
297
+ if (!config.client_id) throw new Error("Cargá primero el client_id.");
298
+ if (!origin) throw new Error("No pude determinar el origin del panel para el redirect.");
299
+ const redirectUri = callbackUrl(origin);
300
+ const state = signState({ slug: this.slug, pid: String(pid ?? ""), scope: scope || "project" });
301
+ const auth_url = buildAuthUrl({
302
+ clientId: config.client_id,
303
+ redirectUri,
304
+ scope: scopeFor(config),
305
+ state,
306
+ });
307
+ return { auth_url, redirect_uri: redirectUri };
308
+ },
309
+
310
+ /**
311
+ * Finish the OAuth dance: trade the code for a refresh token and activate.
312
+ * Called by the daemon's callback route. Returns a patch to persist.
313
+ */
314
+ async completeOAuth(record, { code, redirectUri } = {}) {
315
+ const config = record?.config || {};
316
+ if (!config.client_id || !config.client_secret) {
317
+ throw new Error("Falta el OAuth client guardado para completar la conexión.");
318
+ }
319
+ const tokens = await exchangeCode({
320
+ clientId: config.client_id,
321
+ clientSecret: config.client_secret,
322
+ code,
323
+ redirectUri,
324
+ });
325
+ return {
326
+ patch: {
327
+ status: "active",
328
+ is_enabled: true,
329
+ config: {
330
+ refresh_token: tokens.refresh_token,
331
+ account_email: tokens.email || config.account_email || null,
332
+ calendar_id: "primary",
333
+ calendar_name: tokens.email || "primary",
334
+ needs_reauth: false,
335
+ last_error: null,
336
+ },
337
+ },
338
+ };
339
+ },
340
+
341
+ // Re-check a stored connection (used when flipping toggles once connected).
342
+ async validate(record) {
343
+ const config = record?.config || {};
344
+ if (!config.refresh_token) {
345
+ const detail = "Autorizá con Google en el panel para conectar el calendario.";
346
+ return {
347
+ patch: { status: "pending_validation", is_enabled: false, config: { last_error: detail } },
348
+ result: { ok: false, error: detail, needs_auth: true },
349
+ };
350
+ }
351
+ try {
352
+ // A cheap call that proves the refresh token still works.
353
+ await call(config, "/users/me/calendarList", { query: { maxResults: 1 } });
354
+ } catch (e) {
355
+ return {
356
+ patch: { status: "error", is_enabled: false, config: { last_error: String(e.message || e) } },
357
+ result: { ok: false, error: String(e.message || e) },
358
+ };
359
+ }
360
+ return {
361
+ patch: { status: "active", is_enabled: true, config: { calendar_id: "primary", needs_reauth: false, last_error: null } },
362
+ result: { ok: true, account_email: config.account_email || null },
363
+ };
364
+ },
365
+
366
+ status(record) {
367
+ const c = record?.config || {};
368
+ // No refresh token → not connected, whatever the stored status says. This
369
+ // also demotes a leftover service-account record from the old auth model so
370
+ // it can't masquerade as "active" after the OAuth migration.
371
+ const authorized = !!c.refresh_token;
372
+ let st = record?.status || "disconnected";
373
+ if (!authorized && st === "active") st = "disconnected";
374
+ return {
375
+ slug: this.slug,
376
+ status: st,
377
+ is_enabled: authorized && !!record?.is_enabled,
378
+ account_email: c.account_email || null,
379
+ calendar_id: c.calendar_id || (c.refresh_token ? "primary" : null),
380
+ calendar_name: c.calendar_name || (c.refresh_token ? c.account_email || "primary" : null),
381
+ write_access: !!c.write_access,
382
+ meet: !!c.meet,
383
+ client_id_set: !!c.client_id,
384
+ needs_reauth: !!c.needs_reauth,
385
+ };
386
+ },
387
+
388
+ deactivate() {
389
+ return { patch: { status: "inactive", is_enabled: false } };
390
+ },
391
+
392
+ actions: {
393
+ // Kick off OAuth: the web panel opens the returned auth_url in a popup.
394
+ async authorize(record, ctx = {}) {
395
+ return calendarPlugin.buildAuthorizeUrl(record, {
396
+ origin: ctx.origin,
397
+ pid: ctx.project?.id ?? 0,
398
+ scope: ctx.scope,
399
+ });
400
+ },
401
+ },
402
+ };
403
+
404
+ export default calendarPlugin;
@@ -14,6 +14,8 @@ const SECRET_KEYS = new Set([
14
14
  "token",
15
15
  "api_key",
16
16
  "client_secret",
17
+ "refresh_token",
18
+ "access_token",
17
19
  ]);
18
20
 
19
21
  // Return a shallow copy of a record with secret config values masked, safe to
@@ -73,6 +73,21 @@ function lastMemoryEntries(memoryPath, n) {
73
73
  }
74
74
  }
75
75
 
76
+ // A recalled tool row is indexed as `[tool result: <name>] <name>({…args})`.
77
+ // Stripping the prefix — which is what this did — left the bare call shape
78
+ // sitting in the prompt, the exact worked example that teaches a model to
79
+ // WRITE calls instead of making them (see tools/tool-call-parser.js). The
80
+ // name and the arguments are what makes the bullet useful; the parentheses
81
+ // and braces are what makes it dangerous, so only those go.
82
+ function deFangToolRow(text) {
83
+ const m = String(text ?? "").match(/^\[tool result:\s*([^\]\n]+)\]\s*([\s\S]*)$/);
84
+ if (!m) return text;
85
+ const name = m[1].trim();
86
+ let body = m[2].trim();
87
+ if (body.startsWith(`${name}(`) && body.endsWith(")")) body = body.slice(name.length + 1, -1);
88
+ return `${name} → ${body.replace(/[{}]/g, "")}`.trim();
89
+ }
90
+
76
91
  function bulletFor({ date, channel, text }) {
77
92
  const d = date ? `[${date}]` : "";
78
93
  const c = channel && channel !== "memory" ? `[${channel}]` : channel === "memory" ? "[memory]" : "";
@@ -129,7 +144,7 @@ export async function buildMemoryBlock(message, opts = {}) {
129
144
  push({
130
145
  date: dateOf(h.ts),
131
146
  channel: h.tag === "memory" ? "memory" : h.channel,
132
- text: h.text.replace(/^\[tool result: [^\]]+\]\s*/, ""),
147
+ text: deFangToolRow(h.text),
133
148
  });
134
149
  }
135
150
  for (const e of memEntries) {