@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,68 @@
1
+ {
2
+ "properties": {
3
+ "day_open_schedule": {
4
+ "title": "Abre el día (cron)",
5
+ "description": "Cuándo corre el anclaje de la mañana. Cron de cinco campos, en la hora local de la máquina."
6
+ },
7
+ "day_close_schedule": {
8
+ "title": "Cierra el día (cron)",
9
+ "description": "Cuándo corre el anclaje de la tarde."
10
+ },
11
+ "nudge_budget_per_day": {
12
+ "title": "Mensajes no pedidos por día",
13
+ "description": "El tope fuera de los anclajes. Menos suele ser mejor. Declarar esto activa el presupuesto de interrupciones."
14
+ },
15
+ "quiet_hours": {
16
+ "title": "Horas de silencio",
17
+ "description": "Sin mensajes no pedidos en esta ventana. Las respuestas nunca se retienen."
18
+ },
19
+ "nudge_project_cooldown_minutes": {
20
+ "title": "Espacio mínimo por proyecto (minutos)",
21
+ "description": "Tres ideas sueltas sobre el mismo proyecto en una hora es una interrupción de más."
22
+ },
23
+ "nudge_kind_cooldown_minutes": {
24
+ "title": "Espacio mínimo por tipo (minutos)",
25
+ "description": "Evita que una condición que se repite llene el presupuesto del día ella sola."
26
+ },
27
+ "watch_schedule": {
28
+ "title": "Corre el watch (cron)",
29
+ "description": "Cada cuánto barre cosas que valga la pena notar entre los anclajes. Barato: si no hay nada que reportar, nunca despierta al modelo."
30
+ },
31
+ "calendar_command": {
32
+ "title": "Comando de calendario (opcional)",
33
+ "description": "Comando de shell que imprime la agenda de hoy. Su salida llega al anclaje de la mañana ya buscada, así que leerla no cuesta ni una llamada a herramienta ni un permiso. Vacío significa sin calendario, y el anclaje simplemente no dice nada de eso. Ejemplo: apx mcp run calendar list_events '{\"timeMin\":\"today\"}'"
34
+ },
35
+ "stale_project_days": {
36
+ "title": "Un proyecto queda inactivo tras (días)",
37
+ "description": "Días sin actividad registrada de tarea o compromiso antes de que valga mencionarlo."
38
+ },
39
+ "blocked_task_hours": {
40
+ "title": "Una tarea bloqueada queda trabada tras (horas)",
41
+ "description": "Bloqueada esta mañana es un estado de trabajo normal, no un problema."
42
+ },
43
+ "commitment_lead_hours": {
44
+ "title": "Avisar de una promesa con esta anticipación (horas)",
45
+ "description": "Cuánto antes de su fecha levantar un compromiso, mientras todavía hay tiempo de cumplirlo."
46
+ },
47
+ "primary_channel": {
48
+ "title": "Canal principal",
49
+ "description": "A dónde van los mensajes no pedidos por defecto."
50
+ },
51
+ "routine_delivery": {
52
+ "type": "string",
53
+ "enum": [
54
+ "telegram",
55
+ "web",
56
+ "telegram,web",
57
+ "none"
58
+ ],
59
+ "default": "telegram",
60
+ "title": "Dónde se entregan los anclajes",
61
+ "description": "Los mensajes de apertura y cierre los entrega el runtime a este canal, así llegan aunque el modelo se olvide de mandarlos. Con 'none' quedan solo en el registro."
62
+ },
63
+ "formality": {
64
+ "title": "Trato",
65
+ "description": "Solo tiene efecto en idiomas que lo distinguen (tú / vos / usted)."
66
+ }
67
+ }
68
+ }
@@ -43,6 +43,12 @@
43
43
  "title": "Watch runs (cron)",
44
44
  "description": "How often to sweep for things worth noticing between the anchors. Cheap: with nothing to report it never wakes the model."
45
45
  },
46
+ "calendar_command": {
47
+ "type": "string",
48
+ "default": "",
49
+ "title": "Calendar command (optional)",
50
+ "description": "Shell command that prints today's agenda. Its output reaches the morning anchor already fetched, so reading it costs no tool call and no permission. Blank means no calendar, and the anchor simply says nothing about one. Example: apx mcp run calendar list_events '{\"timeMin\":\"today\"}'"
51
+ },
46
52
  "stale_project_days": {
47
53
  "type": "integer",
48
54
  "default": 7,
@@ -63,14 +69,36 @@
63
69
  },
64
70
  "primary_channel": {
65
71
  "type": "string",
66
- "enum": ["telegram", "desktop", "cli", "web"],
72
+ "enum": [
73
+ "telegram",
74
+ "desktop",
75
+ "cli",
76
+ "web"
77
+ ],
67
78
  "default": "telegram",
68
79
  "title": "Primary channel",
69
80
  "description": "Where unrequested messages go by default."
70
81
  },
