@agentprojectcontext/apx 1.81.0 → 1.89.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (838) hide show
  1. package/package.json +9 -8
  2. package/skills/apc-context/SKILL.md +14 -7
  3. package/skills/apx/SKILL.md +62 -2
  4. package/skills/apx-mcp/SKILL.md +42 -15
  5. package/src/core/agent/a2a/peers.js +161 -0
  6. package/src/core/agent/a2a/reply.js +379 -27
  7. package/src/core/agent/abort.js +25 -0
  8. package/src/core/agent/agent-model.js +58 -0
  9. package/src/core/agent/agent-tools.js +101 -0
  10. package/src/core/agent/author-line.js +110 -0
  11. package/src/core/agent/build-agent-system.js +52 -18
  12. package/src/core/agent/channels/voice-context.js +17 -2
  13. package/src/core/agent/closing-floor.js +117 -0
  14. package/src/core/agent/constants.js +119 -11
  15. package/src/core/agent/engine-call.js +56 -0
  16. package/src/core/agent/group/run-group-turn.js +218 -0
  17. package/src/core/agent/group/turn-resolver.js +165 -0
  18. package/src/core/agent/judge.js +138 -11
  19. package/src/core/agent/loop/side-effects.js +106 -3
  20. package/src/core/agent/memory.js +31 -18
  21. package/src/core/agent/model-capabilities.js +47 -0
  22. package/src/core/agent/model-router.js +11 -40
  23. package/src/core/agent/prompt-builder.js +47 -0
  24. package/src/core/agent/prompts/channels/a2a.md +12 -0
  25. package/src/core/agent/prompts/channels/code.md +3 -1
  26. package/src/core/agent/prompts/channels/telegram.md +2 -0
  27. package/src/core/agent/prompts/channels/web_code.md +1 -1
  28. package/src/core/agent/prompts/channels/whatsapp.md +37 -0
  29. package/src/core/agent/prompts/core/agent-base.md +2 -0
  30. package/src/core/agent/prompts/discipline/action.md +1 -0
  31. package/src/core/agent/prompts/discipline/two-segment.md +2 -1
  32. package/src/core/agent/prompts/modes/mobility.md +36 -0
  33. package/src/core/agent/retry.js +42 -0
  34. package/src/core/agent/run-agent.js +322 -25
  35. package/src/core/agent/run-turn.js +253 -0
  36. package/src/core/agent/self-memory.js +18 -52
  37. package/src/core/agent/skills/agent-skills.js +118 -0
  38. package/src/core/agent/skills/catalog.js +1 -1
  39. package/src/core/agent/skills/declared.js +13 -0
  40. package/src/core/agent/skills/index-store.js +8 -1
  41. package/src/core/agent/skills/inspector.js +20 -3
  42. package/src/core/agent/skills/loader.js +18 -3
  43. package/src/core/agent/skills/media.js +121 -0
  44. package/src/core/agent/skills/origin.js +61 -0
  45. package/src/core/agent/skills/sections.js +136 -0
  46. package/src/core/agent/super-agent.js +54 -14
  47. package/src/core/agent/tools/handlers/_calendar.js +50 -0
  48. package/src/core/agent/tools/handlers/add-mcp.js +103 -0
  49. package/src/core/agent/tools/handlers/asana-create-task.js +3 -1
  50. package/src/core/agent/tools/handlers/attach-media.js +56 -0
  51. package/src/core/agent/tools/handlers/calendar-create-event.js +38 -0
  52. package/src/core/agent/tools/handlers/calendar-find-slot.js +39 -0
  53. package/src/core/agent/tools/handlers/calendar-list-events.js +39 -0
  54. package/src/core/agent/tools/handlers/calendar-update-event.js +35 -0
  55. package/src/core/agent/tools/handlers/call-agent.js +14 -6
  56. package/src/core/agent/tools/handlers/call-runtime.js +27 -49
  57. package/src/core/agent/tools/handlers/comment-task.js +78 -0
  58. package/src/core/agent/tools/handlers/complete-task.js +60 -0
  59. package/src/core/agent/tools/handlers/configure-agent.js +70 -0
  60. package/src/core/agent/tools/handlers/create-agent.js +68 -0
  61. package/src/core/agent/tools/handlers/create-task.js +41 -3
  62. package/src/core/agent/tools/handlers/import-agent.js +5 -5
  63. package/src/core/agent/tools/handlers/list-mcp-tools.js +83 -0
  64. package/src/core/agent/tools/handlers/list-routines.js +46 -0
  65. package/src/core/agent/tools/handlers/list-tasks.js +8 -1
  66. package/src/core/agent/tools/handlers/mark-commitment.js +57 -0
  67. package/src/core/agent/tools/handlers/read-skill.js +64 -0
  68. package/src/core/agent/tools/handlers/remember-routine.js +2 -8
  69. package/src/core/agent/tools/handlers/remember.js +82 -6
  70. package/src/core/agent/tools/handlers/remove-agent.js +42 -0
  71. package/src/core/agent/tools/handlers/run-routine.js +94 -0
  72. package/src/core/agent/tools/handlers/run-shell.js +44 -2
  73. package/src/core/agent/tools/handlers/send-telegram.js +41 -19
  74. package/src/core/agent/tools/handlers/set-agent-prompt.js +44 -0
  75. package/src/core/agent/tools/handlers/view-media.js +69 -0
  76. package/src/core/agent/tools/handlers/write-agent-memory.js +52 -0
  77. package/src/core/agent/tools/helpers.js +36 -4
  78. package/src/core/agent/tools/names.js +64 -0
  79. package/src/core/agent/tools/registry-bridge.js +24 -1
  80. package/src/core/agent/tools/registry.js +79 -0
  81. package/src/core/agent/tools/tool-call-parser.js +136 -13
  82. package/src/core/agent/vision-bridge.js +69 -0
  83. package/src/core/apc/agent-identity.js +74 -0
  84. package/src/core/apc/agent-rename-refs.js +187 -0
  85. package/src/core/apc/agent-write.js +312 -0
  86. package/src/core/apc/agents-vault.js +1 -1
  87. package/src/core/apc/blob-keys.js +42 -0
  88. package/src/core/apc/frontmatter.js +166 -10
  89. package/src/core/apc/parser.js +33 -83
  90. package/src/core/apc/paths.js +4 -6
  91. package/src/core/apc/project-memory.js +44 -0
  92. package/src/core/apc/projects-helpers.js +33 -0
  93. package/src/core/apc/scaffold.js +36 -16
  94. package/src/core/channels/telegram/ask-callbacks.js +103 -0
  95. package/src/core/channels/telegram/dispatch.js +154 -30
  96. package/src/core/channels/telegram/helpers.js +59 -7
  97. package/src/core/channels/telegram/inbound/audio.js +26 -30
  98. package/src/core/channels/telegram/inbound/file.js +22 -32
  99. package/src/core/channels/telegram/inbound/photo.js +24 -28
  100. package/src/core/channels/telegram/progress-gate.js +76 -0
  101. package/src/core/channels/telegram/reply.js +151 -43
  102. package/src/core/channels/telegram/voice-note.js +150 -0
  103. package/src/core/config/index.js +53 -54
  104. package/src/core/config/paths.js +117 -31
  105. package/src/core/config/redact.js +89 -4
  106. package/src/core/config/secret-values.js +2 -4
  107. package/src/core/constants/actors.js +5 -0
  108. package/src/core/constants/channels.js +3 -1
  109. package/src/core/constants/task-categories.js +73 -0
  110. package/src/core/constants/task-fields.js +28 -0
  111. package/src/core/engines/_globs.js +33 -0
  112. package/src/core/engines/anthropic.js +19 -1
  113. package/src/core/engines/catalog.js +20 -0
  114. package/src/core/engines/gemini.js +84 -16
  115. package/src/core/engines/index.js +19 -3
  116. package/src/core/engines/mock.js +145 -1
  117. package/src/core/engines/openai-compatible.js +150 -15
  118. package/src/core/engines/presets.js +36 -9
  119. package/src/core/engines/zen.js +131 -0
  120. package/src/core/events/bus.js +140 -0
  121. package/src/core/events/mascot-notify.js +156 -0
  122. package/src/core/http-tools/browser.js +366 -36
  123. package/src/core/http-tools/catalog.js +206 -22
  124. package/src/core/http-tools/grep.js +62 -7
  125. package/src/core/http-tools/registry.js +3 -1
  126. package/src/core/i18n/en.js +34 -3
  127. package/src/core/i18n/es.js +36 -4
  128. package/src/core/i18n/index.js +5 -5
  129. package/src/core/i18n/pt.js +32 -3
  130. package/src/core/identity/self.js +14 -1
  131. package/src/core/images/engines/a1111.js +219 -0
  132. package/src/core/images/engines/index.js +187 -0
  133. package/src/core/images/engines/mock.js +74 -0
  134. package/src/core/images/engines/openai.js +130 -0
  135. package/src/core/images/engines/sdcpp.js +204 -0
  136. package/src/core/images/engines/shared.js +218 -0
  137. package/src/core/images/generate.js +260 -0
  138. package/src/core/integrations/catalog.js +8 -3
  139. package/src/core/integrations/plugins/_google-oauth.js +179 -0
  140. package/src/core/integrations/plugins/asana.js +7 -3
  141. package/src/core/integrations/plugins/calendar.js +404 -0
  142. package/src/core/integrations/store.js +2 -0
  143. package/src/core/memory/broker.js +16 -1
  144. package/src/core/memory/compactor.js +19 -3
  145. package/src/core/memory/consolidate.js +2 -2
  146. package/src/core/memory/dated-log.js +66 -0
  147. package/src/core/memory/embed-engines/custom.js +59 -0
  148. package/src/core/memory/embed-engines/gemini.js +9 -3
  149. package/src/core/memory/embed-engines/index.js +87 -15
  150. package/src/core/memory/embeddings.js +52 -24
  151. package/src/core/memory/index.js +13 -3
  152. package/src/core/memory/indexer.js +83 -27
  153. package/src/core/memory/prune.js +182 -0
  154. package/src/core/memory/store.js +22 -0
  155. package/src/core/memory/summarizer.js +72 -8
  156. package/src/core/mobility/answer.js +80 -0
  157. package/src/core/mobility/geofence.js +667 -0
  158. package/src/core/mobility/osm-route.js +282 -0
  159. package/src/core/mobility/preferences.js +91 -0
  160. package/src/core/mobility/state.js +245 -0
  161. package/src/core/mobility/trip-event.js +384 -0
  162. package/src/core/net/tailscale.js +168 -0
  163. package/src/core/profiles/bundled/secretary/PROFILE.md +32 -42
  164. package/src/core/profiles/bundled/secretary/config.schema.es.json +68 -0
  165. package/src/core/profiles/bundled/secretary/config.schema.json +30 -2
  166. package/src/core/profiles/bundled/secretary/profile.json +3 -1
  167. package/src/core/profiles/bundled/secretary/routines/a2a-sweep.json +20 -0
  168. package/src/core/profiles/bundled/secretary/routines/day-close.json +4 -1
  169. package/src/core/profiles/bundled/secretary/routines/day-open.json +7 -1
  170. package/src/core/profiles/bundled/secretary/routines/watch.json +13 -2
  171. package/src/core/profiles/lifecycle.js +243 -19
  172. package/src/core/profiles/paths.js +12 -0
  173. package/src/core/profiles/store.js +47 -0
  174. package/src/core/routines/active-runs.js +213 -0
  175. package/src/core/routines/delivery.js +612 -0
  176. package/src/core/routines/header.js +88 -0
  177. package/src/core/routines/index.js +26 -0
  178. package/src/core/routines/run-log.js +78 -0
  179. package/src/core/routines/runner.js +629 -66
  180. package/src/core/routines/signals.js +75 -0
  181. package/src/core/runtime-skills/apc-context/SKILL.md +14 -7
  182. package/src/core/runtime-skills/apx/SKILL.md +93 -1
  183. package/src/core/runtime-skills/apx-agency-agents/SKILL.md +2 -2
  184. package/src/core/runtime-skills/apx-agent/SKILL.md +134 -19
  185. package/src/core/runtime-skills/apx-commitment/SKILL.md +21 -11
  186. package/src/core/runtime-skills/apx-image/SKILL.md +60 -0
  187. package/src/core/runtime-skills/apx-integrations/SKILL.md +82 -0
  188. package/src/core/runtime-skills/apx-mcp/SKILL.md +45 -14
  189. package/src/core/runtime-skills/apx-mcp-builder/SKILL.md +4 -4
  190. package/src/core/runtime-skills/apx-profile/SKILL.md +27 -2
  191. package/src/core/runtime-skills/apx-project/SKILL.md +23 -2
  192. package/src/core/runtime-skills/apx-routine/SKILL.md +40 -17
  193. package/src/core/runtime-skills/apx-runtime/SKILL.md +124 -14
  194. package/src/core/runtime-skills/apx-sessions/SKILL.md +7 -6
  195. package/src/core/runtime-skills/apx-skill-builder/SKILL.md +15 -13
  196. package/src/core/runtime-skills/apx-task/SKILL.md +79 -26
  197. package/src/core/runtime-skills/apx-telegram/SKILL.md +12 -12
  198. package/src/core/runtime-skills/apx-transcribe/SKILL.md +56 -0
  199. package/src/core/runtime-skills/apx-voice/SKILL.md +27 -8
  200. package/src/core/runtime-skills/claude-code/SKILL.md +8 -0
  201. package/src/core/runtime-skills/openrouter/SKILL.md +8 -2
  202. package/src/core/runtimes/_spawn.js +9 -1
  203. package/src/core/runtimes/claude-code.js +11 -2
  204. package/src/core/runtimes/codex.js +44 -10
  205. package/src/core/runtimes/index.js +17 -2
  206. package/src/core/runtimes/opencode.js +88 -9
  207. package/src/core/runtimes/outcome.js +119 -0
  208. package/src/core/sessions/index.js +193 -1
  209. package/src/core/stores/agent-inbox.js +109 -23
  210. package/src/core/stores/code-sessions.js +21 -0
  211. package/src/core/stores/commitments.js +27 -3
  212. package/src/core/stores/conversations.js +220 -20
  213. package/src/core/stores/deliveries.js +177 -0
  214. package/src/core/stores/media-archive.js +228 -0
  215. package/src/core/stores/messages.js +1096 -112
  216. package/src/core/stores/organization.js +34 -0
  217. package/src/core/stores/project-memory.js +71 -0
  218. package/src/core/stores/routine-memory.js +16 -8
  219. package/src/core/stores/routines.js +27 -49
  220. package/src/core/stores/sessions.js +4 -8
  221. package/src/core/stores/tasks.js +212 -18
  222. package/src/core/stores/turn-record.js +209 -0
  223. package/src/core/tasks/columns.js +136 -0
  224. package/src/core/tasks/comment-turn.js +258 -0
  225. package/src/core/util/time.js +13 -0
  226. package/src/core/voice/engines/index.js +54 -1
  227. package/src/core/voice/engines/openai.js +50 -4
  228. package/src/core/voice/opus.js +67 -0
  229. package/src/core/voice/pronounceable.js +43 -0
  230. package/src/core/voice/transcription.js +4 -0
  231. package/src/core/voice/tts.js +114 -24
  232. package/src/host/daemon/active-turns.js +188 -0
  233. package/src/host/daemon/api/admin-config.js +9 -0
  234. package/src/host/daemon/api/agents.js +99 -90
  235. package/src/host/daemon/api/artifact-preview.js +7 -6
  236. package/src/host/daemon/api/artifacts.js +3 -2
  237. package/src/host/daemon/api/code.js +55 -9
  238. package/src/host/daemon/api/commitments.js +11 -0
  239. package/src/host/daemon/api/confirm.js +3 -2
  240. package/src/host/daemon/api/conversations.js +543 -35
  241. package/src/host/daemon/api/deck.js +9 -8
  242. package/src/host/daemon/api/deliveries.js +33 -0
  243. package/src/host/daemon/api/desktop.js +5 -4
  244. package/src/host/daemon/api/embeddings.js +15 -6
  245. package/src/host/daemon/api/engines.js +59 -8
  246. package/src/host/daemon/api/exec.js +437 -121
  247. package/src/host/daemon/api/groups.js +215 -0
  248. package/src/host/daemon/api/images.js +107 -0
  249. package/src/host/daemon/api/inbox.js +123 -2
  250. package/src/host/daemon/api/integrations.js +64 -2
  251. package/src/host/daemon/api/mcps.js +7 -6
  252. package/src/host/daemon/api/media.js +283 -0
  253. package/src/host/daemon/api/mobility.js +177 -0
  254. package/src/host/daemon/api/net.js +182 -0
  255. package/src/host/daemon/api/pairing.js +38 -5
  256. package/src/host/daemon/api/profiles.js +30 -2
  257. package/src/host/daemon/api/routines.js +36 -4
  258. package/src/host/daemon/api/runtimes.js +74 -39
  259. package/src/host/daemon/api/sessions-search.js +7 -2
  260. package/src/host/daemon/api/sessions.js +44 -2
  261. package/src/host/daemon/api/shared.js +127 -20
  262. package/src/host/daemon/api/skills.js +11 -4
  263. package/src/host/daemon/api/super-agent.js +384 -53
  264. package/src/host/daemon/api/tasks.js +180 -10
  265. package/src/host/daemon/api/telegram.js +11 -10
  266. package/src/host/daemon/api/thread-faces.js +159 -0
  267. package/src/host/daemon/api/top-level.js +3 -3
  268. package/src/host/daemon/api/transcribe.js +11 -10
  269. package/src/host/daemon/api/tts.js +97 -4
  270. package/src/host/daemon/api/turn-abort.js +23 -0
  271. package/src/host/daemon/api/turns.js +49 -0
  272. package/src/host/daemon/api/voice.js +5 -4
  273. package/src/host/daemon/api/web.js +98 -0
  274. package/src/host/daemon/api.js +39 -0
  275. package/src/host/daemon/delivery-sweep.js +58 -0
  276. package/src/host/daemon/desktop-ws.js +5 -23
  277. package/src/host/daemon/events-ws.js +273 -0
  278. package/src/host/daemon/index.js +59 -15
  279. package/src/host/daemon/plugins/desktop/index.js +17 -4
  280. package/src/host/daemon/plugins/telegram/index.js +78 -40
  281. package/src/host/daemon/pty-bridge.py +99 -0
  282. package/src/host/daemon/routines-scheduler.js +1 -0
  283. package/src/host/daemon/smoke.js +1 -2
  284. package/src/host/daemon/terminal-ws.js +132 -0
  285. package/src/host/daemon/tts-keepwarm.js +87 -0
  286. package/src/host/daemon/wakeup.js +11 -6
  287. package/src/host/daemon/whisper-server.js +44 -0
  288. package/src/host/daemon/whisper-server.py +70 -13
  289. package/src/host/daemon/ws-auth.js +28 -0
  290. package/src/interfaces/android/app/build.gradle +42 -0
  291. package/src/interfaces/android/app/proguard-rules.pro +4 -0
  292. package/src/interfaces/android/app/src/main/AndroidManifest.xml +139 -0
  293. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/AlertScreen.java +139 -0
  294. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/AndroidAutoDetector.java +106 -0
  295. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ApxCarAppService.java +57 -0
  296. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ApxPreferences.java +165 -0
  297. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarAlertStore.java +84 -0
  298. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarMessageActionReceiver.java +47 -0
  299. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarMessageNotification.java +152 -0
  300. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DaemonAddress.java +35 -0
  301. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DaemonClient.java +339 -0
  302. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DeviceLocation.java +38 -0
  303. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ErrandScreen.java +127 -0
  304. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MainActivity.java +872 -0
  305. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsNavigationDetector.java +63 -0
  306. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsNavigationListenerService.java +453 -0
  307. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsShareIntentParser.java +93 -0
  308. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotBlobCatalog.java +66 -0
  309. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotOverlayService.java +448 -0
  310. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotView.java +249 -0
  311. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MessageFrameParser.java +240 -0
  312. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/NotifyChannels.java +69 -0
  313. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ProximityActionReceiver.java +78 -0
  314. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ProximityNotification.java +161 -0
  315. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/StartupReceiver.java +57 -0
  316. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TravelEventGate.java +62 -0
  317. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TravelStatusBanner.java +116 -0
  318. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripLocationService.java +272 -0
  319. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripPlacesSheet.java +203 -0
  320. package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripScreen.java +182 -0
  321. package/src/interfaces/android/app/src/main/res/drawable/app_background.xml +12 -0
  322. package/src/interfaces/android/app/src/main/res/drawable/ic_apx_app.xml +10 -0
  323. package/src/interfaces/android/app/src/main/res/drawable/ic_apx_launcher_foreground.xml +12 -0
  324. package/src/interfaces/android/app/src/main/res/drawable/ic_apx_notification.xml +22 -0
  325. package/src/interfaces/android/app/src/main/res/drawable/ic_trip_car.xml +37 -0
  326. package/src/interfaces/android/app/src/main/res/drawable-nodpi/apx_logo.png +0 -0
  327. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_amatista.png +0 -0
  328. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_aqua.png +0 -0
  329. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_brasa.png +0 -0
  330. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_campana.png +0 -0
  331. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_caracol.png +0 -0
  332. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_carbon.png +0 -0
  333. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cobalto.png +0 -0
  334. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cometa.png +0 -0
  335. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_coral.png +0 -0
  336. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cubi.png +0 -0
  337. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_eclipse.png +0 -0
  338. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_faro.png +0 -0
  339. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_gajo.png +0 -0
  340. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_iris.png +0 -0
  341. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_kiwi.png +0 -0
  342. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_laguna.png +0 -0
  343. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_lila.png +0 -0
  344. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_menta.png +0 -0
  345. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_nimbo.png +0 -0
  346. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_noche.png +0 -0
  347. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_onyx.png +0 -0
  348. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_orbita.png +0 -0
  349. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_ovni.png +0 -0
  350. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_papa.png +0 -0
  351. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_parche.png +0 -0
  352. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_peon.png +0 -0
  353. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_perla.png +0 -0
  354. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_pino.png +0 -0
  355. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_quad.png +0 -0
  356. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_rubi.png +0 -0
  357. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_saturno.png +0 -0
  358. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_trebol.png +0 -0
  359. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_trino.png +0 -0
  360. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_volcan.png +0 -0
  361. package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_zafiro.png +0 -0
  362. package/src/interfaces/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
  363. package/src/interfaces/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
  364. package/src/interfaces/android/app/src/main/res/raw/apx_notification.mp3 +0 -0
  365. package/src/interfaces/android/app/src/main/res/values/colors.xml +4 -0
  366. package/src/interfaces/android/app/src/main/res/values/strings.xml +25 -0
  367. package/src/interfaces/android/app/src/main/res/values/styles.xml +10 -0
  368. package/src/interfaces/android/app/src/main/res/values-v31/styles.xml +14 -0
  369. package/src/interfaces/android/app/src/main/res/xml/automotive_app_desc.xml +9 -0
  370. package/src/interfaces/android/app/src/main/res/xml/network_security_config.xml +10 -0
  371. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/AndroidAutoDetectorTest.java +85 -0
  372. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/CarAlertStoreTest.java +104 -0
  373. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/DaemonAddressTest.java +23 -0
  374. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MapsNavigationDetectorTest.java +69 -0
  375. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MapsShareIntentParserTest.java +31 -0
  376. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MessageFrameParserTest.java +180 -0
  377. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/TravelEventGateTest.java +64 -0
  378. package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/TripPlacesSheetTest.java +66 -0
  379. package/src/interfaces/android/build.gradle +3 -0
  380. package/src/interfaces/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  381. package/src/interfaces/android/gradle/wrapper/gradle-wrapper.properties +9 -0
  382. package/src/interfaces/android/gradle.properties +3 -0
  383. package/src/interfaces/android/gradlew +248 -0
  384. package/src/interfaces/android/gradlew.bat +82 -0
  385. package/src/interfaces/android/settings.gradle +18 -0
  386. package/src/interfaces/cli/commands/a2a.js +145 -4
  387. package/src/interfaces/cli/commands/agent.js +247 -22
  388. package/src/interfaces/cli/commands/code.js +1 -1
  389. package/src/interfaces/cli/commands/commitment.js +5 -0
  390. package/src/interfaces/cli/commands/config.js +85 -6
  391. package/src/interfaces/cli/commands/exec.js +90 -1
  392. package/src/interfaces/cli/commands/image.js +314 -0
  393. package/src/interfaces/cli/commands/mcp.js +87 -23
  394. package/src/interfaces/cli/commands/memory.js +35 -22
  395. package/src/interfaces/cli/commands/panel.js +94 -0
  396. package/src/interfaces/cli/commands/profile.js +14 -0
  397. package/src/interfaces/cli/commands/project.js +29 -0
  398. package/src/interfaces/cli/commands/routine.js +45 -10
  399. package/src/interfaces/cli/commands/runtime.js +30 -7
  400. package/src/interfaces/cli/commands/session.js +90 -38
  401. package/src/interfaces/cli/commands/sessions.js +35 -2
  402. package/src/interfaces/cli/commands/skills.js +15 -9
  403. package/src/interfaces/cli/commands/status.js +2 -3
  404. package/src/interfaces/cli/commands/task.js +54 -5
  405. package/src/interfaces/cli/commands/telegram.js +12 -4
  406. package/src/interfaces/cli/commands/transcribe.js +177 -0
  407. package/src/interfaces/cli/help/index.js +311 -72
  408. package/src/interfaces/cli/http.js +61 -13
  409. package/src/interfaces/cli/index.js +1 -1
  410. package/src/interfaces/cli/routes/agent.js +5 -4
  411. package/src/interfaces/cli/routes/commitment.js +3 -2
  412. package/src/interfaces/cli/routes/config.js +7 -2
  413. package/src/interfaces/cli/routes/image.js +11 -0
  414. package/src/interfaces/cli/routes/index.js +2 -0
  415. package/src/interfaces/cli/routes/log.js +1 -1
  416. package/src/interfaces/cli/routes/memory.js +3 -2
  417. package/src/interfaces/cli/routes/panel.js +15 -2
  418. package/src/interfaces/cli/routes/profile.js +3 -2
  419. package/src/interfaces/cli/routes/transcribe.js +10 -0
  420. package/src/interfaces/cli/stdin.js +29 -0
  421. package/src/interfaces/desktop/assets/blobs/amatista.png +0 -0
  422. package/src/interfaces/desktop/assets/blobs/aqua.png +0 -0
  423. package/src/interfaces/desktop/assets/blobs/brasa.png +0 -0
  424. package/src/interfaces/desktop/assets/blobs/campana.png +0 -0
  425. package/src/interfaces/desktop/assets/blobs/caracol.png +0 -0
  426. package/src/interfaces/desktop/assets/blobs/carbon.png +0 -0
  427. package/src/interfaces/desktop/assets/blobs/cobalto.png +0 -0
  428. package/src/interfaces/desktop/assets/blobs/cometa.png +0 -0
  429. package/src/interfaces/desktop/assets/blobs/coral.png +0 -0
  430. package/src/interfaces/desktop/assets/blobs/cubi.png +0 -0
  431. package/src/interfaces/desktop/assets/blobs/eclipse.png +0 -0
  432. package/src/interfaces/desktop/assets/blobs/faro.png +0 -0
  433. package/src/interfaces/desktop/assets/blobs/gajo.png +0 -0
  434. package/src/interfaces/desktop/assets/blobs/iris.png +0 -0
  435. package/src/interfaces/desktop/assets/blobs/kiwi.png +0 -0
  436. package/src/interfaces/desktop/assets/blobs/laguna.png +0 -0
  437. package/src/interfaces/desktop/assets/blobs/lila.png +0 -0
  438. package/src/interfaces/desktop/assets/blobs/menta.png +0 -0
  439. package/src/interfaces/desktop/assets/blobs/nimbo.png +0 -0
  440. package/src/interfaces/desktop/assets/blobs/noche.png +0 -0
  441. package/src/interfaces/desktop/assets/blobs/onyx.png +0 -0
  442. package/src/interfaces/desktop/assets/blobs/orbita.png +0 -0
  443. package/src/interfaces/desktop/assets/blobs/ovni.png +0 -0
  444. package/src/interfaces/desktop/assets/blobs/papa.png +0 -0
  445. package/src/interfaces/desktop/assets/blobs/parche.png +0 -0
  446. package/src/interfaces/desktop/assets/blobs/peon.png +0 -0
  447. package/src/interfaces/desktop/assets/blobs/perla.png +0 -0
  448. package/src/interfaces/desktop/assets/blobs/pino.png +0 -0
  449. package/src/interfaces/desktop/assets/blobs/quad.png +0 -0
  450. package/src/interfaces/desktop/assets/blobs/rubi.png +0 -0
  451. package/src/interfaces/desktop/assets/blobs/saturno.png +0 -0
  452. package/src/interfaces/desktop/assets/blobs/trebol.png +0 -0
  453. package/src/interfaces/desktop/assets/blobs/trino.png +0 -0
  454. package/src/interfaces/desktop/assets/blobs/volcan.png +0 -0
  455. package/src/interfaces/desktop/assets/blobs/zafiro.png +0 -0
  456. package/src/interfaces/desktop/assets/notification.mp3 +0 -0
  457. package/src/interfaces/desktop/main.js +473 -29
  458. package/src/interfaces/desktop/mascot-blobs.js +41 -0
  459. package/src/interfaces/desktop/mascot-preload.js +32 -0
  460. package/src/interfaces/desktop/mascot.css +186 -0
  461. package/src/interfaces/desktop/mascot.html +40 -0
  462. package/src/interfaces/desktop/mascot.js +163 -0
  463. package/src/interfaces/desktop/preload.js +10 -0
  464. package/src/interfaces/desktop/renderer.js +308 -48
  465. package/src/interfaces/desktop/style.css +34 -0
  466. package/src/interfaces/mcp-server/index.js +87 -0
  467. package/src/interfaces/tui/_shims/util-locale.ts +0 -2
  468. package/src/interfaces/tui/app.tsx +0 -6
  469. package/src/interfaces/tui/attach.ts +0 -1
  470. package/src/interfaces/tui/context/sdk-apx.tsx +0 -4
  471. package/src/interfaces/tui/plugin/api.tsx +0 -3
  472. package/src/interfaces/tui/plugin/runtime.ts +0 -3
  473. package/src/interfaces/tui/thread.ts +0 -16
  474. package/src/interfaces/web/README.md +22 -14
  475. package/src/interfaces/web/dist/assets/claude-XtpLmGtF.webp +0 -0
  476. package/src/interfaces/web/dist/assets/codex-DExPUgvh.webp +0 -0
  477. package/src/interfaces/web/dist/assets/index-BEoRgIqd.css +32 -0
  478. package/src/interfaces/web/dist/assets/index-BEoRgIqd.css.br +0 -0
  479. package/src/interfaces/web/dist/assets/index-BEoRgIqd.css.gz +0 -0
  480. package/src/interfaces/web/dist/assets/index-C6fXHc1p.js +1074 -0
  481. package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.br +0 -0
  482. package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.gz +0 -0
  483. package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map +1 -0
  484. package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map.br +0 -0
  485. package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map.gz +0 -0
  486. package/src/interfaces/web/dist/favicon/dark/site.webmanifest +12 -6
  487. package/src/interfaces/web/dist/favicon/white/site.webmanifest +12 -6
  488. package/src/interfaces/web/dist/index.html +22 -6
  489. package/src/interfaces/web/dist/index.html.br +0 -0
  490. package/src/interfaces/web/dist/index.html.gz +0 -0
  491. package/src/interfaces/web/dist/manifest.webmanifest +25 -0
  492. package/src/interfaces/web/dist/modules/blobs/amatista.png +0 -0
  493. package/src/interfaces/web/dist/modules/blobs/aqua.png +0 -0
  494. package/src/interfaces/web/dist/modules/blobs/brasa.png +0 -0
  495. package/src/interfaces/web/dist/modules/blobs/campana.png +0 -0
  496. package/src/interfaces/web/dist/modules/blobs/caracol.png +0 -0
  497. package/src/interfaces/web/dist/modules/blobs/carbon.png +0 -0
  498. package/src/interfaces/web/dist/modules/blobs/cobalto.png +0 -0
  499. package/src/interfaces/web/dist/modules/blobs/cometa.png +0 -0
  500. package/src/interfaces/web/dist/modules/blobs/coral.png +0 -0
  501. package/src/interfaces/web/dist/modules/blobs/cubi.png +0 -0
  502. package/src/interfaces/web/dist/modules/blobs/eclipse.png +0 -0
  503. package/src/interfaces/web/dist/modules/blobs/faro.png +0 -0
  504. package/src/interfaces/web/dist/modules/blobs/gajo.png +0 -0
  505. package/src/interfaces/web/dist/modules/blobs/iris.png +0 -0
  506. package/src/interfaces/web/dist/modules/blobs/kiwi.png +0 -0
  507. package/src/interfaces/web/dist/modules/blobs/laguna.png +0 -0
  508. package/src/interfaces/web/dist/modules/blobs/lila.png +0 -0
  509. package/src/interfaces/web/dist/modules/blobs/menta.png +0 -0
  510. package/src/interfaces/web/dist/modules/blobs/nimbo.png +0 -0
  511. package/src/interfaces/web/dist/modules/blobs/noche.png +0 -0
  512. package/src/interfaces/web/dist/modules/blobs/onyx.png +0 -0
  513. package/src/interfaces/web/dist/modules/blobs/orbita.png +0 -0
  514. package/src/interfaces/web/dist/modules/blobs/ovni.png +0 -0
  515. package/src/interfaces/web/dist/modules/blobs/papa.png +0 -0
  516. package/src/interfaces/web/dist/modules/blobs/parche.png +0 -0
  517. package/src/interfaces/web/dist/modules/blobs/peon.png +0 -0
  518. package/src/interfaces/web/dist/modules/blobs/perla.png +0 -0
  519. package/src/interfaces/web/dist/modules/blobs/pino.png +0 -0
  520. package/src/interfaces/web/dist/modules/blobs/quad.png +0 -0
  521. package/src/interfaces/web/dist/modules/blobs/rubi.png +0 -0
  522. package/src/interfaces/web/dist/modules/blobs/saturno.png +0 -0
  523. package/src/interfaces/web/dist/modules/blobs/trebol.png +0 -0
  524. package/src/interfaces/web/dist/modules/blobs/trino.png +0 -0
  525. package/src/interfaces/web/dist/modules/blobs/volcan.png +0 -0
  526. package/src/interfaces/web/dist/modules/blobs/zafiro.png +0 -0
  527. package/src/interfaces/web/dist/sw.js +106 -0
  528. package/src/interfaces/web/dist/sw.js.br +0 -0
  529. package/src/interfaces/web/dist/sw.js.gz +0 -0
  530. package/src/interfaces/web/eslint.config.js +83 -0
  531. package/src/interfaces/web/index.html +20 -4
  532. package/src/interfaces/web/package-lock.json +1651 -1280
  533. package/src/interfaces/web/package.json +9 -10
  534. package/src/interfaces/web/pnpm-lock.yaml +867 -869
  535. package/src/interfaces/web/public/favicon/dark/site.webmanifest +12 -6
  536. package/src/interfaces/web/public/favicon/white/site.webmanifest +12 -6
  537. package/src/interfaces/web/public/manifest.webmanifest +25 -0
  538. package/src/interfaces/web/public/modules/blobs/amatista.png +0 -0
  539. package/src/interfaces/web/public/modules/blobs/aqua.png +0 -0
  540. package/src/interfaces/web/public/modules/blobs/brasa.png +0 -0
  541. package/src/interfaces/web/public/modules/blobs/campana.png +0 -0
  542. package/src/interfaces/web/public/modules/blobs/caracol.png +0 -0
  543. package/src/interfaces/web/public/modules/blobs/carbon.png +0 -0
  544. package/src/interfaces/web/public/modules/blobs/cobalto.png +0 -0
  545. package/src/interfaces/web/public/modules/blobs/cometa.png +0 -0
  546. package/src/interfaces/web/public/modules/blobs/coral.png +0 -0
  547. package/src/interfaces/web/public/modules/blobs/cubi.png +0 -0
  548. package/src/interfaces/web/public/modules/blobs/eclipse.png +0 -0
  549. package/src/interfaces/web/public/modules/blobs/faro.png +0 -0
  550. package/src/interfaces/web/public/modules/blobs/gajo.png +0 -0
  551. package/src/interfaces/web/public/modules/blobs/iris.png +0 -0
  552. package/src/interfaces/web/public/modules/blobs/kiwi.png +0 -0
  553. package/src/interfaces/web/public/modules/blobs/laguna.png +0 -0
  554. package/src/interfaces/web/public/modules/blobs/lila.png +0 -0
  555. package/src/interfaces/web/public/modules/blobs/menta.png +0 -0
  556. package/src/interfaces/web/public/modules/blobs/nimbo.png +0 -0
  557. package/src/interfaces/web/public/modules/blobs/noche.png +0 -0
  558. package/src/interfaces/web/public/modules/blobs/onyx.png +0 -0
  559. package/src/interfaces/web/public/modules/blobs/orbita.png +0 -0
  560. package/src/interfaces/web/public/modules/blobs/ovni.png +0 -0
  561. package/src/interfaces/web/public/modules/blobs/papa.png +0 -0
  562. package/src/interfaces/web/public/modules/blobs/parche.png +0 -0
  563. package/src/interfaces/web/public/modules/blobs/peon.png +0 -0
  564. package/src/interfaces/web/public/modules/blobs/perla.png +0 -0
  565. package/src/interfaces/web/public/modules/blobs/pino.png +0 -0
  566. package/src/interfaces/web/public/modules/blobs/quad.png +0 -0
  567. package/src/interfaces/web/public/modules/blobs/rubi.png +0 -0
  568. package/src/interfaces/web/public/modules/blobs/saturno.png +0 -0
  569. package/src/interfaces/web/public/modules/blobs/trebol.png +0 -0
  570. package/src/interfaces/web/public/modules/blobs/trino.png +0 -0
  571. package/src/interfaces/web/public/modules/blobs/volcan.png +0 -0
  572. package/src/interfaces/web/public/modules/blobs/zafiro.png +0 -0
  573. package/src/interfaces/web/public/sw.js +106 -0
  574. package/src/interfaces/web/src/App.tsx +106 -10
  575. package/src/interfaces/web/src/assets/cli/claude.webp +0 -0
  576. package/src/interfaces/web/src/assets/cli/codex.webp +0 -0
  577. package/src/interfaces/web/src/assets/cli/cursor.svg +1 -0
  578. package/src/interfaces/web/src/assets/cli/opencode.png +0 -0
  579. package/src/interfaces/web/src/components/Combobox.tsx +201 -0
  580. package/src/interfaces/web/src/components/MobileHint.tsx +95 -0
  581. package/src/interfaces/web/src/components/MobileLinkDialog.tsx +156 -0
  582. package/src/interfaces/web/src/components/ModelCombobox.tsx +21 -113
  583. package/src/interfaces/web/src/components/{routines/ReadOnlyBlock.tsx → ReadOnlyBlock.tsx} +13 -4
  584. package/src/interfaces/web/src/components/Roby.tsx +5 -3
  585. package/src/interfaces/web/src/components/RobyBubble.tsx +23 -5
  586. package/src/interfaces/web/src/components/RowMenu.tsx +46 -0
  587. package/src/interfaces/web/src/components/TimezoneSelect.tsx +4 -1
  588. package/src/interfaces/web/src/components/Toast.tsx +50 -14
  589. package/src/interfaces/web/src/components/UiSelect.tsx +12 -5
  590. package/src/interfaces/web/src/components/agents/AgentAvatar.tsx +171 -0
  591. package/src/interfaces/web/src/components/agents/AgentFormFields.tsx +42 -11
  592. package/src/interfaces/web/src/components/agents/AgentModelBadge.tsx +157 -0
  593. package/src/interfaces/web/src/components/agents/AgentModelSelect.tsx +57 -0
  594. package/src/interfaces/web/src/components/agents/AgentSkillsPicker.tsx +115 -0
  595. package/src/interfaces/web/src/components/agents/BlobAvatar.tsx +50 -0
  596. package/src/interfaces/web/src/components/agents/blobPresets.ts +50 -0
  597. package/src/interfaces/web/src/components/agents/modelCatalog.ts +66 -0
  598. package/src/interfaces/web/src/components/chat/ActionGroup.tsx +162 -0
  599. package/src/interfaces/web/src/components/chat/AskAnswersCard.tsx +4 -3
  600. package/src/interfaces/web/src/components/chat/AskQuestionsCard.tsx +1 -1
  601. package/src/interfaces/web/src/components/chat/Attachment.tsx +220 -0
  602. package/src/interfaces/web/src/components/chat/ChatList.tsx +226 -51
  603. package/src/interfaces/web/src/components/chat/ChatRowActivity.tsx +45 -0
  604. package/src/interfaces/web/src/components/chat/Composer.tsx +672 -23
  605. package/src/interfaces/web/src/components/chat/ComposerCommands.tsx +175 -0
  606. package/src/interfaces/web/src/components/chat/ComposerSuggest.tsx +215 -0
  607. package/src/interfaces/web/src/components/chat/ContextBar.tsx +133 -65
  608. package/src/interfaces/web/src/components/chat/InlineAskPanel.tsx +107 -47
  609. package/src/interfaces/web/src/components/chat/MessageBubble.tsx +460 -119
  610. package/src/interfaces/web/src/components/chat/MessageList.tsx +165 -18
  611. package/src/interfaces/web/src/components/chat/ReasoningBlock.tsx +58 -0
  612. package/src/interfaces/web/src/components/chat/SessionPicker.tsx +182 -0
  613. package/src/interfaces/web/src/components/chat/SkillTrace.tsx +183 -0
  614. package/src/interfaces/web/src/components/chat/ToolCall.tsx +11 -11
  615. package/src/interfaces/web/src/components/code/CodeContextTab.tsx +87 -53
  616. package/src/interfaces/web/src/components/code/CodeFileTree.tsx +11 -52
  617. package/src/interfaces/web/src/components/code/CodeFileViewer.tsx +5 -4
  618. package/src/interfaces/web/src/components/code/CodeProjectPicker.tsx +31 -7
  619. package/src/interfaces/web/src/components/code/CodeSessionList.tsx +32 -11
  620. package/src/interfaces/web/src/components/code/CodeSidePanel.tsx +33 -3
  621. package/src/interfaces/web/src/components/code/CodeTerminal.tsx +5 -4
  622. package/src/interfaces/web/src/components/code/NewCodeSessionDialog.tsx +164 -0
  623. package/src/interfaces/web/src/components/commitments/CommitmentDetail.tsx +162 -0
  624. package/src/interfaces/web/src/components/commitments/CommitmentFormDialog.tsx +158 -0
  625. package/src/interfaces/web/src/components/commitments/CommitmentList.tsx +194 -0
  626. package/src/interfaces/web/src/components/commitments/commitmentState.tsx +46 -0
  627. package/src/interfaces/web/src/components/common/BulkActionBar.tsx +60 -0
  628. package/src/interfaces/web/src/components/common/ConfirmDialog.tsx +4 -1
  629. package/src/interfaces/web/src/components/common/SelectCheckbox.tsx +40 -0
  630. package/src/interfaces/web/src/components/common/TabNav.tsx +1 -1
  631. package/src/interfaces/web/src/components/cron/CronPicker.tsx +1 -1
  632. package/src/interfaces/web/src/components/files/FileBrowser.tsx +1 -1
  633. package/src/interfaces/web/src/components/files/FileTree.tsx +6 -4
  634. package/src/interfaces/web/src/components/files/FileViewer.tsx +9 -5
  635. package/src/interfaces/web/src/components/files/MarkdownPreview.tsx +45 -9
  636. package/src/interfaces/web/src/components/images/ImageDefaultsCard.tsx +93 -0
  637. package/src/interfaces/web/src/components/images/ImageProviderList.tsx +142 -0
  638. package/src/interfaces/web/src/components/images/ImageProviderModal.tsx +263 -0
  639. package/src/interfaces/web/src/components/images/ImageTestCard.tsx +142 -0
  640. package/src/interfaces/web/src/components/inbox/ChannelFilter.tsx +178 -0
  641. package/src/interfaces/web/src/components/inbox/InboxList.tsx +77 -81
  642. package/src/interfaces/web/src/components/inbox/InboxRowItem.tsx +140 -0
  643. package/src/interfaces/web/src/components/integrations/ComingSoonPlugin.tsx +2 -2
  644. package/src/interfaces/web/src/components/integrations/PluginConnect.tsx +208 -30
  645. package/src/interfaces/web/src/components/integrations/PluginToolsSection.tsx +1 -1
  646. package/src/interfaces/web/src/components/layout/ProjectAvatar.tsx +39 -24
  647. package/src/interfaces/web/src/components/layout/ProjectSidebar.tsx +253 -58
  648. package/src/interfaces/web/src/components/memory/MemoryBrowser.tsx +94 -47
  649. package/src/interfaces/web/src/components/routines/ExecutionsList.tsx +202 -90
  650. package/src/interfaces/web/src/components/routines/RoutineDetail.tsx +28 -6
  651. package/src/interfaces/web/src/components/routines/RoutineEditor.tsx +16 -5
  652. package/src/interfaces/web/src/components/routines/RoutineList.tsx +49 -9
  653. package/src/interfaces/web/src/components/routines/VarTextarea.tsx +1 -1
  654. package/src/interfaces/web/src/components/routines/runChat.ts +121 -0
  655. package/src/interfaces/web/src/components/sessions/SessionDetail.tsx +148 -0
  656. package/src/interfaces/web/src/components/sessions/SessionTerminal.tsx +98 -0
  657. package/src/interfaces/web/src/components/settings/AccessPanel.tsx +205 -0
  658. package/src/interfaces/web/src/components/settings/DefaultRouterCard.tsx +246 -101
  659. package/src/interfaces/web/src/components/settings/DesktopSettingsPanel.tsx +36 -2
  660. package/src/interfaces/web/src/components/settings/DevicesPanel.tsx +19 -6
  661. package/src/interfaces/web/src/components/settings/EmbedProviderList.tsx +274 -0
  662. package/src/interfaces/web/src/components/settings/EnginesPanel.tsx +26 -6
  663. package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +118 -119
  664. package/src/interfaces/web/src/components/settings/NudgePanel.tsx +4 -3
  665. package/src/interfaces/web/src/components/settings/PairDeviceDialog.tsx +15 -4
  666. package/src/interfaces/web/src/components/settings/PanelPrefs.tsx +374 -0
  667. package/src/interfaces/web/src/components/settings/ProfilePanel.tsx +70 -2
  668. package/src/interfaces/web/src/components/settings/RoutingPanel.tsx +2 -1
  669. package/src/interfaces/web/src/components/settings/SkillsInspectorPanel.tsx +102 -43
  670. package/src/interfaces/web/src/components/settings/SkillsManager.tsx +76 -21
  671. package/src/interfaces/web/src/components/settings/SkillsSettings.tsx +10 -3
  672. package/src/interfaces/web/src/components/settings/SuperAgentPanel.tsx +8 -0
  673. package/src/interfaces/web/src/components/settings/TelegramChannelsPanel.tsx +11 -2
  674. package/src/interfaces/web/src/components/settings/TelegramContactsPanel.tsx +19 -8
  675. package/src/interfaces/web/src/components/settings/TelegramRolesPanel.tsx +12 -2
  676. package/src/interfaces/web/src/components/settings/WebPanel.tsx +22 -31
  677. package/src/interfaces/web/src/components/settings/providers/ProviderCard.tsx +15 -3
  678. package/src/interfaces/web/src/components/settings/providers/ProviderModal.tsx +97 -66
  679. package/src/interfaces/web/src/components/settings/providers/ProviderTestDialog.tsx +150 -0
  680. package/src/interfaces/web/src/components/settings/providers/typeStyles.ts +67 -25
  681. package/src/interfaces/web/src/components/settings/providers/types.ts +3 -0
  682. package/src/interfaces/web/src/components/tasks/TaskBoard.tsx +201 -0
  683. package/src/interfaces/web/src/components/tasks/TaskColumnsDialog.tsx +243 -0
  684. package/src/interfaces/web/src/components/tasks/TaskComments.tsx +167 -0
  685. package/src/interfaces/web/src/components/tasks/TaskDetail.tsx +335 -0
  686. package/src/interfaces/web/src/components/tasks/TaskFormDialog.tsx +406 -0
  687. package/src/interfaces/web/src/components/tasks/TaskList.tsx +258 -0
  688. package/src/interfaces/web/src/components/tasks/TaskSubtasks.tsx +126 -0
  689. package/src/interfaces/web/src/components/tasks/columns.ts +51 -0
  690. package/src/interfaces/web/src/components/tasks/taskStatus.tsx +159 -34
  691. package/src/interfaces/web/src/components/tasks/taskViewPrefs.ts +73 -0
  692. package/src/interfaces/web/src/components/tasks/useTaskColumns.ts +31 -0
  693. package/src/interfaces/web/src/components/ui/chat-input.tsx +136 -12
  694. package/src/interfaces/web/src/components/ui/context-menu.tsx +15 -198
  695. package/src/interfaces/web/src/components/ui/dialog.tsx +3 -2
  696. package/src/interfaces/web/src/components/ui/filter-chips.tsx +4 -0
  697. package/src/interfaces/web/src/components/ui/popover.tsx +14 -49
  698. package/src/interfaces/web/src/components/ui/sheet.tsx +2 -1
  699. package/src/interfaces/web/src/components/ui/spinner.tsx +2 -1
  700. package/src/interfaces/web/src/components/ui.tsx +62 -23
  701. package/src/interfaces/web/src/components/voice/VoiceProviderList.tsx +2 -1
  702. package/src/interfaces/web/src/components/voice/VoiceProviderModal.tsx +66 -8
  703. package/src/interfaces/web/src/components/voice/VoiceQvoxInstallCard.tsx +63 -0
  704. package/src/interfaces/web/src/components/voice/VoiceQvoxStatusCard.tsx +51 -0
  705. package/src/interfaces/web/src/components/voice/VoiceSttCard.tsx +4 -3
  706. package/src/interfaces/web/src/components/voice/VoiceTestCard.tsx +38 -4
  707. package/src/interfaces/web/src/constants/index.ts +1 -0
  708. package/src/interfaces/web/src/hooks/useChannelPrefs.ts +39 -0
  709. package/src/interfaces/web/src/hooks/useChat.ts +1092 -85
  710. package/src/interfaces/web/src/hooks/useChatActivity.ts +24 -0
  711. package/src/interfaces/web/src/hooks/useInbox.ts +26 -4
  712. package/src/interfaces/web/src/hooks/useLiveMessages.ts +16 -0
  713. package/src/interfaces/web/src/hooks/useOllamaModels.ts +79 -0
  714. package/src/interfaces/web/src/hooks/useRecorder.ts +198 -0
  715. package/src/interfaces/web/src/hooks/useTokenBootstrap.ts +23 -6
  716. package/src/interfaces/web/src/i18n/en.ts +832 -175
  717. package/src/interfaces/web/src/i18n/es.ts +841 -188
  718. package/src/interfaces/web/src/lib/api/agents.ts +23 -4
  719. package/src/interfaces/web/src/lib/api/code.ts +17 -0
  720. package/src/interfaces/web/src/lib/api/commitments.ts +7 -1
  721. package/src/interfaces/web/src/lib/api/conversations.ts +38 -11
  722. package/src/interfaces/web/src/lib/api/embeddings.ts +3 -0
  723. package/src/interfaces/web/src/lib/api/engines.ts +14 -0
  724. package/src/interfaces/web/src/lib/api/groups.ts +93 -0
  725. package/src/interfaces/web/src/lib/api/images.ts +193 -0
  726. package/src/interfaces/web/src/lib/api/inbox.ts +29 -5
  727. package/src/interfaces/web/src/lib/api/integrations.ts +9 -0
  728. package/src/interfaces/web/src/lib/api/media.ts +126 -0
  729. package/src/interfaces/web/src/lib/api/net.ts +44 -0
  730. package/src/interfaces/web/src/lib/api/profiles.ts +12 -0
  731. package/src/interfaces/web/src/lib/api/projects.ts +9 -1
  732. package/src/interfaces/web/src/lib/api/routines.ts +9 -1
  733. package/src/interfaces/web/src/lib/api/sessions.ts +18 -0
  734. package/src/interfaces/web/src/lib/api/skills.ts +8 -0
  735. package/src/interfaces/web/src/lib/api/super_agent.ts +3 -0
  736. package/src/interfaces/web/src/lib/api/tasks.ts +46 -6
  737. package/src/interfaces/web/src/lib/api/tools.ts +2 -0
  738. package/src/interfaces/web/src/lib/api/transcribe.ts +31 -0
  739. package/src/interfaces/web/src/lib/api/turns.ts +20 -0
  740. package/src/interfaces/web/src/lib/api/voice.ts +72 -2
  741. package/src/interfaces/web/src/lib/api.ts +3 -0
  742. package/src/interfaces/web/src/lib/channels.ts +214 -0
  743. package/src/interfaces/web/src/lib/chat-activity.ts +175 -0
  744. package/src/interfaces/web/src/lib/chat-prefs.ts +48 -0
  745. package/src/interfaces/web/src/lib/code-context.ts +0 -2
  746. package/src/interfaces/web/src/lib/http.ts +51 -17
  747. package/src/interfaces/web/src/lib/inbox-selection.ts +29 -0
  748. package/src/interfaces/web/src/lib/live.ts +252 -0
  749. package/src/interfaces/web/src/lib/net.ts +211 -0
  750. package/src/interfaces/web/src/lib/notify.ts +331 -0
  751. package/src/interfaces/web/src/lib/projectNav.ts +40 -0
  752. package/src/interfaces/web/src/lib/pwa.ts +115 -0
  753. package/src/interfaces/web/src/lib/qvox.ts +24 -0
  754. package/src/interfaces/web/src/lib/slug.ts +3 -0
  755. package/src/interfaces/web/src/lib/tone.ts +150 -0
  756. package/src/interfaces/web/src/main.tsx +15 -4
  757. package/src/interfaces/web/src/screens/ApxAdminScreen.tsx +33 -11
  758. package/src/interfaces/web/src/screens/InboxScreen.tsx +126 -71
  759. package/src/interfaces/web/src/screens/ProjectScreen.tsx +8 -4
  760. package/src/interfaces/web/src/screens/SettingsScreen.tsx +7 -4
  761. package/src/interfaces/web/src/screens/base/AgentDefaultsTab.tsx +30 -9
  762. package/src/interfaces/web/src/screens/base/CommitmentsTab.tsx +150 -168
  763. package/src/interfaces/web/src/screens/base/LogsTab.tsx +8 -7
  764. package/src/interfaces/web/src/screens/base/SessionsTab.tsx +99 -37
  765. package/src/interfaces/web/src/screens/base/WorkspacesTab.tsx +1 -1
  766. package/src/interfaces/web/src/screens/mobile/MobileChat.tsx +85 -0
  767. package/src/interfaces/web/src/screens/mobile/MobileChatList.tsx +244 -0
  768. package/src/interfaces/web/src/screens/mobile/MobileCommitments.tsx +350 -0
  769. package/src/interfaces/web/src/screens/mobile/MobileScreen.tsx +138 -0
  770. package/src/interfaces/web/src/screens/mobile/MobileTabBar.tsx +105 -0
  771. package/src/interfaces/web/src/screens/mobile/MobileTasks.tsx +407 -0
  772. package/src/interfaces/web/src/screens/mobile/NewChatSheet.tsx +313 -0
  773. package/src/interfaces/web/src/screens/mobile/mobileList.tsx +194 -0
  774. package/src/interfaces/web/src/screens/mobile/routes.ts +239 -0
  775. package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +135 -64
  776. package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +0 -1
  777. package/src/interfaces/web/src/screens/modules/ImagesScreen.tsx +172 -0
  778. package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +36 -4
  779. package/src/interfaces/web/src/screens/project/AgentBrainGraph.tsx +117 -30
  780. package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +537 -92
  781. package/src/interfaces/web/src/screens/project/AgentsTab.tsx +344 -93
  782. package/src/interfaces/web/src/screens/project/ArtifactsTab.tsx +1 -1
  783. package/src/interfaces/web/src/screens/project/ChatTab.tsx +1160 -94
  784. package/src/interfaces/web/src/screens/project/IntegrationsTab.tsx +3 -2
  785. package/src/interfaces/web/src/screens/project/McpsTab.tsx +62 -14
  786. package/src/interfaces/web/src/screens/project/Overview.tsx +36 -15
  787. package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +93 -8
  788. package/src/interfaces/web/src/screens/project/SkillsTab.tsx +4 -1
  789. package/src/interfaces/web/src/screens/project/StructureTab.tsx +5 -4
  790. package/src/interfaces/web/src/screens/project/TasksTab.tsx +351 -129
  791. package/src/interfaces/web/src/screens/project/VarsTab.tsx +17 -5
  792. package/src/interfaces/web/src/styles.css +106 -31
  793. package/src/interfaces/web/src/types/daemon.ts +246 -2
  794. package/src/interfaces/web/src/vite-env.d.ts +20 -0
  795. package/src/interfaces/tui/plugin/command-shim.ts +0 -109
  796. package/src/interfaces/web/components.json +0 -25
  797. package/src/interfaces/web/dist/assets/index-CvEoGtTf.js +0 -849
  798. package/src/interfaces/web/dist/assets/index-CvEoGtTf.js.map +0 -1
  799. package/src/interfaces/web/dist/assets/index-DzBBXFaO.css +0 -1
  800. package/src/interfaces/web/src/components/tasks/TaskDetailPanel.tsx +0 -142
  801. package/src/interfaces/web/src/components/ui/accordion.tsx +0 -72
  802. package/src/interfaces/web/src/components/ui/alert-dialog.tsx +0 -187
  803. package/src/interfaces/web/src/components/ui/alert.tsx +0 -76
  804. package/src/interfaces/web/src/components/ui/aspect-ratio.tsx +0 -22
  805. package/src/interfaces/web/src/components/ui/avatar.tsx +0 -107
  806. package/src/interfaces/web/src/components/ui/breadcrumb.tsx +0 -125
  807. package/src/interfaces/web/src/components/ui/button-group.tsx +0 -87
  808. package/src/interfaces/web/src/components/ui/calendar.tsx +0 -221
  809. package/src/interfaces/web/src/components/ui/card.tsx +0 -103
  810. package/src/interfaces/web/src/components/ui/carousel.tsx +0 -242
  811. package/src/interfaces/web/src/components/ui/chart.tsx +0 -371
  812. package/src/interfaces/web/src/components/ui/checkbox.tsx +0 -29
  813. package/src/interfaces/web/src/components/ui/collapsible.tsx +0 -19
  814. package/src/interfaces/web/src/components/ui/combobox.tsx +0 -295
  815. package/src/interfaces/web/src/components/ui/command.tsx +0 -196
  816. package/src/interfaces/web/src/components/ui/direction.tsx +0 -4
  817. package/src/interfaces/web/src/components/ui/drawer.tsx +0 -134
  818. package/src/interfaces/web/src/components/ui/empty.tsx +0 -104
  819. package/src/interfaces/web/src/components/ui/field.tsx +0 -236
  820. package/src/interfaces/web/src/components/ui/hover-card.tsx +0 -51
  821. package/src/interfaces/web/src/components/ui/input-otp.tsx +0 -85
  822. package/src/interfaces/web/src/components/ui/item.tsx +0 -201
  823. package/src/interfaces/web/src/components/ui/menubar.tsx +0 -280
  824. package/src/interfaces/web/src/components/ui/native-select.tsx +0 -61
  825. package/src/interfaces/web/src/components/ui/navigation-menu.tsx +0 -168
  826. package/src/interfaces/web/src/components/ui/pagination.tsx +0 -130
  827. package/src/interfaces/web/src/components/ui/progress.tsx +0 -83
  828. package/src/interfaces/web/src/components/ui/radio-group.tsx +0 -36
  829. package/src/interfaces/web/src/components/ui/resizable.tsx +0 -50
  830. package/src/interfaces/web/src/components/ui/scroll-area.tsx +0 -53
  831. package/src/interfaces/web/src/components/ui/sidebar.tsx +0 -726
  832. package/src/interfaces/web/src/components/ui/slider.tsx +0 -52
  833. package/src/interfaces/web/src/components/ui/sonner.tsx +0 -49
  834. package/src/interfaces/web/src/components/ui/table.tsx +0 -116
  835. package/src/interfaces/web/src/components/ui/toggle-group.tsx +0 -87
  836. package/src/interfaces/web/src/components/ui/toggle.tsx +0 -45
  837. package/src/interfaces/web/src/hooks/use-mobile.ts +0 -19
  838. package/src/interfaces/web/src/screens/base/GlobalTasksTab.tsx +0 -161
