@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
@@ -0,0 +1,150 @@
1
+ // Telegram replies as VOICE while the owner is driving.
2
+ //
3
+ // The rule: when a trip is active, every automatic Telegram reply goes out
4
+ // twice — first the spoken note, then the written reply under a transcript
5
+ // header. Two sends, deliberately. The audio is what you can consume with your
6
+ // eyes on the road; the text is what you can scroll back to at the next red
7
+ // light, and what search, the web panel and the ledger can read. Neither one
8
+ // alone covers both.
9
+ //
10
+ // They are not always the same words. The written half is the whole reply; the
11
+ // spoken half is its FIRST PARAGRAPH (see spokenPart). That is what lets an
12
+ // answer carry something unspeakable — a command, a prompt to paste, a diff —
13
+ // without it being read out at the wheel: the model is told to put such things
14
+ // below a blank line and to say where they went, and this module honours the
15
+ // break it drew.
16
+ //
17
+ // Length is otherwise still the prompt's job, not this module's: the turn runs
18
+ // in voice MODE (channelMeta.voice → prompts/modes/voice.md, two short
19
+ // sentences) plus mobility mode, the same switch the desktop capsule uses.
20
+ // Shortening a paragraph the model already wrote would only truncate it
21
+ // mid-sentence, which is why nothing here does that — cutting at a boundary
22
+ // the model was asked to draw is a different thing from cutting mid-thought.
23
+ //
24
+ // Core stays core: the Telegram I/O arrives as `io` ({ send, sendVoice }), so
25
+ // nothing here imports the host plugin.
26
+ import fs from "node:fs";
27
+ import { t, resolveLang } from "#core/i18n/index.js";
28
+ import { synthesize } from "#core/voice/tts.js";
29
+ import { toVoiceNote } from "#core/voice/opus.js";
30
+ import { stripEmoji } from "#core/voice/pronounceable.js";
31
+ import { archiveOutboundMedia, outboundMediaMeta } from "#core/stores/media-archive.js";
32
+ import { mobilityContext } from "#core/mobility/state.js";
33
+
34
+ /**
35
+ * The half of a reply that gets SPOKEN: everything up to the first blank line
36
+ * or the first code fence, whichever comes first.
37
+ *
38
+ * This is not shortening the model's answer after the fact — that only ever
39
+ * truncates mid-sentence, which is why it was refused. It is honouring a
40
+ * boundary the model drew itself, on instruction: prompts/modes/mobility.md
41
+ * tells it the first paragraph is what gets spoken and that anything a person
42
+ * cannot hear — a command, a prompt to paste, a diff — goes below a blank line
43
+ * instead. Both halves are still delivered; only the audio stops at the break.
44
+ *
45
+ * Without it, "your answer is also a voice note" meant a driver being read a
46
+ * shell command character by character, because the model had nowhere else to
47
+ * put it and no reason to think it should.
48
+ *
49
+ * A reply with no break is spoken whole — the common case is one short
50
+ * paragraph, and nothing about it changes. A reply that opens straight into a
51
+ * code block has no sayable half at all; that comes back empty, and the caller
52
+ * sends it as plain text rather than voicing punctuation.
53
+ */
54
+ export function spokenPart(text) {
55
+ const clean = String(text || "").trim();
56
+ if (!clean || clean.startsWith("```")) return "";
57
+ const breaks = [clean.indexOf("\n```"), clean.indexOf("\n\n")].filter((at) => at > 0);
58
+ return breaks.length ? clean.slice(0, Math.min(...breaks)).trim() : clean;
59
+ }
60
+
61
+ /**
62
+ * Is the owner in a car right now, and does this install want spoken replies
63
+ * for that? Trip state is the trigger; `config.voice.mobility_replies` is the
64
+ * kill switch (default on — the feature is pointless if you have to arm it
65
+ * before every drive, and the whole point is that you cannot safely touch the
66
+ * phone once you have started).
67
+ */
68
+ export function mobilityVoiceActive(globalConfig, state = mobilityContext()) {
69
+ if (globalConfig?.voice?.mobility_replies === false) return false;
70
+ return Boolean(state?.trip?.active);
71
+ }
72
+
73
+ /**
74
+ * Send `text` as a voice note plus its transcript. Returns what actually
75
+ * happened, so the caller can log the right thing:
76
+ *
77
+ * { voice: true, transcript, provider, media, sent } — both went out
78
+ * { voice: false, reason } — TTS or ffmpeg
79
+ * failed; the caller still owes the text
80
+ *
81
+ * `sent` is the TEXT message's Telegram result, not the audio's: it is the one
82
+ * carrying the inline keyboard, so it is the one a later edit has to address.
83
+ *
84
+ * The transcript send is the caller's business ONLY in the failure case: on
85
+ * success this function has already sent both halves, keyboard included. That
86
+ * asymmetry is on purpose — the keyboard must ride on the text message (a
87
+ * voice note with chips under it reads as if the chips belong to the audio
88
+ * player), and only this function knows whether the audio made it.
89
+ *
90
+ * `synthesizeFn` / `toVoiceNoteFn` are seams, not options: the same shape as
91
+ * `ctx.mobilityFetch` elsewhere in this feature. Speech and ffmpeg are the two
92
+ * things a test cannot have (the always-available mock engine returns silence,
93
+ * which this function is required to refuse), and without them the two-send
94
+ * contract would be untestable.
95
+ */
96
+ export async function deliverVoiceReply({
97
+ io, chat_id, text, reply_markup, globalConfig, log = () => {},
98
+ synthesizeFn = synthesize, toVoiceNoteFn = toVoiceNote,
99
+ }) {
100
+ const lang = resolveLang(globalConfig);
101
+ const clean = String(text || "").trim();
102
+ if (!clean) return { voice: false, reason: "empty" };
103
+ // The audio is the FIRST paragraph; the transcript below is the whole reply.
104
+ // See spokenPart() — the split is the model's, made on instruction.
105
+ const head = spokenPart(clean);
106
+ if (!head) return { voice: false, reason: "nothing-sayable" };
107
+
108
+ let audio = null;
109
+ let converted = null;
110
+ try {
111
+ // Spoken text loses its emoji; the transcript below keeps them. A TTS model
112
+ // has to produce something for every token, and 📍 comes out as a couple of
113
+ // seconds of humming in the middle of the sentence.
114
+ const sayable = stripEmoji(head);
115
+ const spoken = await synthesizeFn({ text: sayable || head, globalConfig });
116
+ // "mock" is the selector's way of saying nothing spoke — the audio is
117
+ // silence. Sending it would look like a delivered reply the owner simply
118
+ // could not hear, which is worse than plain text.
119
+ if (!spoken?.audio_path || spoken.provider === "mock") {
120
+ return { voice: false, reason: `tts:${spoken?.provider || "none"}` };
121
+ }
122
+ audio = spoken.audio_path;
123
+ converted = await toVoiceNoteFn(audio);
124
+ if (!converted) return { voice: false, reason: "ffmpeg" };
125
+
126
+ const duration = Math.round(spoken.duration_s || 0) || undefined;
127
+ await io.sendVoice({ chat_id, audio: converted, duration });
128
+ const transcript = `${t("mobility.transcript", { lang })}\n${clean}`;
129
+ const sent = await io.send({ chat_id, text: transcript, reply_markup });
130
+ // The tmp file is about to be deleted, so the ledger row cannot point at
131
+ // it — archive the bytes first and hand the caller the meta that makes the
132
+ // web thread show a real player instead of "[voice]".
133
+ const media = outboundMediaMeta(
134
+ "audio",
135
+ archiveOutboundMedia(converted, { mime: "audio/ogg" }),
136
+ { duration }
137
+ );
138
+ return { voice: true, transcript, provider: spoken.provider, media, sent };
139
+ } catch (error) {
140
+ log(`telegram voice reply failed: ${error?.message || error}`);
141
+ return { voice: false, reason: error?.message || "send-failed" };
142
+ } finally {
143
+ // Both files live under ~/.apx/tmp/tts and neither is referenced again:
144
+ // the ledger keeps its own archived copy (media-archive.js) once sendVoice
145
+ // has logged the row.
146
+ for (const file of new Set([audio, converted].filter(Boolean))) {
147
+ try { fs.unlinkSync(file); } catch { /* already gone */ }
148
+ }
149
+ }
150
+ }
@@ -4,7 +4,7 @@
4
4
  // can keep `import { APX_HOME, projectStorageRoot } from ".../config"` working.