82
+ "routine_delivery": {
83
+ "type": "string",
84
+ "enum": [
85
+ "telegram",
86
+ "web",
87
+ "telegram,web",
88
+ "none"
89
+ ],
90
+ "default": "telegram",
91
+ "title": "Where the anchors are delivered",
92
+ "description": "The morning and evening messages are handed to this channel by the runtime, so they arrive whether or not the model remembers to send them. 'none' keeps them in the log only."
93
+ },
71
94
  "formality": {
72
95
  "type": "string",
73
- "enum": ["tu", "vos", "usted", "neutral"],
96
+ "enum": [
97
+ "tu",
98
+ "vos",
99
+ "usted",
100
+ "neutral"
101
+ ],
74
102
  "default": "neutral",
75
103
  "title": "Form of address",
76
104
  "description": "Only meaningful in languages that distinguish it."
@@ -11,7 +11,9 @@
11
11
  "provides": {
12
12
  "routines": [
13
13
  "day-open",
14
- "day-close"
14
+ "day-close",
15
+ "watch",
16
+ "a2a-sweep"
15
17
  ],
16
18
  "channels": [
17
19
  "routine"
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "a2a-sweep",
3
+ "kind": "watch",
4
+ "schedule": "*/20 * * * *",
5
+ "permission_mode": "permiso",
6
+ "enabled_by_default": true,
7
+ "spec": {
8
+ "prompt": "You are sweeping the agent-to-agent (a2a) inbox for {{owner_name}}. The signals below are messages other agents sent for them since the last sweep — facts, already gathered.\n\nDecide which, if any, are worth {{owner_name}} hearing RIGHT NOW versus folding into the next day-open/day-close brief. A `blocker` is urgent and crosses even quiet-hours; a `status` or `fyi` almost always waits for the brief. Most sweeps should stay quiet. A promise inside a message is already tracked as a commitment — do not repeat it here.\n\nIf you decide to speak, your reply IS the message: ONE line, second person, ready to read. This routine delivers what you write to {{owner_name}}'s channel — there is no send tool to call, and the interruption budget still applies (a blocker or a message they solicited crosses it; ordinary status/fyi is held when the budget says so). If you decide to stay quiet, do NOT write that decision as a message. Reply with `NO_MESSAGE` as the very first line and put your reasoning on the lines after it. The marker is what keeps it off {{owner_name}}'s phone and off their interruption budget; what you write after it is filed as a note they can go and read, not a message they receive.\n\nNote what you learned with remember_routine, especially when you stayed quiet.",
9
+ "types": [
10
+ "a2a_message"
11
+ ]
12
+ },
13
+ "deliver_to": [
14
+ "profile"
15
+ ],
16
+ "allowed_tools": [
17
+ "send_telegram",
18
+ "remember_routine"
19
+ ]
20
+ }
@@ -5,9 +5,12 @@
5
5
  "permission_mode": "permiso",
6
6
  "enabled_by_default": true,
7
7
  "spec": {
8
- "prompt": "Close the day, across every registered project.\n\nHOW TO SPEND YOUR STEPS. You get a small, fixed number of tool calls, and the LAST one is taken away from you to write your closing prose — so a turn spent exploring ends with nothing delivered. Gather with list_tasks and list_commitments (once each, no project argument) and NOTHING ELSE. Do not search sessions, do not read files, do not run shell commands: none of that is what {{owner_name}} asked for. Then send, immediately. Report what you actually have; an honest short message beats a complete one that never arrives.\n\nSend ONE short message with three things: what moved today, what is still stuck, and what carries over. Keep promises to people separate from ordinary tasks — if a commitment came due today, ask whether it was kept rather than marking it yourself. Note anything that has gone quiet longer than the staleness threshold. If the day was quiet, say that plainly in a line.\n\nDELIVERY: send_telegram. A routine's own output is only written to the log if you do not call the tool, {{owner_name}} receives nothing at all. One message, then stop.\n\nAfter sending, record with remember_routine anything durable you learned about how this person works — one line. Never write_file for this: a scheduled run has nobody to approve it and the whole turn dies there.",
8
+ "prompt": "Close the day, across every registered project.\n\nHOW TO SPEND YOUR STEPS. You get a small, fixed number of tool calls, and the LAST one is taken away from you to write your closing prose — so a turn spent exploring ends with nothing delivered. Gather with list_tasks and list_commitments (once each, no project argument) and NOTHING ELSE. Do not search sessions, do not read files, do not run shell commands: none of that is what {{owner_name}} asked for. Then send, immediately. Report what you actually have; an honest short message beats a complete one that never arrives.\n\nSend ONE short message with three things: what moved today, what is still stuck, and what carries over. Keep promises to people separate from ordinary tasks — if a commitment came due today, ask whether it was kept rather than marking it yourself. Note anything that has gone quiet longer than the staleness threshold. If the day was quiet, say that plainly in a line.\n\nDELIVERY: your closing message IS the message. This routine delivers what you write to the channel itself, so there is no send tool to call — write the last thing you say AS the message, in the second person, ready to read. One message, then stop.\n\nAfter sending, record with remember_routine anything durable you learned about how this person works — one line. Never write_file for this: a scheduled run has nobody to approve it and the whole turn dies there.",
9
9
  "anchor": true
10
10
  },
11
+ "deliver_to": [
12
+ "profile"
13
+ ],
11
14
  "allowed_tools": [
12
15
  "send_telegram"
13
16
  ]
@@ -5,10 +5,16 @@
5
5
  "permission_mode": "permiso",
6
6
  "enabled_by_default": true,
7
7
  "spec": {
8
- "prompt": "Open the day. Look at what is due today, what is overdue, what is blocked, and what is promised, across every registered project. HOW TO SPEND YOUR STEPS. You get a small, fixed number of tool calls, and the LAST one is taken away from you to write your closing prose — so a turn spent exploring ends with nothing delivered. Gather with list_tasks and list_commitments (once each, no project argument) and NOTHING ELSE. Do not search sessions, do not read files, do not run shell commands: none of that is what {{owner_name}} asked for. Then send, immediately. Report what you actually have; an honest short message beats a complete one that never arrives. Lead with promises: a broken promise costs more than a late task, so it goes first and is named as a promise to a person, never folded into the task list.\n\nThen send ONE short message: promises coming due or already past, what is due today, anything on the calendar, and the single thing that most deserves attention. Not an inventory.\n\nIf there is genuinely nothing pressing, say so in one line — and then do the thing a chief of staff does with an empty morning: ask what should go on today's list, or name the one stale project worth picking up. An empty day is a prompt, not a silence.\n\nDELIVERY: send it with send_telegram. A routine's own output is only written to the log if you do not call the tool, {{owner_name}} receives nothing at all. Send exactly one message, then stop; do not end the turn by asking whether to keep looking.",
8
+ "prompt": "Open the day. Look at what is due today, what is overdue, what is blocked, and what is promised, across every registered project. HOW TO SPEND YOUR STEPS. You get a small, fixed number of tool calls, and the LAST one is taken away from you to write your closing prose — so a turn spent exploring ends with nothing delivered. Gather with list_tasks and list_commitments (once each, no project argument) and NOTHING ELSE. Do not search sessions, do not read files, do not run shell commands: none of that is what {{owner_name}} asked for. Then send, immediately. Report what you actually have; an honest short message beats a complete one that never arrives. Lead with promises: a broken promise costs more than a late task, so it goes first and is named as a promise to a person, never folded into the task list.\n\nTODAY'S AGENDA — already fetched for you, below, at the cost of zero steps:\n<calendar>\n{{pre_output}}\n</calendar>\nIf that block is empty, no calendar is connected: say nothing about the calendar at all, and do not apologise for not having one. If it carries an error rather than an agenda, treat it the same way. Never name a meeting that is not written there.\n\nThen send ONE short message: promises coming due or already past, what is due today, anything on the calendar, and the single thing that most deserves attention. Not an inventory.\n\nIf there is genuinely nothing pressing, say so in one line — and then do the thing a chief of staff does with an empty morning: ask what should go on today's list, or name the one stale project worth picking up. An empty day is a prompt, not a silence.\n\nDELIVERY: your closing message IS the message. This routine delivers what you write to the channel itself, so there is no send tool to call and nothing is lost if you forget one write the last thing you say AS the message, in the second person, ready to read. Then stop; do not end the turn by asking whether to keep looking.",
9
9
  "anchor": true
10
10
  },
11
+ "deliver_to": [
12
+ "profile"
13
+ ],
11
14
  "allowed_tools": [
12
15
  "send_telegram"
16
+ ],
17
+ "pre_commands": [
18
+ "{{calendar_command}}"
13
19
  ]
14
20
  }
@@ -5,9 +5,20 @@
5
5
  "permission_mode": "permiso",
6
6
  "enabled_by_default": true,
7
7
  "spec": {
8
- "prompt": "You are watching {{owner_name}}'s projects between the anchors. The signals below were detected deterministically — they are facts, already gathered; you do not need to look them up again.\n\nDecide whether any of it is worth interrupting for RIGHT NOW rather than waiting for the next anchor. Staying quiet is the normal outcome and costs you nothing. A message that could have waited until tomorrow morning costs you the next one, because that is the one they will not open.\n\nIf you do speak: send ONE line naming the single most important thing and what you suggest doing about it, with send_telegram. DELIVERY: send it with send_telegram. A routine's own output is only written to the log if you do not call the tool, {{owner_name}} receives nothing at all. If you decide to stay quiet, just say so in your reply and call nothing.\n\nWhichever you choose, note what you learned with remember_routine — especially when you stayed quiet, because next time you need to know this kind of signal was not worth it."
8
+ "prompt": "You are watching {{owner_name}}'s projects between the anchors. The signals below were detected deterministically — they are facts, already gathered; you do not need to look them up again.\n\nDecide whether any of it is worth interrupting for RIGHT NOW rather than waiting for the next anchor. Staying quiet is the normal outcome and costs you nothing. A message that could have waited until tomorrow morning costs you the next one, because that is the one they will not open.\n\nIf you decide to speak, your reply IS the message: write ONE line naming the single most important thing and what you suggest doing about it, in the second person, ready to read. This routine delivers what you write to {{owner_name}}'s channel itself — there is no send tool to call and nothing is lost if you forget one. If you decide to stay quiet, do NOT write that decision as a message. Reply with `NO_MESSAGE` as the very first line and put your reasoning on the lines after it. The marker is what keeps it off {{owner_name}}'s phone and off their interruption budget; what you write after it is filed as a note they can go and read, not a message they receive.\n\nWhichever you choose, note what you learned with remember_routine — especially when you stayed quiet, because next time you need to know this kind of signal was not worth it.",
9
+ "types": [
10
+ "overdue_task",
11
+ "blocked_task",
12
+ "stale_project",
13
+ "commitment_due",
14
+ "overdue_commitment"
15
+ ]
9
16
  },
17
+ "deliver_to": [
18
+ "profile"
19
+ ],
10
20
  "allowed_tools": [
11
- "send_telegram"
21
+ "send_telegram",
22
+ "remember_routine"
12
23
  ]
13
24
  }