@@ -0,0 +1,314 @@
1
+ // apx image — text-to-image from the command line.
2
+ //
3
+ // apx image "<prompt>" generate with the routed engine
4
+ // apx image "<prompt>" --out fox.png write it where you say
5
+ // apx image "<prompt>" --size 768x512 --steps 8 --cfg 1.0
6
+ // apx image "<prompt>" --provider a1111 force one engine
7
+ // apx image "<prompt>" --init photo.png img2img: start from that picture
8
+ // apx image "<prompt>" --control pose.png ControlNet: keep its structure
9
+ // apx image "<prompt>" --init p.png --mask m.png inpaint just the white part
10
+ // apx image providers which engines are reachable
11
+ // apx image capabilities [--provider <id>] models/samplers a server offers
12
+ //
13
+ // Two reference-image flags, not one, because they are two operations against
14
+ // two routes: --init hands the sampler a canvas to repaint (how far it may
15
+ // stray is --denoise), --control hands it a structure to build a fresh picture
16
+ // around (how hard to enforce it is --control-strength). --img-ref is accepted
17
+ // as a friendlier spelling of --init, which is the one people reach for.
18
+ // The file is read here and sent as base64, so the daemon may be on another
19
+ // machine; express caps a body at 2 MB, which SIZE_LIMIT keeps us under.
20
+ //
21
+ // A thin client over the daemon's POST /api/images/generate — the same routing
22
+ // the web panel and any agent surface use, so a picture made here is made the
23
+ // same way everywhere. The daemon writes into ~/.apx/images/<date>/; --out
24
+ // copies the result to a path of your choosing. Nothing is ever written into a
25
+ // project checkout unless --out asks for it.
26
+
27
+ import fs from "node:fs";
28
+ import path from "node:path";
29
+ import { spawn } from "node:child_process";
30
+ import { http } from "../http.js";
31
+
32
+ const c = {
33
+ reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m",
34
+ green: "\x1b[32m", red: "\x1b[31m", yellow: "\x1b[33m", cyan: "\x1b[36m",
35
+ };
36
+ const NO_COLOR = !!process.env.NO_COLOR;
37
+ const paint = (code) => (s) => (NO_COLOR ? s : `${code}${s}${c.reset}`);
38
+ const err = paint(c.red);
39
+ const dim = paint(c.dim);
40
+ const bold = paint(c.bold);
41
+ const ok = paint(c.green);
42
+ const warn = paint(c.yellow);
43
+ const cy = paint(c.cyan);
44
+
45
+ // Reserved first positionals. A prompt that is literally one of these words
46
+ // needs --prompt to disambiguate; anything else is read as the prompt.
47
+ const SUBCOMMANDS = new Set(["providers", "capabilities"]);
48
+
49
+ const USAGE = [
50
+ "Usage: apx image \"<prompt>\" [--out <file>] [--provider <id>] [--size 768x512]",
51
+ " [--steps N] [--cfg N] [--seed N] [--negative \"...\"]",
52
+ " [--count N] [--model <id>] [--format png|jpeg|webp] [--json] [--open]",
53
+ " [--init <img> [--denoise 0.45] [--mask <img> [--mask-blur N]]]",
54
+ " [--control <img> [--control-strength 0.8]]",
55
+ " apx image providers",
56
+ " apx image capabilities [--provider <id>]",
57
+ ].join("\n");
58
+
59
+ // Express parses request bodies up to 2 MB (host/daemon/api.js). Base64 costs
60
+ // a third on top, so refuse a little under that with an actionable message
61
+ // rather than letting the daemon answer an opaque 413.
62
+ const SIZE_LIMIT = 1_400_000;
63
+
64
+ /**
65
+ * Read a reference image and return bare base64.
66
+ *
67
+ * Failing loudly here matters: a mistyped path that fell through would render
68
+ * a perfectly good picture that simply ignored the reference, and nothing in
69
+ * the output would say why.
70
+ */
71
+ function readImageFlag(value, flagName) {
72
+ const file = str(value);
73
+ if (!file) throw new Error(`${flagName} needs a file path`);
74
+ const resolved = path.resolve(file);
75
+ if (!fs.existsSync(resolved)) throw new Error(`${flagName}: no such file — ${resolved}`);
76
+ const stat = fs.statSync(resolved);
77
+ if (stat.isDirectory()) throw new Error(`${flagName}: that is a directory — ${resolved}`);
78
+ if (stat.size > SIZE_LIMIT) {
79
+ throw new Error(
80
+ `${flagName}: ${formatBytes(stat.size)} is too big (limit ${formatBytes(SIZE_LIMIT)}).\n` +
81
+ ` Shrink it first, e.g. sips -Z 768 "${resolved}" --out /tmp/ref.png`
82
+ );
83
+ }
84
+ return fs.readFileSync(resolved).toString("base64");
85
+ }
86
+
87
+ function num(v) {
88
+ if (v === undefined || v === true) return undefined;
89
+ const n = Number(v);
90
+ return Number.isFinite(n) ? n : undefined;
91
+ }
92
+
93
+ function str(v) {
94
+ return typeof v === "string" && v.trim() ? v.trim() : undefined;
95
+ }
96
+
97
+ /** Flags → the body POST /images/generate expects. Absent stays absent. */
98
+ function requestFrom(flags) {
99
+ const body = {};
100
+ const put = (key, value) => { if (value !== undefined) body[key] = value; };
101
+ put("provider", str(flags.provider));
102
+ put("size", str(flags.size));
103
+ put("width", num(flags.width));
104
+ put("height", num(flags.height));
105
+ put("steps", num(flags.steps));
106
+ put("cfg_scale", num(flags.cfg ?? flags["cfg-scale"] ?? flags.cfg_scale));
107
+ put("seed", num(flags.seed));
108
+ put("count", num(flags.count ?? flags.n));
109
+ put("sampler", str(flags.sampler));
110
+ put("scheduler", str(flags.scheduler));
111
+ put("negative_prompt", str(flags.negative ?? flags["negative-prompt"]));
112
+ put("model", str(flags.model));
113
+ put("format", str(flags.format));
114
+
115
+ // --img-ref is the same thing as --init; refuse to guess if both are given
116
+ // with different files, since silently dropping one changes the picture.
117
+ const initFlag = flags.init ?? flags["img-ref"] ?? flags.img_ref;
118
+ const controlFlag = flags.control ?? flags["control-image"] ?? flags.control_image;
119
+ if (initFlag !== undefined && controlFlag !== undefined) {
120
+ throw new Error(
121
+ "--init and --control are different operations; pass one.\n" +
122
+ " --init repaint that picture (img2img)\n" +
123
+ " --control build a new one around its structure (ControlNet)"
124
+ );
125
+ }
126
+ const maskFlag = flags.mask;
127
+ if (maskFlag !== undefined && initFlag === undefined) {
128
+ throw new Error("--mask needs --init: inpainting repaints part of a picture you supply");
129
+ }
130
+ if (initFlag !== undefined) {
131
+ put("init_image", readImageFlag(initFlag, "--init"));
132
+ put("denoising_strength", num(flags.denoise ?? flags["denoising-strength"] ?? flags.denoising_strength));
133
+ }
134
+ if (maskFlag !== undefined) {
135
+ put("mask", readImageFlag(maskFlag, "--mask"));
136
+ put("mask_blur", num(flags["mask-blur"] ?? flags.mask_blur));
137
+ // Named rather than numeric: nobody remembers that 2 means latent noise,
138
+ // and it is the knob that decides whether the prompt lands at all.
139
+ const fill = str(flags["inpaint-fill"] ?? flags.inpaint_fill);
140
+ if (fill) {
141
+ const FILLS = { fill: 0, original: 1, noise: 2, nothing: 3 };
142
+ if (!(fill in FILLS)) {
143
+ throw new Error(`--inpaint-fill: unknown "${fill}". Use: ${Object.keys(FILLS).join(" | ")}`);
144
+ }
145
+ put("inpainting_fill", FILLS[fill]);
146
+ }
147
+ }
148
+ if (controlFlag !== undefined) {
149
+ put("control_image", readImageFlag(controlFlag, "--control"));
150
+ put("control_strength", num(flags["control-strength"] ?? flags.control_strength));
151
+ }
152
+ return body;
153
+ }
154
+
155
+ /** Open a file in the OS viewer. Best-effort — never fails the command. */
156
+ function openFile(file) {
157
+ const bin = process.platform === "darwin" ? "open"
158
+ : process.platform === "win32" ? "explorer"
159
+ : "xdg-open";
160
+ try {
161
+ spawn(bin, [file], { detached: true, stdio: "ignore" }).unref();
162
+ } catch { /* no viewer is not an error */ }
163
+ }
164
+
165
+ /**
166
+ * Copy the daemon's file to --out. Copy, not move: the gallery under ~/.apx
167
+ * stays the durable record, so a later `--out` overwrite never loses the only
168
+ * copy of a picture.
169
+ */
170
+ function copyOut(srcPath, outFlag, index, total) {
171
+ let dest = path.resolve(outFlag);
172
+ if (fs.existsSync(dest) && fs.statSync(dest).isDirectory()) {
173
+ dest = path.join(dest, path.basename(srcPath));
174
+ } else if (total > 1 && index > 0) {
175
+ // Several images, one --out name: number them rather than overwrite.
176
+ const ext = path.extname(dest);
177
+ dest = path.join(path.dirname(dest), `${path.basename(dest, ext)}-${index + 1}${ext}`);
178
+ }
179
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
180
+ fs.copyFileSync(srcPath, dest);
181
+ return dest;
182
+ }
183
+
184
+ function formatBytes(n) {
185
+ if (!Number.isFinite(n)) return "";
186
+ if (n >= 1024 * 1024) return `${(n / 1024 / 1024).toFixed(1)} MB`;
187
+ // Sub-kilobyte files are real (the mock engine writes a 180-byte swatch);
188
+ // rounding them to "0 KB" reads as a failure.
189
+ if (n >= 1024) return `${Math.round(n / 1024)} KB`;
190
+ return `${n} B`;
191
+ }
192
+
193
+ async function cmdProviders(flags) {
194
+ const info = await http.get("/api/images/providers");
195
+ if (flags.json) {
196
+ process.stdout.write(JSON.stringify(info, null, 2) + "\n");
197
+ return;
198
+ }
199
+ process.stdout.write(
200
+ `${bold("Routing")} ${info.mode}` +
201
+ (info.mode === "single" ? ` → ${cy(info.configured_provider)}` : ` (${info.order.join(" → ")})`) +
202
+ "\n\n"
203
+ );
204
+ for (const e of info.engines || []) {
205
+ const mark = e.available ? ok("●") : dim("○");
206
+ const state = [
207
+ e.available ? "reachable" : "unreachable",
208
+ e.configured ? "configured" : "not configured",
209
+ e.enabled ? null : "disabled",
210
+ ].filter(Boolean).join(", ");
211
+ const label = e.label && e.label !== e.id ? ` ${dim(`(${e.label})`)}` : "";
212
+ process.stdout.write(` ${mark} ${bold(e.id)}${label} ${dim(state)}\n`);
213
+ if (e.note) process.stdout.write(` ${dim(e.note)}\n`);
214
+ }
215
+ const d = info.defaults || {};
216
+ process.stdout.write(
217
+ `\n${dim(`Defaults: ${d.width}x${d.height}, ${d.steps} steps, cfg ${d.cfg_scale}, ${d.format}`)}\n`
218
+ );
219
+ }
220
+
221
+ async function cmdCapabilities(flags) {
222
+ const q = flags.provider ? `?provider=${encodeURIComponent(String(flags.provider))}` : "";
223
+ const info = await http.get(`/api/images/capabilities${q}`);
224
+ if (flags.json) {
225
+ process.stdout.write(JSON.stringify(info, null, 2) + "\n");
226
+ return;
227
+ }
228
+ const caps = info.capabilities;
229
+ process.stdout.write(`${bold(info.provider)}\n`);
230
+ if (!caps) {
231
+ process.stdout.write(dim(" No catalog — the engine is unreachable or has no discovery route.\n"));
232
+ return;
233
+ }
234
+ const row = (label, list) => {
235
+ if (!list?.length) return;
236
+ process.stdout.write(` ${bold(label)} ${list.join(", ")}\n`);
237
+ };
238
+ row("Models ", caps.models);
239
+ row("Samplers ", caps.samplers);
240
+ row("Schedulers", caps.schedulers);
241
+ row("Formats ", caps.formats);
242
+ if (caps.defaults?.width) {
243
+ process.stdout.write(dim(` Server defaults: ${caps.defaults.width}x${caps.defaults.height}\n`));
244
+ }
245
+ }
246
+
247
+ export async function cmdImage(args) {
248
+ const flags = args.flags || {};
249
+ const first = args._[0];
250
+
251
+ if (SUBCOMMANDS.has(first) && !str(flags.prompt)) {
252
+ if (first === "providers") return cmdProviders(flags);
253
+ if (first === "capabilities") return cmdCapabilities(flags);
254
+ }
255
+
256
+ const prompt = str(flags.prompt) || args._.filter(Boolean).join(" ").trim();
257
+ if (!prompt) {
258
+ process.stderr.write(err("apx image: missing prompt") + "\n" + dim(USAGE) + "\n");
259
+ process.exitCode = 1;
260
+ return;
261
+ }
262
+
263
+ let body;
264
+ try {
265
+ body = { prompt, ...requestFrom(flags) };
266
+ } catch (e) {
267
+ process.stderr.write(err(`apx image: ${e.message}`) + "\n");
268
+ process.exitCode = 1;
269
+ return;
270
+ }
271
+ const quiet = !!flags.json;
272
+ if (!quiet) {
273
+ process.stderr.write(dim(`Generating… ${prompt.length > 60 ? prompt.slice(0, 60) + "…" : prompt}`) + "\n");
274
+ }
275
+
276
+ let result;
277
+ try {
278
+ result = await http.post("/api/images/generate", body);
279
+ } catch (e) {
280
+ process.stderr.write(err(`apx image: ${e.message}`) + "\n");
281
+ process.exitCode = 1;
282
+ return;
283
+ }
284
+
285
+ const images = result.images || [];
286
+ const written = images.map((img, i) =>
287
+ (flags.out ? copyOut(img.path, String(flags.out), i, images.length) : img.path));
288
+
289
+ if (flags.json) {
290
+ process.stdout.write(JSON.stringify({ ...result, written }, null, 2) + "\n");
291
+ } else {
292
+ for (const file of written) process.stdout.write(file + "\n");
293
+ const secs = (result.elapsed_ms / 1000).toFixed(1);
294
+ const bits = [
295
+ result.provider,
296
+ result.meta?.mode && result.meta.mode !== "txt2img" ? result.meta.mode : null,
297
+ result.model || null,
298
+ `${result.request?.width}x${result.request?.height}`,
299
+ images[0]?.seed != null ? `seed ${images[0].seed}` : null,
300
+ formatBytes(images[0]?.bytes),
301
+ `${secs}s`,
302
+ ].filter(Boolean);
303
+ process.stderr.write(dim(` ${bits.join(" · ")}`) + "\n");
304
+ // Say what the engine could not honor — a silently ignored --steps is the
305
+ // difference between "this looks wrong" and "that engine has no steps".
306
+ if (result.ignored?.length) {
307
+ process.stderr.write(
308
+ warn(` ${result.provider} ignored: ${result.ignored.join(", ")}`) + "\n"
309
+ );
310
+ }
311
+ }
312
+
313
+ if (flags.open) written.forEach(openFile);
314
+ }
@@ -69,35 +69,97 @@ export async function cmdMcpList(args = {}) {
69
69
  }