5
5
  import fs from "node:fs";
6
6
  import path from "node:path";
7
- import { APX_HOME, CONFIG_PATH } from "./paths.js";
7
+ import { APX_HOME, CONFIG_PATH, syncPaths } from "./paths.js";
8
8
  import { PERMISSION_MODES } from "../constants/permissions.js";
9
9
  import { agentsMdFile, apcProjectFile } from "../apc/paths.js";
10
10
 
@@ -62,6 +62,25 @@ const DEFAULT_CONFIG = {
62
62
  // snappier but more "want me to continue?" hand-backs. 0/unset → built-in
63
63
  // default (TELEGRAM_TOOL_ITERS in src/core/agent/constants.js).
64
64
  telegram_max_iters: 0,
65
+ // Tool-loop budget for a routine that does NOT report to Telegram (Magui
66
+ // filling a backlog, an agent working a repo): no human waits on it mid-run,
67
+ // so it runs to completion rather than to a chat budget. 0/unset → built-in
68
+ // ceiling (ROUTINE_UNCAPPED_TOOL_ITERS in src/core/agent/constants.js), which
69
+ // is a runaway backstop, not a normal stopping point. Telegram-bound routines
70
+ // keep telegram_max_iters so their message stays one concise turn.
71
+ routine_max_iters: 0,
72
+ // Tool-loop budget for the web chat (big chat + docked sidebar). This is the
73
+ // surface you watch while it works, so it runs to completion instead of
74
+ // stopping every few actions to ask — the "want me to keep going?" close is
75
+ // Telegram's guardrail, where you can't see the turn go wrong. 0/unset →
76
+ // built-in ceiling (WEB_TOOL_ITERS in src/core/agent/constants.js), which is
77
+ // a runaway backstop, not a normal stopping point.
78
+ web_max_iters: 0,
79
+ // How often optional MODEL prose may appear during a working Telegram turn.
80
+ // Every real tool start is already shown immediately, with typing renewed;
81
+ // this controls only extra model-written heartbeats. 0 disables those extra
82
+ // notes. See core/channels/telegram/progress-gate.js.
83
+ telegram_progress_every_s: 90,
65
84
  // Char cap for a FOREIGN project's AGENTS.md in the prompt. 0 = no cap.
66
85
  // The project APX runs inside is never capped regardless of this value —
67
86
  // a project must always read its own contract whole.
@@ -110,13 +129,26 @@ const DEFAULT_CONFIG = {
110
129
  enabled: true,
111
130
  rules: [],
112
131
  },
113
- // Goal-completion judge (OpenHands critic pattern): after a
114
- // completion-contract turn declares done, an LLM judge scores goal
115
- // completion (0..1); below success_threshold the agent gets a
132
+ // Vision bridge: when the answering model cannot see pixels (zen free
133
+ // models, etc.), describe attached photos with this vision model and fold
134
+ // the text into the prompt. Default gemini-2.0-flash; override here or via
135
+ // a has_image routing rule.
136
+ vision_bridge_model: null,
137
+ // Goal-completion judge (OpenHands critic pattern): an LLM judge scores
138
+ // goal completion (0..1); below success_threshold the agent gets a
116
139
  // verification follow-up and continues, up to max_iterations rounds.
140
+ // enabled — verify the "done" a completion-contract (coding)
141
+ // turn declares. Opt-in: it costs a call per finish.
142
+ // continue_unfinished — continue a CONVERSATIONAL turn that stopped
143
+ // mid-task (the model announced its next step and
144
+ // called no tool). On by default; that stop reads as
145
+ // a bug, and the manual fix is the user typing
146
+ // "seguí". Chat turns and turns that ended asking a
147
+ // question are never judged.
117
148
  // model "" → judge runs on super_agent.model.
118
149
  judge: {
119
150
  enabled: false,
151
+ continue_unfinished: true,
120
152
  success_threshold: 0.6,
121
153
  max_iterations: 2,
122
154
  model: "",
@@ -155,7 +187,8 @@ const DEFAULT_CONFIG = {
155
187
  window_hours: 6, // only surface channels touched within this window
156
188
  max_lines: 3, // hard cap on bullets (token guard)
157
189
  },
158
- // Legacy flat keys (still honored as an ollama override for old configs).
190
+ // Flat Ollama embedding defaults; embed-engines/index.js folds these into
191
+ // an `embeddings.ollama` block when the config has no explicit one.
159
192
  embed_model: "nomic-embed-text", // Ollama embeddings model
160
193
  embed_base_url: "", // "" → falls back to engines.ollama.base_url
161
194
  embed_timeout_ms: 4000,
@@ -204,6 +237,12 @@ const DEFAULT_CONFIG = {
204
237
  };
205
238
 
206
239
  function ensureHome() {
240
+ // Re-derive the home first. It is fixed for the life of a real process, so
241
+ // this is a string compare that always says "no" in production — but a test
242
+ // that relocates APX_HOME after this module loaded needs its fixture read
243
+ // back, not the developer's real config. Doing it here, rather than relying
244
+ // on nothing having imported config yet, is what makes that deterministic.
245
+ syncPaths();
207
246
  fs.mkdirSync(APX_HOME, { recursive: true });
208
247
  }
209
248
 
@@ -340,36 +379,15 @@ export function writeConfig(cfg) {
340
379
  try { fs.chmodSync(CONFIG_PATH, 0o600); } catch {}
341
380
  }
342
381
 
343
- // Normalise `model_fallback` to the new format (`models` as an ordered array
344
- // of "<provider>:<model>" strings). Legacy configs that use `order + models{}`
345
- // are converted in place; the result is what the runtime sees, but
346
- // writeConfig() preserves whichever shape the user has on disk unless we
347
- // rewrite it explicitly elsewhere.
382
+ // Normalise `model_fallback`: `models` is an ordered array of
383
+ // "<provider>:<model>" strings. Anything else falls back to the defaults.
348
384
  function mergeModelFallback(raw) {
349
385
  const def = DEFAULT_CONFIG.super_agent.model_fallback;
350
386
  const src = raw && typeof raw === "object" ? raw : {};
351
387
 
352
- // Resolve `models` to an array. Three input shapes:
353
- // 1. array of strings keep, filtered to "<provider>:<model>".
354
- // 2. legacy object + (optional) order → walk order, collect values.
355
- // 3. nothing → use defaults.
356
- let models;
357
- if (Array.isArray(src.models)) {
358
- models = src.models
359
- .filter((m) => typeof m === "string" && m.includes(":"))
360
- .map(String);
361
- } else if (src.models && typeof src.models === "object") {
362
- const order = Array.isArray(src.order)
363
- ? src.order.map(String)
364
- : ["ollama", "openrouter", "groq"];
365
- models = [];
366
- for (const p of order) {
367
- const m = src.models[p.toLowerCase()];
368
- if (typeof m === "string" && m.includes(":")) models.push(m);
369
- }
370
- } else {
371
- models = [...def.models];
372
- }
388
+ const models = Array.isArray(src.models)
389
+ ? src.models.filter((m) => typeof m === "string" && m.includes(":")).map(String)
390
+ : [...def.models];
373
391
 
374
392
  return {
375
393
  enabled: typeof src.enabled === "boolean" ? src.enabled : def.enabled,
@@ -381,31 +399,12 @@ function mergeModelFallback(raw) {
381
399
  };
382
400
  }
383
401
 
384
- // Migrate legacy `telegram.bot_token` / `telegram.chat_id` (root level) into
385
- // `telegram.channels[]`. These root-level fields were removed once channels[]
386
- // became the source of truth; we keep this helper around so existing configs
387
- // upgrade in place without losing credentials.
402
+ // `telegram.channels[]` is the source of truth for credentials. A bare
403
+ // `bot_token`/`chat_id` at the root is not a supported shape and is dropped.
388
404
  function mergeTelegram(rawTelegram) {
389
405
  const src = rawTelegram || {};
390
- const { bot_token: legacyBotToken, chat_id: legacyChatId, channels: rawChannels, ...rest } = src;
391
- let channels = Array.isArray(rawChannels) ? rawChannels : [];
392
-
393
- const hasLegacy =
394
- (typeof legacyBotToken === "string" && legacyBotToken.length > 0) ||
395
- (typeof legacyChatId === "string" && legacyChatId.length > 0);
396
-
397
- if (hasLegacy && channels.length === 0) {
398
- // Build a single "default" channel from the legacy fields and drop them.
399
- channels = [
400
- {
401
- name: "default",
402
- bot_token: legacyBotToken || "",
403
- chat_id: legacyChatId || "",
404
- },
405
- ];
406
- // eslint-disable-next-line no-console
407
- console.warn("[apx] migrated legacy telegram.bot_token/chat_id into channels[0]");
408
- }
406
+ const { bot_token: _dropBotToken, chat_id: _dropChatId, channels: rawChannels, ...rest } = src;
407
+ const channels = Array.isArray(rawChannels) ? rawChannels : [];
409
408
 
410
409
  return {
411
410
  ...DEFAULT_CONFIG.telegram,
@@ -7,31 +7,49 @@ import path from "node:path";
7
7
  /**
8
8
  * Where APX keeps everything. `APX_HOME` in the environment relocates it —
9
9
  * useful for sandboxes and required by tests that need an isolated home.
10
- *
11
- * Resolve lazily when a caller can be reached after the environment changes
12
- * (tests stub os.homedir mid-run); the eager `APX_HOME` constant below is the
13
- * common case and stays for the ~30 call sites that read it at import time.
14
10
  */
15
- export function apxHome() {
11
+ function computeHome() {
16
12
  return process.env.APX_HOME || path.join(os.homedir(), ".apx");
17
13
  }
18
14
 
19
- export const APX_HOME = apxHome();
20
- export const CONFIG_PATH = path.join(APX_HOME, "config.json");
21
- export const PID_PATH = path.join(APX_HOME, "daemon.pid");
22
- export const LOG_PATH = path.join(APX_HOME, "daemon.log");
23
- export const TELEGRAM_STATE_PATH = path.join(APX_HOME, "telegram-state.json");
24
- export const TOKEN_PATH = path.join(APX_HOME, "daemon.token");
15
+ // ---------------------------------------------------------------------------
16
+ // The paths below are `let`, not `const`, and that is the whole point.
17
+ //
18
+ // They used to be frozen at import: whichever module reached this file first
19
+ // decided where ~/.apx was for the rest of the process. That made test
20
+ // isolation a RACE — a test that relocates APX_HOME inside its body only won if
21
+ // nothing had imported config before it, which depends on module-graph order
22
+ // and, under a parallel runner, on which files happen to share a process. Two
23
+ // suites flaked on exactly that (tests/admin-reload, tests/commitments-api):
24
+ // they wrote a fixture config into a temp home and then read the developer's
25
+ // real one.
26
+ //
27
+ // An ES module export is a LIVE BINDING, so reassigning here updates every
28
+ // importer — including ones that imported before the change — with no call-site
29
+ // changes and no accessor cost. Importers still cannot assign: the binding is
30
+ // read-only on their side, so `let` costs nothing in safety.
31
+ //
32
+ // Call `syncPaths()` after changing APX_HOME (or HOME). `apxHome()` and
33
+ // `ensureHome()` already do, which covers readConfig/writeConfig and therefore
34
+ // nearly everything.
35
+ // ---------------------------------------------------------------------------
36
+
37
+ export let APX_HOME = computeHome();
38
+ export let CONFIG_PATH;
39
+ export let PID_PATH;
40
+ export let LOG_PATH;
41
+ export let TELEGRAM_STATE_PATH;
42
+ export let TOKEN_PATH;
25
43
 
26
44
  // Global channel messages (telegram, direct, whatsapp, …) live here,
27
45
  // separated from any project. Structure: ~/.apx/messages/<channel>/YYYY-MM-DD.jsonl
28
- export const GLOBAL_MESSAGES_DIR = path.join(APX_HOME, "messages");
46
+ export let GLOBAL_MESSAGES_DIR;
29
47
 
30
48
  // Per-project runtime storage (conversations, sessions) — never in the repo.
31
49
  // Structure: ~/.apx/projects/<apx_id>/agents/<slug>/conversations/
32
- export const PROJECT_STORE_ROOT = path.join(APX_HOME, "projects");
50
+ export let PROJECT_STORE_ROOT;
33
51
  export const DEFAULT_PROJECT_ID = "default";
34
- export const DEFAULT_PROJECT_STORE = path.join(PROJECT_STORE_ROOT, DEFAULT_PROJECT_ID);
52
+ export let DEFAULT_PROJECT_STORE;
35
53
 
36
54
  // ---------------------------------------------------------------------------
37
55
  // Everything else under ~/.apx.
@@ -44,38 +62,106 @@ export const DEFAULT_PROJECT_STORE = path.join(PROJECT_STORE_ROOT, DEFAULT_PROJE
44
62
  // ---------------------------------------------------------------------------
45
63
 
46
64
  /** The super-agent's own notebook (see core/agent/self-memory.js). */
47
- export const SELF_MEMORY_PATH = path.join(APX_HOME, "memory.md");
65
+ export let SELF_MEMORY_PATH;
48
66
  /** Who the super-agent is: name, personality, owner. */
49
- export const IDENTITY_PATH = path.join(APX_HOME, "identity.json");
67
+ export let IDENTITY_PATH;
50
68
 
51
69
  /** User-installed skills and the RAG index built over them. */
52
- export const SKILLS_DIR = path.join(APX_HOME, "skills");
53
- export const SKILLS_INDEX_PATH = path.join(SKILLS_DIR, ".index.json");
70
+ export let SKILLS_DIR;
71
+ export let SKILLS_INDEX_PATH;
54
72
 
55
73
  /** Agent vault — reusable agent definitions, not tied to one project. */
56
- export const AGENT_VAULT_DIR = path.join(APX_HOME, "agents");
74
+ export let AGENT_VAULT_DIR;
57
75
 
58
76
  /** Ledger of unrequested outbound messages and the user's feedback on them. */
59
- export const NUDGES_PATH = path.join(APX_HOME, "nudges.json");
77
+ export let NUDGES_PATH;
78
+ /** Mobility preferences such as "do not mention more trips today". */
79
+ export let MOBILITY_PATH;
60
80
 
61
81
  /** Unified log tree. Everything writes here so one tail follows the system. */
62
- export const LOG_DIR = path.join(APX_HOME, "logs");
63
- export const APX_LOG_PATH = path.join(LOG_DIR, "apx.log");
64
- export const ERROR_TRACE_PATH = path.join(LOG_DIR, "errors.jsonl");
82
+ export let LOG_DIR;
83
+ export let APX_LOG_PATH;
84
+ export let ERROR_TRACE_PATH;
65
85
 
66
86
  /** Desktop capsule (Electron) runtime state. */
67
- export const DESKTOP_PID_PATH = path.join(APX_HOME, "desktop.pid");
68
- export const DESKTOP_LOG_PATH = path.join(APX_HOME, "desktop.log");
69
- export const DESKTOP_AUTOSTART_LOG_PATH = path.join(APX_HOME, "desktop-autostart.log");
87
+ export let DESKTOP_PID_PATH;
88
+ export let DESKTOP_LOG_PATH;
89
+ export let DESKTOP_AUTOSTART_LOG_PATH;
70
90
 
71
91
  /** Scratch space. Safe to delete between runs. */
72
- export const TMP_DIR = path.join(APX_HOME, "tmp");
73
- export const TTS_TMP_DIR = path.join(TMP_DIR, "tts");
74
- export const RECORDINGS_TMP_DIR = path.join(TMP_DIR, "recordings");
92
+ export let TMP_DIR;
93
+ export let TTS_TMP_DIR;
94
+ export let RECORDINGS_TMP_DIR;
95
+
96
+ /**
97
+ * Generated images (see core/images/). NOT under tmp/ on purpose: a TTS clip is
98
+ * consumed once and thrown away, but a picture the user asked for is an
99
+ * artifact they will want again, so it keeps a dated gallery instead. Nothing
100
+ * here is ever written into a project checkout — see rule "no auto-writes into
101
+ * the repo": `apx image` only writes into the repo when --out says so.
102
+ */
103
+ export let IMAGES_DIR;
75
104
 
76
105
  /** Managed runtimes we install on the user's behalf. */
77
- export const RUNTIME_DIR = path.join(APX_HOME, "runtime");
78
- export const WHISPER_VENV_DIR = path.join(RUNTIME_DIR, "whisper-venv");
106
+ export let RUNTIME_DIR;
107
+ export let WHISPER_VENV_DIR;
108
+
109
+ /** Derive every path under the home. Order matters where one nests in another. */
110
+ function rebuild(home) {
111
+ APX_HOME = home;
112
+ CONFIG_PATH = path.join(home, "config.json");
113
+ PID_PATH = path.join(home, "daemon.pid");
114
+ LOG_PATH = path.join(home, "daemon.log");
115
+ TELEGRAM_STATE_PATH = path.join(home, "telegram-state.json");
116
+ TOKEN_PATH = path.join(home, "daemon.token");
117
+ GLOBAL_MESSAGES_DIR = path.join(home, "messages");
118
+ PROJECT_STORE_ROOT = path.join(home, "projects");
119
+ DEFAULT_PROJECT_STORE = path.join(PROJECT_STORE_ROOT, DEFAULT_PROJECT_ID);
120
+ SELF_MEMORY_PATH = path.join(home, "memory.md");
121
+ IDENTITY_PATH = path.join(home, "identity.json");
122
+ SKILLS_DIR = path.join(home, "skills");
123
+ SKILLS_INDEX_PATH = path.join(SKILLS_DIR, ".index.json");
124
+ AGENT_VAULT_DIR = path.join(home, "agents");
125
+ NUDGES_PATH = path.join(home, "nudges.json");
126
+ MOBILITY_PATH = path.join(home, "mobility.json");
127
+ LOG_DIR = path.join(home, "logs");
128
+ APX_LOG_PATH = path.join(LOG_DIR, "apx.log");
129
+ ERROR_TRACE_PATH = path.join(LOG_DIR, "errors.jsonl");
130
+ DESKTOP_PID_PATH = path.join(home, "desktop.pid");
131
+ DESKTOP_LOG_PATH = path.join(home, "desktop.log");
132
+ DESKTOP_AUTOSTART_LOG_PATH = path.join(home, "desktop-autostart.log");
133
+ TMP_DIR = path.join(home, "tmp");
134
+ TTS_TMP_DIR = path.join(TMP_DIR, "tts");
135
+ RECORDINGS_TMP_DIR = path.join(TMP_DIR, "recordings");
136
+ IMAGES_DIR = path.join(home, "images");
137
+ RUNTIME_DIR = path.join(home, "runtime");
138
+ WHISPER_VENV_DIR = path.join(RUNTIME_DIR, "whisper-venv");
139
+ }
140
+
141
+ rebuild(APX_HOME);
142
+
143
+ /**
144
+ * Point every path at wherever the home is NOW.
145
+ *
146
+ * Production never needs this — the environment is fixed at boot — but a test
147
+ * that relocates APX_HOME (or stubs os.homedir, or moves HOME) after this
148
+ * module has loaded does, and calling it is deterministic where relying on
149
+ * import order was not.
150
+ *
151
+ * @returns {boolean} whether anything moved.
152
+ */
153
+ export function syncPaths() {
154
+ const next = computeHome();
155
+ if (next === APX_HOME) return false;
156
+ rebuild(next);
157
+ return true;
158
+ }
159
+
160
+ /** The home, guaranteed current. */
161
+ export function apxHome() {
162
+ syncPaths();
163
+ return APX_HOME;
164
+ }
79
165
 
80
166
  export function projectStorageRoot(apxId) {
81
167
  return path.join(PROJECT_STORE_ROOT, apxId);
@@ -18,6 +18,9 @@ export const SECRET_PATHS = [
18
18
  "voice.tts.elevenlabs.api_key",
19
19
  "voice.tts.openai.api_key",
20
20
  "voice.tts.gemini.api_key",
21
+ "images.a1111.api_key",
22
+ "images.sdcpp.api_key",
23
+ "images.openai.api_key",
21
24
  "transcription.openai.api_key",
22
25
  "transcription.custom.api_key",
23
26
  "memory.embeddings.openai.api_key",
@@ -30,8 +33,92 @@ export const SECRET_PATHS = [
30
33
  // below. Listed here so the "which keys are secrets" question still has one
31
34
  // answer to read.
32
35
  "engines.gemini.api_keys.*",
36
+ // User-added providers live in an object keyed by slug, so the segment in
37
+ // the middle is a wildcard. redact() walks these too — see expandWildcards.
38
+ "voice.tts.custom.*.api_key",
39
+ "images.custom.*.api_key",
33
40
  ];
34
41
 
42
+ /**
43
+ * Expand a wildcard path against a real config, yielding the concrete dotted
44
+ * paths that exist in it. Only object maps are walked: `engines.gemini.
45
+ * api_keys.*` addresses a LIST, which has no key to name, and stays handled by
46
+ * the array cases below.
47
+ */
48
+ function expandWildcards(cfg, pattern) {
49
+ const parts = pattern.split(".");
50
+ let paths = [[]];
51
+ let nodes = [cfg];
52
+ for (const part of parts) {
53
+ const nextPaths = [];
54
+ const nextNodes = [];
55
+ for (let i = 0; i < nodes.length; i++) {
56
+ const node = nodes[i];
57
+ if (!node || typeof node !== "object" || Array.isArray(node)) continue;
58
+ const keys = part === "*" ? Object.keys(node) : [part];
59
+ for (const key of keys) {
60
+ if (!(key in node)) continue;
61
+ nextPaths.push([...paths[i], key]);
62
+ nextNodes.push(node[key]);
63
+ }
64
+ }
65
+ paths = nextPaths;
66
+ nodes = nextNodes;
67
+ }
68
+ return paths.map((p) => p.join("."));
69
+ }
70
+
71
+ /** Every concrete secret path present in `cfg`, wildcards resolved. */
72
+ function concreteSecretPaths(cfg) {
73
+ const out = [];
74
+ for (const pattern of SECRET_PATHS) {
75
+ if (!pattern.includes("*")) { out.push(pattern); continue; }
76
+ // A trailing `*` addresses list entries, not map keys — skip those here.
77
+ if (pattern.endsWith(".*")) continue;
78
+ out.push(...expandWildcards(cfg, pattern));
79
+ }
80
+ return out;
81
+ }
82
+
83
+ // Leaf names that carry a secret even when the full path is not in
84
+ // SECRET_PATHS yet — a provider added after this list was last touched still
85
+ // gets caught. Deliberately narrow: `base_url`, `model` and `provider` are the
86
+ // keys that legitimately belong in a committed project config.
87
+ const SECRET_LEAF_RE = /(^|_)(api_?keys?|tokens?|secrets?|passwords?|credentials?)$/;
88
+
89
+ /**
90
+ * True when a dotted config key addresses a secret — used to warn before a
91
+ * credential is written somewhere it should not be (a committed
92
+ * `.apc/config.json`). Three ways to match, in order of confidence:
93
+ *
94
+ * 1. the key IS a secret path engines.openai.api_key
95
+ * 2. the key is an ANCESTOR of one engines.openai ← value holds api_key
96
+ * 3. the leaf name looks like a secret engines.newprovider.api_key
97
+ *
98
+ * Case 2 matters because `apx config set engines.openai '{"api_key":"…"}'` puts
99
+ * the secret in the VALUE, where a leaf-name check would never see it.
100
+ * Wildcards in SECRET_PATHS (`telegram.channels.*.bot_token`) match any segment.
101
+ */
102
+ export function isSecretKey(dottedKey) {
103
+ if (typeof dottedKey !== "string" || !dottedKey.trim()) return false;
104
+ const parts = dottedKey.trim().split(".");
105
+
106
+ for (const pattern of SECRET_PATHS) {
107
+ const pp = pattern.split(".");
108
+ // Compare only the segments the two have in common: a shorter key is an
109
+ // ancestor (case 2), a longer one reaches inside a secret (still secret).
110
+ const shared = Math.min(pp.length, parts.length);
111
+ let hit = true;
112
+ for (let i = 0; i < shared; i++) {
113
+ if (pp[i] === "*") continue;
114
+ if (pp[i] !== parts[i]) { hit = false; break; }
115
+ }
116
+ if (hit) return true;
117
+ }
118
+
119
+ return SECRET_LEAF_RE.test(parts[parts.length - 1].toLowerCase());
120
+ }
121
+
35
122
  /** Replace a secret string with the visible marker, preserving the last 5 chars. */
36
123
  export function secretMarker(value) {
37
124
  if (typeof value !== "string" || !value.length) return value;
@@ -49,8 +136,7 @@ export function redactConfig(cfg) {
49
136
  const out = JSON.parse(JSON.stringify(cfg || {}));
50
137
  const mark = (val) => (typeof val === "string" && val.length ? secretMarker(val) : val);
51
138
 
52
- for (const dotted of SECRET_PATHS) {
53
- if (dotted.includes("*")) continue;
139
+ for (const dotted of concreteSecretPaths(cfg)) {
54
140
  const parts = dotted.split(".");
55
141
  let cur = out;
56
142
  for (let i = 0; i < parts.length - 1; i++) {
@@ -108,8 +194,7 @@ function setDotted(obj, dotted, value) {
108
194
  */
109
195
  export function mergeRedactedSecrets(next, prior) {
110
196
  if (!next || typeof next !== "object") return next;
111
- for (const dotted of SECRET_PATHS) {
112
- if (dotted.includes("*")) continue;
197
+ for (const dotted of concreteSecretPaths(next)) {
113
198
  if (isSecretMarker(getDotted(next, dotted))) {
114
199
  const priorVal = getDotted(prior, dotted);
115
200
  if (typeof priorVal === "string" && priorVal.length) setDotted(next, dotted, priorVal);
@@ -37,9 +37,8 @@ function getDotted(obj, dotted) {
37
37
 
38
38
  /**
39
39
  * Walk a config object and return every secret VALUE it holds: all
40
- * SECRET_PATHS entries, every telegram channel bot_token, and the legacy
41
- * root telegram.bot_token (pre-migration configs). Deduped; empty and
42
- * too-short strings dropped.
40
+ * SECRET_PATHS entries and every telegram channel bot_token. Deduped; empty
41
+ * and too-short strings dropped.
43
42
  */
44
43
  export function collectSecretValues(cfg) {
45
44
  const out = new Set();
@@ -56,7 +55,6 @@ export function collectSecretValues(cfg) {
56
55
  if (isRegistrable(ch?.bot_token)) out.add(ch.bot_token);
57
56
  }
58
57
  }
59
- if (isRegistrable(cfg?.telegram?.bot_token)) out.add(cfg.telegram.bot_token);
60
58
  } catch {
61
59
  // collection must never break the caller — return what we got so far
62
60
  }
@@ -6,3 +6,8 @@
6
6
  // was named). Identity (display name + personality) lives in identity.json and
7
7
  // is resolved at runtime via resolveAgentName().
8
8
  export const SUPERAGENT_ACTOR_ID = "super_agent";
9
+
10
+ // The human. Not an agent and never summonable: the owner speaks by typing, so
11
+ // naming them in a mention resolves to nothing. Used as the author of anything
12
+ // a person wrote — a task comment, a group line — where an agent slug would go.
13
+ export const OWNER_ACTOR_ID = "owner";