@@ -15,6 +15,8 @@ import { readConfig, writeConfig } from "../config/index.js";
15
15
  import { projectStorageRoot, DEFAULT_PROJECT_ID } from "../config/paths.js";
16
16
  import { readIdentity } from "../identity/index.js";
17
17
  import { renderPromptTemplate } from "../agent/render-template.js";
18
+ import { getPluginService } from "../integrations/catalog.js";
19
+ import { resolveIntegration } from "../integrations/store.js";
18
20
  import {
19
21
  listRoutines,
20
22
  upsertRoutine,
@@ -45,6 +47,7 @@ import {
45
47
  } from "./store.js";
46
48
  import {
47
49
  renderProfilePrompt,
50
+ profileTemplateVars,
48
51
  clearProfileBlockCache,
49
52
  validateTemplateVars,
50
53
  profileChannelFile,
@@ -74,6 +77,12 @@ function routineFingerprint(r) {
74
77
  pre_commands: r?.pre_commands || [],
75
78
  post_commands: r?.post_commands || [],
76
79
  skip_prompt_on: r?.skip_prompt_on || "signal",
80
+ // Added LAST and only when set, so the digest of every routine installed
81
+ // before delivery existed is byte-identical to the one stored beside it.
82
+ // Folding an always-present `deliver_to: null` into the canonical object
83
+ // would change every stored hash at once, and every package routine would
84
+ // read as "the user edited this" and never be updated again.
85
+ ...(r?.deliver_to?.length ? { deliver_to: r.deliver_to } : {}),
77
86
  };
78
87
  return crypto.createHash("sha256").update(JSON.stringify(canonical)).digest("hex").slice(0, 16);
79
88
  }
@@ -353,27 +362,84 @@ export function installProfile(source, { force = false } = {}) {
353
362
 
354
363
  // --------------------- routines ---------------------------------------------
355
364
 
365
+ /**
366
+ * Placeholders that belong to the routine RUNTIME, not to this renderer.
367
+ * `{{pre_output}}` is filled by core/routines/runner.js with the stdout of
368
+ * pre_commands, moments before the handler runs. Rendering happens at install
369
+ * time, long before that, and an unknown variable renders as "" — so without
370
+ * this identity mapping a profile could never hand its pre_commands output to
371
+ * its own prompt.
372
+ */
373
+ const RUNTIME_PLACEHOLDERS = Object.freeze({ pre_output: "{{pre_output}}" });
374
+
375
+ /**
376
+ * A rendered shell command that came out empty is a setting the user left
377
+ * blank, not a command to run. Keeping it would hand runner.js a `""` to
378
+ * execute and, worse, make `hasPreCmds` true — which changes how the routine
379
+ * behaves (skip_prompt_on, {{pre_output}}) for a step that does nothing.
380
+ */
381
+ function dropBlankCommands(spec) {
382
+ const out = { ...spec };
383
+ for (const key of ["pre_commands", "post_commands"]) {
384
+ if (!Array.isArray(out[key])) continue;
385
+ const kept = out[key].filter((c) => typeof c === "string" && c.trim() !== "");
386
+ if (kept.length) out[key] = kept;
387
+ else delete out[key];
388
+ }
389
+ return out;
390
+ }
391
+
392
+ /** Render every string leaf of a parsed value, leaving keys and non-strings alone. */
393
+ function renderDeep(value, settings) {
394
+ if (typeof value === "string") return renderPromptTemplate(value, settings);
395
+ if (Array.isArray(value)) return value.map((v) => renderDeep(v, settings));
396
+ if (value && typeof value === "object") {
397
+ return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, renderDeep(v, settings)]));
398
+ }
399
+ return value;
400
+ }
401
+
356
402
  /** The profile's routine specs, rendered against its effective settings. */