70
70
  }
71
71
 
72
+ // A flag that was given without a value parses as `true`. For value-carrying
73
+ // flags that means "the user typed --url with nothing after it" — not a value.
74
+ function flagValue(v) {
75
+ return v === undefined || v === true ? null : String(v);
76
+ }
77
+
78
+ // `--header "Authorization: Bearer xxx"` and `--header X-Api-Key=abc` both work:
79
+ // we split on whichever of `:` / `=` comes first, so a value may contain either.
80
+ function parseHeaders(raw) {
81
+ const headers = {};
82
+ for (const h of Array.isArray(raw) ? raw : [raw]) {
83
+ const s = String(h);
84
+ const cuts = [s.indexOf(":"), s.indexOf("=")].filter((i) => i >= 0);
85
+ if (cuts.length === 0) {
86
+ throw new Error(`apx mcp add: bad --header "${s}" (use "Name: value" or Name=value)`);
87
+ }
88
+ const cut = Math.min(...cuts);
89
+ const key = s.slice(0, cut).trim();
90
+ if (!key) throw new Error(`apx mcp add: bad --header "${s}" (empty header name)`);
91
+ headers[key] = s.slice(cut + 1).trim();
92
+ }
93
+ return headers;
94
+ }
95
+
96
+ function parseEnv(raw) {
97
+ const env = {};
98
+ for (const e of Array.isArray(raw) ? raw : [raw]) {
99
+ const [k, ...rest] = String(e).split("=");
100
+ env[k] = rest.join("=");
101
+ }
102
+ return env;
103
+ }
104
+
72
105
  export async function cmdMcpAdd(args) {
73
106
  const name = args._[0];
74
107
  if (!name) throw new Error("apx mcp add: missing <name>");
75
- const command = args.flags.command;
76
- if (!command || command === true) throw new Error("apx mcp add: --command required");
77
108
 
78
- // Args after `--` go to the MCP. `args._` already excludes the `--` separator
79
- // when our parser strips it. We treat anything in args._ after [0] as args.
80
- const mcpArgs = args._.slice(1);
109
+ const command = flagValue(args.flags.command);
110
+ const url = flagValue(args.flags.url);
81
111
 
82
- const env = {};
83
- if (args.flags.env) {
84
- const entries = Array.isArray(args.flags.env) ? args.flags.env : [args.flags.env];
85
- for (const e of entries) {
86
- const [k, ...rest] = String(e).split("=");
87
- env[k] = rest.join("=");
88
- }
112
+ // --transport is sugar; the real signal is --url (http) vs --command (stdio).
113
+ // We only read it to reject a contradictory pair with a useful message.
114
+ const declared = flagValue(args.flags.transport)?.toLowerCase() || null;
115
+ if (declared && !["stdio", "http", "sse", "streamable-http"].includes(declared)) {
116
+ throw new Error(`apx mcp add: unknown --transport "${declared}" (use stdio|http)`);
117
+ }
118
+ const transport = declared === "stdio" ? "stdio" : declared ? "http" : url ? "http" : "stdio";
119
+
120
+ if (command && url) {
121
+ throw new Error("apx mcp add: pass either --command (stdio) or --url (http), not both");
122
+ }
123
+ if (transport === "http" && !url) {
124
+ throw new Error("apx mcp add: --transport http requires --url <endpoint>");
125
+ }
126
+ if (transport === "stdio" && !command) {
127
+ throw new Error(
128
+ "apx mcp add: --command required for a stdio server (for a remote one: --url <endpoint>)"
129
+ );
130
+ }
131
+ if (args.flags.header && transport !== "http") {
132
+ throw new Error("apx mcp add: --header only applies to an http server (--url)");
89
133
  }
90
134
 
91
135
  const scope = resolveWriteScope(args.flags);
92
136
  const pid = await resolveProjectId(args?.flags?.project);
93
- const result = await http.post(`/api/projects/${pid}/mcps?scope=${encodeURIComponent(scope)}`, {
94
- name,
95
- command,
96
- args: mcpArgs,
97
- env,
98
- enabled: true,
99
- });
100
- console.log(`Added MCP "${result.name}" (scope: ${scope})`);
137
+
138
+ let body;
139
+ if (transport === "http") {
140
+ body = {
141
+ name,
142
+ url,
143
+ ...(args.flags.header ? { headers: parseHeaders(args.flags.header) } : {}),
144
+ enabled: true,
145
+ };
146
+ } else {
147
+ // Args after `--` go to the MCP. `args._` already excludes the `--` separator
148
+ // when our parser strips it. We treat anything in args._ after [0] as args.
149
+ body = {
150
+ name,
151
+ command,
152
+ args: args._.slice(1),
153
+ env: args.flags.env ? parseEnv(args.flags.env) : {},
154
+ enabled: true,
155
+ };
156
+ }
157
+
158
+ const result = await http.post(
159
+ `/api/projects/${pid}/mcps?scope=${encodeURIComponent(scope)}`,
160
+ body
161
+ );
162
+ console.log(`Added MCP "${result.name}" (${transport}, scope: ${scope})`);
101
163
  }
102
164
 
103
165
  export async function cmdMcpRemove(args) {
@@ -132,11 +194,13 @@ async function toggleEnabled(args, enabled) {
132
194
  `MCP "${name}" comes from foreign source "${m.source}" — toggle it in that IDE's config directly.`
133
195
  );
134
196
  }
197
+ // Re-post only the keys that belong to this server's transport — sending
198
+ // `command: null` at an http entry would write a stdio field into it.
135
199
  await http.post(`/api/projects/${pid}/mcps?scope=${encodeURIComponent(scope)}`, {
136
200
  name: m.name,
137
- command: m.command,
138
- args: m.args,
139
- env: m.env,
201
+ ...(m.transport === "http"
202
+ ? { url: m.url, headers: m.headers || {} }
203
+ : { command: m.command, args: m.args, env: m.env }),
140
204
  enabled,
141
205
  });
142
206
  console.log(`${enabled ? "Enabled" : "Disabled"} MCP "${name}"`);
@@ -1,10 +1,12 @@
1
1
  import fs from "node:fs";
2
2
  import { findApfRoot } from "#core/apc/parser.js";
3
- import { agentMemoryPath, readAgentMemory, writeAgentMemory, ensureAgentRuntimeDir } from "#core/agent/memory.js";
3
+ import { agentMemoryPath, readAgentMemory, writeAgentMemory, appendAgentMemory } from "#core/agent/memory.js";
4
4
  import { http } from "../http.js";
5
+ import { readStdinSync } from "../stdin.js";
5
6
  import {
6
7
  proposeConsolidation, applyConsolidation, revertConsolidation, notebookSize,
7
8
  } from "#core/memory/consolidate.js";
9
+ import { pruneSelfMemory } from "#core/memory/prune.js";
8
10
  import { readSelfMemory } from "#core/agent/self-memory.js";
9
11
 
10
12
  function requireRoot() {
@@ -38,14 +40,7 @@ export async function cmdMemory(args) {
38
40
 
39
41
  if (args.flags.append && args.flags.append !== true) {
40
42
  const note = String(args.flags.append);
41
- ensureAgentRuntimeDir(root, slug);
42
- let body = readAgentMemory(root, slug);
43
- if (!/##\s+Recent context/i.test(body)) {
44
- body += body.endsWith("\n") ? "\n## Recent context\n" : "\n\n## Recent context\n";
45
- }
46
- const today = new Date().toISOString().slice(0, 10);
47
- body = body.replace(/(##\s+Recent context\s*\n)/i, `$1- ${today}: ${note}\n`);
48
- writeAgentMemory(root, slug, body);
43
+ appendAgentMemory(root, slug, note);
49
44
  await nudgeDaemon(root);
50
45
  console.log(`appended to ${slug} memory: ${note}`);
51
46
  return;
@@ -58,19 +53,6 @@ export async function cmdMemory(args) {
58
53
  process.stdout.write(body);
59
54
  }
60
55
 
61
- function readStdinSync() {
62
- const chunks = [];
63
- const buf = Buffer.alloc(65536);
64
- try {
65
- while (true) {
66
- const bytes = fs.readSync(0, buf, 0, buf.length);
67
- if (!bytes) break;
68
- chunks.push(buf.slice(0, bytes).toString("utf8"));
69
- }
70
- } catch {}
71
- return chunks.join("");
72
- }
73
-
74
56
 
75
57
  // ── The super-agent's own notebook (~/.apx/memory.md) ────────────────────────
76
58
  //
@@ -133,6 +115,37 @@ export async function cmdMemoryConsolidate(args) {
133
115
  console.log("\nUndo: apx memory revert");
134
116
  }
135
117
 
118
+ /**
119
+ * apx memory prune [--apply] [--series N] [--threshold X]
120
+ *
121
+ * Collapse replicated notebook entries (daily routine chatter, the same fact
122
+ * saved twice), keeping the newest of each. Dry by default, same contract as
123
+ * consolidate: deleting from the file the agent believes about itself is not
124
+ * something to do silently. --apply writes, after a timestamped backup.
125
+ */
126
+ export async function cmdMemoryPrune(args) {
127
+ const opts = { apply: args?.flags?.apply === true };
128
+ if (args?.flags?.series) opts.series_min = Number(args.flags.series);
129
+ if (args?.flags?.threshold) opts.near_dup = Number(args.flags.threshold);
130
+
131
+ const r = pruneSelfMemory(opts);
132
+ if (!r.removed.length) {
133
+ console.log("nothing replicated — the notebook is already clean.");
134
+ return;
135
+ }
136
+
137
+ console.log(`${r.applied ? "removed" : "would remove"} ${r.removed.length} replicated ${r.removed.length === 1 ? "entry" : "entries"} (keeping ${r.kept}):`);
138
+ for (const e of r.removed) {
139
+ const tag = e.channel && e.channel !== "memory" ? `[${e.channel}] ` : "";
140
+ console.log(` - ${e.date || "????-??-??"} ${tag}${e.text.slice(0, 80)}`);
141
+ }
142
+ if (r.applied) {
143
+ console.log(`\nbackup: ${r.backup}`);
144
+ } else {
145
+ console.log("\nNothing was written. Add --apply to prune.");
146
+ }
147
+ }
148
+
136
149
  export async function cmdMemoryRevert(args) {
137
150
  const { removed } = revertConsolidation(args?.flags?.since ? { since: String(args.flags.since) } : {});
138
151
  console.log(removed
@@ -10,11 +10,18 @@
10
10
  // /admin/web-token is loopback-only by design, so a phone cannot fetch it.
11
11
  import { readConfig, writeConfig, effectivePort, effectiveHost } from "#core/config/index.js";
12
12
  import { detectLanAddresses, validateBindHost, isLoopback, isWildcard } from "#core/net/lan.js";
13
+ import {
14
+ disableTailscaleServe,
15
+ enableTailscaleServe,
16
+ tailscaleServe,
17
+ tailscaleStatus,
18
+ } from "#core/net/tailscale.js";
13
19
 
14
20
  export const PANEL_USAGE = {
15
21
  status: "apx panel status",
16
22
  share: "apx panel share [--host <ip>]",
17
23
  unshare: "apx panel unshare",
24
+ tailscale: "apx panel tailscale <status|on|off>",
18
25
  };
19
26
 
20
27
  export async function cmdPanelStatus() {
@@ -121,3 +128,90 @@ export async function cmdPanelUnshare() {
121
128
  console.log(` Was ${was}. Nothing on your network can reach it now.`);
122
129
  console.log(" Restart the daemon to apply: apx restart");
123
130
  }
131
+
132
+
133
+ // ── Tailscale ────────────────────────────────────────────────────────────────
134
+ //
135
+ // `share` and this are not two flavours of the same thing. Sharing binds a LAN
136
+ // address: fast and private, and gone the moment the phone leaves the house.
137
+ // Tailscale gives the daemon a name that works from anywhere, and `serve` puts
138
+ // a real HTTPS certificate in front of it.
139
+ //
140
+ // That certificate is the point, not a nicety. A browser only grants a secure
141
+ // context to https:// and localhost, and without one it switches off service
142
+ // workers (so the panel cannot be installed as an app on Android), getUserMedia
143
+ // (so no voice notes) and the clipboard. Over http://192.168.x.x those three
144
+ // are off no matter what APX does.
145
+ //
146
+ // `serve` is reachable only from devices signed into the same tailnet. It is
147
+ // NOT `funnel`, which would put the panel on the public internet; nothing here
148
+ // offers that.
149
+
150
+ export async function cmdPanelTailscaleStatus() {
151
+ const port = effectivePort(readConfig());
152
+ const ts = await tailscaleStatus();
153
+
154
+ if (!ts.installed) {
155
+ console.log("tailscale: not installed on this machine");
156
+ console.log(" https://tailscale.com/download");
157
+ return;
158
+ }
159
+ if (!ts.running) {
160
+ console.log(`tailscale: installed but not connected (state: ${ts.state || "unknown"})`);
161
+ console.log(" Sign in from the Tailscale app, then run this again.");
162
+ return;
163
+ }
164
+
165
+ console.log(`tailscale: connected as ${ts.dnsName || ts.hostname || ts.ipv4}`);
166
+ console.log(` Tailnet address: http://${ts.ipv4}:${port}`);
167
+
168
+ const serve = await tailscaleServe(port);
169
+ if (serve.serving && serve.url) {
170
+ console.log(` Published HTTPS: ${serve.url}`);
171
+ console.log("");
172
+ console.log(" Install the panel from that URL: it is the only address here that a");
173
+ console.log(" browser will treat as secure, which is what installing as an app, the");
174
+ console.log(" microphone and the clipboard all depend on.");
175
+ console.log(" Stop publishing: apx panel tailscale off");
176
+ } else {
177
+ console.log(" Not published over HTTPS yet: apx panel tailscale on");
178
+ if (serve.error) console.log(` (serve status said: ${serve.error})`);
179
+ }
180
+ }
181
+
182
+ export async function cmdPanelTailscaleOn() {
183
+ const port = effectivePort(readConfig());
184
+ try {
185
+ const out = await enableTailscaleServe(port);
186
+ if (out.serving && out.url) {
187
+ console.log(`panel published on your tailnet — ${out.url}`);
188
+ console.log("");
189
+ console.log(" Only devices signed into the same tailnet can reach it. This is");
190
+ console.log(" `serve`, not `funnel`: nothing is exposed to the public internet.");
191
+ console.log("");
192
+ console.log(" Open that URL on the phone and pair it there (Settings → Devices).");
193
+ console.log(" Installing the app from it also gets you the microphone.");
194
+ } else {
195
+ console.log("tailscale accepted the command but is not reporting a published URL yet.");
196
+ console.log(" Check again in a moment: apx panel tailscale status");
197
+ }
198
+ } catch (e) {
199
+ console.error(`apx panel tailscale on: ${e.message}`);
200
+ console.error("");
201
+ console.error(" HTTPS on a tailnet needs MagicDNS and HTTPS certificates enabled for");
202
+ console.error(" the tailnet, in the Tailscale admin console (DNS page).");
203
+ process.exit(1);
204
+ }
205
+ }
206
+
207
+ export async function cmdPanelTailscaleOff() {
208
+ const port = effectivePort(readConfig());
209
+ try {
210
+ await disableTailscaleServe(port);
211
+ console.log("panel is no longer published on your tailnet");
212
+ console.log(" The tailnet IP still reaches it; only the HTTPS name is gone.");
213
+ } catch (e) {
214
+ console.error(`apx panel tailscale off: ${e.message}`);
215
+ process.exit(1);
216
+ }
217
+ }
@@ -4,6 +4,7 @@
4
4
  // apx profile show <id> [--preview]
5
5
  // apx profile install <id|path> [--force]
6
6
  // apx profile use <id> [--force]
7
+ // apx profile sync
7
8
  // apx profile off
8
9
  // apx profile config [--set k=v]... [--interactive]
9
10
  // apx profile doctor [<id>]
@@ -21,6 +22,7 @@ export const PROFILE_USAGE = {
21
22
  show: "apx profile show <id> [--preview]",
22
23
  install: "apx profile install <id|path> [--force]",
23
24
  use: "apx profile use <id> [--force]",
25
+ sync: "apx profile sync",
24
26
  off: "apx profile off",
25
27
  config: "apx profile config [--set key=value]... [--interactive]",
26
28
  doctor: "apx profile doctor [<id>]",
@@ -145,6 +147,18 @@ export async function cmdProfileUse(args) {
145
147
  if (!r.profile.active) console.log(" (warning: profile did not activate)");
146
148
  }
147
149
 
150
+ export async function cmdProfileSync(args) {
151
+ const r = await http.post("/api/profiles/sync", { id: args?.flags?.profile || null });
152
+
153
+ const { installed = [], skipped = [] } = r.routines || {};
154
+ console.log(`profile "${r.id}"${r.version ? ` v${r.version}` : ""} re-read from disk`);
155
+ if (installed.length) console.log(` routines refreshed: ${installed.join(", ")}`);
156
+ else console.log(" no routines to refresh");
157
+ for (const s of skipped) {
158
+ console.log(` routine "${s.name}" left alone (${s.reason.replace(/_/g, " ")})`);
159
+ }
160
+ }
161
+
148
162
  export async function cmdProfileOff() {
149
163
  const r = await http.post("/api/profiles/off", {});
150
164
  if (!r.was) {