357
403
  export function renderProfileRoutines(profile, globalConfig) {
358
404
  const dir = path.join(profile.dir, "routines");
359
405
  if (!fs.existsSync(dir)) return [];
360
406
 
361
- const settings = effectiveProfileConfig(profile, globalConfig);
407
+ // The SAME variables PROFILE.md gets — settings plus the read-only facts from
408
+ // identity.json. Rendering routines with settings alone left `{{owner_name}}`
409
+ // empty in every routine that used it, which is how the Secretary's anchor
410
+ // came to tell the model "none of that is what asked for".
411
+ const identity = (() => { try { return readIdentity(); } catch { return null; } })();
412
+ const settings = {
413
+ ...profileTemplateVars(profile, identity, globalConfig),
414
+ ...RUNTIME_PLACEHOLDERS,
415
+ };
362
416
  const out = [];
363
417
 
364
418
  for (const file of fs.readdirSync(dir).filter((f) => f.endsWith(".json")).sort()) {
419
+ const text = fs.readFileSync(path.join(dir, file), "utf8");
365
420
  let raw;
366
421
  try {
367
- raw = JSON.parse(renderPromptTemplate(fs.readFileSync(path.join(dir, file), "utf8"), settings));
368
- } catch (e) {
369
- throw new Error(`profile "${profile.id}": routines/${file} is not valid JSON after rendering — ${e.message}`);
422
+ // Parse FIRST, then render the string leaves. Rendering the file text
423
+ // instead lets a setting decide where the document ends: one double quote
424
+ // in a value `apx mcp run cal list '{"day":"today"}'` is the realistic
425
+ // one — and the routine stops being JSON.
426
+ raw = renderDeep(JSON.parse(text), settings);
427
+ } catch {
428
+ // Unless the file is not JSON until it IS rendered, which is what a
429
+ // placeholder in an unquoted position (`"timeout": {{secs}}`) means. That
430
+ // shape predates the safe path, so it keeps working the old way.
431
+ try {
432
+ raw = JSON.parse(renderPromptTemplate(text, settings));
433
+ } catch (e) {
434
+ throw new Error(`profile "${profile.id}": routines/${file} is not valid JSON after rendering — ${e.message}`);
435
+ }
370
436
  }
371
437
  if (!raw?.name || !raw?.kind || !raw?.schedule) {
372
438
  throw new Error(`profile "${profile.id}": routines/${file} needs name, kind and schedule`);
373
439
  }
374
440
  // Namespaced, because `name` is the real primary key of the routines store
375
441
  // and a profile must never collide with a routine the user wrote.
376
- out.push({ ...raw, name: `${profile.id}-${raw.name}` });
442
+ out.push({ ...dropBlankCommands(raw), name: `${profile.id}-${raw.name}` });
377
443
  }
378
444
  return out;
379
445
  }
@@ -433,6 +499,44 @@ export function syncProfileRoutines(profile, globalConfig, { enable = true } = {
433
499
  return { installed, skipped };
434
500
  }
435
501
 
502
+ /**
503
+ * Force the profile's routines back to the package version, discarding local
504
+ * edits and repairing provenance. This is what sync CANNOT do: sync deliberately
505
+ * skips a routine the user edited (`user_modified`) or one whose profile origin
506
+ * was lost (`user_owned`), so a routine that drifted — a hand-patched schedule,
507
+ * or an `origin` gone null after an old migration — never picks up a new package
508
+ * field like `deliver_to`. Re-adopt overwrites by NAME: the package spec wins,
509
+ * `origin`/`origin_hash` are rewritten so it reads as "exactly as installed"
510
+ * again, and the run history (`last_run_at`) is preserved by upsertRoutine.
511
+ *
512
+ * @param {{ only?: string|null }} opts one routine name, or null for all.
513
+ * @returns {{ readopted: string[] }}
514
+ */
515
+ export function readoptProfileRoutines(profile, globalConfig, { only = null } = {}) {
516
+ const storage = superAgentStorage();
517
+ const specs = renderProfileRoutines(profile, globalConfig);
518
+ const existing = listRoutines(storage);
519
+ const origin = profileOrigin(profile.id);
520
+
521
+ const readopted = [];
522
+ for (const spec of specs) {
523
+ const { name, enabled_by_default, ...rest } = spec;
524
+ if (only && name !== only) continue;
525
+ const prev = existing.find((r) => r.name === name);
526
+ upsertRoutine(storage, {
527
+ ...rest,
528
+ name,
529
+ // Keep whether the user had it switched off — re-adopt is about behaviour
530
+ // and provenance, not about turning a routine back on behind their back.
531
+ enabled: prev ? prev.enabled !== false : enabled_by_default !== false,
532
+ origin,
533
+ origin_hash: routineFingerprint(rest),
534
+ });
535
+ readopted.push(name);
536
+ }
537
+ return { readopted };
538
+ }
539
+
436
540
  /** Disable — never delete — the routines a profile installed. */
437
541
  export function disableProfileRoutines(profileId) {
438
542
  const storage = superAgentStorage();
@@ -554,6 +658,59 @@ export function setProfileConfig(values, { id = null } = {}) {
554
658
  return { config: settings, changed: Object.keys(value), routines };
555
659
  }
556
660
 
661
+ /**
662
+ * Re-install the active profile's routines from the package as it is on disk
663
+ * TODAY, without touching settings or activation.
664
+ *
665
+ * A bundled package improves with every APX update, but the routines it
666
+ * installs are records in the super-agent's store, frozen at install time. So
667
+ * an owner who installed the Secretary in June kept June's anchors for good —
668
+ * the improved prompt shipped, and nothing carried it across. The only paths
669
+ * that re-rendered were `use` and changing a setting, neither of which is a
670
+ * thing you would think to run after a `git pull`.
671
+ *
672
+ * Routines the owner edited are still skipped: their fingerprint no longer
673
+ * matches the one taken at install, and that is the whole point of the check.
674
+ */
675
+ export function syncProfile(id = null) {
676
+ const cfg = readConfig();
677
+ const state = readProfileState(cfg);
678
+ const targetId = id || state.active;
679
+ if (!targetId) throw new Error("no profile is active — run: apx profile use <id>");
680
+
681
+ const profile = readProfile(targetId);
682
+ if (!profile) throw new Error(`profile "${targetId}" is not installed`);
683
+ if (state.active !== targetId) {
684
+ throw new Error(`profile "${targetId}" is not active — its routines are not installed`);
685
+ }
686
+
687
+ clearProfileBlockCache();
688
+ return { id: targetId, version: profile.manifest?.version || null, routines: syncProfileRoutines(profile, cfg) };
689
+ }
690
+
691
+ /**
692
+ * Re-adopt the active profile's routines from the package, forcing past the
693
+ * user_modified/user_owned skips that sync respects. `only` targets one routine
694
+ * (the per-warning "re-adopt this one" button); omit it to re-adopt all. This is
695
+ * the recovery path a non-CLI user needs when their installed routines drifted —
696
+ * see readoptProfileRoutines.
697
+ */
698
+ export function readoptProfile(id = null, { only = null } = {}) {
699
+ const cfg = readConfig();
700
+ const state = readProfileState(cfg);
701
+ const targetId = id || state.active;
702
+ if (!targetId) throw new Error("no profile is active — run: apx profile use <id>");
703
+
704
+ const profile = readProfile(targetId);
705
+ if (!profile) throw new Error(`profile "${targetId}" is not installed`);
706
+ if (state.active !== targetId) {
707
+ throw new Error(`profile "${targetId}" is not active — its routines are not installed`);
708
+ }
709
+
710
+ clearProfileBlockCache();
711
+ return { id: targetId, version: profile.manifest?.version || null, ...readoptProfileRoutines(profile, cfg, { only }) };
712
+ }
713
+
557
714
  // --------------------- doctor -----------------------------------------------
558
715
 
559
716
  /**
@@ -562,11 +719,17 @@ export function setProfileConfig(values, { id = null } = {}) {
562
719
  */
563
720
  export function profileDoctor(id = null) {
564
721
  const cfg = readConfig();
722
+ // The doctor is owner-facing UI, so its prose follows the owner's language —
723
+ // unlike the prompt block, which is instructions to the model and stays
724
+ // English. `fix` values are literal CLI commands and are NOT translated; only
725
+ // the human sentences around them are.
726
+ const es = /^es(-|$)/.test(String(cfg.user?.language || "en").toLowerCase());
727
+ const L = (esStr, enStr) => (es ? esStr : enStr);
565
728
  const state = readProfileState(cfg);
566
729
  const targetId = id || state.active;
567
730
 
568
731
  if (!targetId) {
569
- return { id: null, active: false, ok: true, checks: [], summary: "No profile active (vanilla)." };
732
+ return { id: null, active: false, ok: true, checks: [], summary: L("No hay perfil activo (vanilla).", "No profile active (vanilla).") };
570
733
  }
571
734
 
572
735
  const profile = readProfile(targetId);
@@ -575,8 +738,8 @@ export function profileDoctor(id = null) {
575
738
  id: targetId,
576
739
  active: false,
577
740
  ok: false,
578
- checks: [{ level: "error", label: "package", detail: `not installed`, fix: `apx profile install ${targetId}` }],
579
- summary: `profile "${targetId}" is not installed`,
741
+ checks: [{ level: "error", label: "package", detail: L("no está instalado", "not installed"), fix: `apx profile install ${targetId}` }],
742
+ summary: L(`el perfil "${targetId}" no está instalado`, `profile "${targetId}" is not installed`),
580
743
  };
581
744
  }
582
745
 
@@ -595,7 +758,7 @@ export function profileDoctor(id = null) {
595
758
  checks.push({
596
759
  level: "warn",
597
760
  label: "channel",
598
- detail: `Telegram is not configured — the profile cannot reach you there`,
761
+ detail: L("Telegram no está configurado — el perfil no puede alcanzarte ahí", "Telegram is not configured — the profile cannot reach you there"),
599
762
  fix: "apx telegram setup",
600
763
  });
601
764
  }
@@ -603,14 +766,36 @@ export function profileDoctor(id = null) {
603
766
  }
604
767
 
605
768
  // Integrations. Required ones block; optional ones degrade.
769
+ //
770
+ // A profile may name an integration APX has no plugin for — `calendar` is the
771
+ // live case. `apx integration connect calendar` cannot work and never will
772
+ // until a plugin exists, so pointing at it is worse than saying nothing:
773
+ // the reader spends their time on a command that returns "unknown plugin".
774
+ // Those slugs get the path that does exist, which is MCP.
775
+ const integrationFix = (slug) =>
776
+ getPluginService(slug)
777
+ ? `apx integration connect ${slug}`
778
+ : `apx mcp add ${slug} --scope global --command <cmd> -- <args>`;
779
+ const integrationDetail = (slug, suffix) =>
780
+ getPluginService(slug)
781
+ ? L(`${slug} no está conectado — ${suffix}`, `${slug} is not connected — ${suffix}`)
782
+ : L(`${slug} no tiene plugin nativo — alcanzalo con un servidor MCP; ${suffix}`, `${slug} has no built-in plugin — reach it through an MCP server; ${suffix}`);
783
+
784
+ // Integrations live in per-project stores (~/.apx/projects/<id>/integrations.json),
785
+ // with project→default precedence — NOT in a global `config.integrations`, which
786
+ // is null on a normal install. Checking the config object reported "calendar is
787
+ // not connected" while a connected Google Calendar sat in the default project.
788
+ // resolveIntegration() looks where they actually are, so a calendar connected at
789
+ // the (default) project level counts as connected for the super-agent.
790
+ const integrationConnected = (slug) => !!resolveIntegration({ slug });
606
791
  for (const slug of requires.integrations || []) {
607
- if (!cfg.integrations?.[slug]) {
608
- checks.push({ level: "error", label: "integration", detail: `${slug} is required and not connected`, fix: `apx integration connect ${slug}` });
792
+ if (!integrationConnected(slug)) {
793
+ checks.push({ level: "error", label: "integration", detail: integrationDetail(slug, L("el perfil lo requiere", "the profile requires it")), fix: integrationFix(slug) });
609
794
  }
610
795
  }
611
796
  for (const slug of requires.optional_integrations || []) {
612
- if (!cfg.integrations?.[slug]) {
613
- checks.push({ level: "warn", label: "integration", detail: `${slug} is not connected the profile degrades without it`, fix: `apx integration connect ${slug}` });
797
+ if (!integrationConnected(slug)) {
798
+ checks.push({ level: "warn", label: "integration", detail: integrationDetail(slug, L("el perfil se degrada sin esto", "the profile degrades without it")), fix: integrationFix(slug) });
614
799
  }
615
800
  }
616
801
 
@@ -621,7 +806,7 @@ export function profileDoctor(id = null) {
621
806
  checks.push({
622
807
  level: "warn",
623
808
  label: "capability",
624
- detail: `"${cap}" is not provided by this APX version — the profile degrades`,
809
+ detail: L(`"${cap}" no la provee esta versión de APX — el perfil se degrada`, `"${cap}" is not provided by this APX version — the profile degrades`),
625
810
  fix: null,
626
811
  });
627
812
  }
@@ -630,9 +815,48 @@ export function profileDoctor(id = null) {
630
815
  // Routines it installed that are currently off.
631
816
  if (state.active === targetId) {
632
817
  const origin = profileOrigin(targetId);
633
- const off = listRoutines(superAgentStorage()).filter((r) => r.origin === origin && !r.enabled);
634
- for (const r of off) {
635
- checks.push({ level: "warn", label: "routine", detail: `"${r.name}" is disabled`, fix: `apx routine enable ${r.name}` });
818
+ const installed = listRoutines(superAgentStorage()).filter((r) => r.origin === origin);
819
+ for (const r of installed.filter((r) => !r.enabled)) {
820
+ checks.push({ level: "warn", label: "routine", detail: L(`"${r.name}" está deshabilitada`, `"${r.name}" is disabled`), fix: `apx routine enable ${r.name}` });
821
+ }
822
+
823
+ // Routines that no longer match the package they came from. Worth saying
824
+ // out loud because nothing announces it: the package improves with every
825
+ // APX update while the installed record stays exactly as it was, and a
826
+ // profile setting that lands in a routine (the Secretary's
827
+ // `calendar_command`) silently does nothing until one of them moves.
828
+ try {
829
+ const rendered = renderProfileRoutines(profile, cfg);
830
+ for (const spec of rendered) {
831
+ const prev = installed.find((r) => r.name === spec.name);
832
+ if (!prev) continue;
833
+ const { name, enabled_by_default, ...rest } = spec;
834
+ if (routineFingerprint(rest) === routineFingerprint(prev)) continue;
835
+
836
+ const edited = prev.origin_hash && routineFingerprint(prev) !== prev.origin_hash;
837
+ checks.push(edited
838
+ ? {
839
+ level: "warn",
840
+ label: "routine",
841
+ // `routine` names the record so a UI can offer a targeted re-adopt
842
+ // (POST /profiles/readopt {routine}) next to this exact warning.
843
+ routine: name,
844
+ // Their edits win — that is the contract. But a routine that sync
845
+ // will always skip is one they now maintain themselves, and they
846
+ // should hear that while they can still decide otherwise.
847
+ detail: L(`"${name}" ahora es tuya (la editaste) y el paquete avanzó — sync la va a seguir salteando`, `"${name}" is yours now (you edited it) and the package has moved on — sync will keep skipping it`),
848
+ fix: L(`apx routine show ${name} # editala, o borrala y corré: apx profile sync`, `apx routine show ${name} # then edit it, or delete it and run: apx profile sync`),
849
+ }
850
+ : {
851
+ level: "warn",
852
+ label: "routine",
853
+ routine: name,
854
+ detail: L(`"${name}" es más vieja que el paquete que la instaló`, `"${name}" is older than the package that installed it`),
855
+ fix: "apx profile sync",
856
+ });
857
+ }
858
+ } catch {
859
+ /* a package that no longer renders is already reported by validate */
636
860
  }
637
861
  }
638
862
 
@@ -645,8 +869,8 @@ export function profileDoctor(id = null) {
645
869
  budget: profile.manifest?.prompt_budget_tokens || null,
646
870
  checks,
647
871
  summary: errors === 0
648
- ? `profile "${targetId}" is healthy${checks.length ? ` (${checks.length} warning(s))` : ""}`
649
- : `profile "${targetId}" has ${errors} blocking problem(s)`,
872
+ ? L(`el perfil "${targetId}" está sano${checks.length ? ` (${checks.length} advertencia(s))` : ""}`, `profile "${targetId}" is healthy${checks.length ? ` (${checks.length} warning(s))` : ""}`)
873
+ : L(`el perfil "${targetId}" tiene ${errors} problema(s) que bloquean`, `profile "${targetId}" has ${errors} blocking problem(s)`),
650
874
  };
651
875
  }
652
876
 
@@ -49,3 +49,15 @@ export function promptFileFor(lang) {
49
49
  if (!code || code.toLowerCase() === "en") return PROMPT_FILE;
50
50
  return `PROFILE.${code}.md`;
51
51
  }
52
+
53
+ /**
54
+ * Language-specific settings-schema filename: config.schema.es.json, …
55
+ * Mirrors promptFileFor. The localized file carries only display strings
56
+ * (title/description); types, defaults and enums stay in the base schema, which
57
+ * is the single source of truth for validation.
58
+ */
59
+ export function schemaFileFor(lang) {
60
+ const code = String(lang || "").trim();
61
+ if (!code || code.toLowerCase() === "en") return CONFIG_SCHEMA_FILE;
62
+ return `config.schema.${code}.json`;
63
+ }