@agentprojectcontext/apx 1.77.3 → 1.79.0

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 (356) hide show
  1. package/README.md +23 -9
  2. package/package.json +12 -12
  3. package/src/core/agent/build-agent-system.js +3 -2
  4. package/src/core/agent/constants.js +3 -2
  5. package/src/core/agent/loop/greeting-guard.js +55 -0
  6. package/src/core/agent/loop/side-effects.js +52 -0
  7. package/src/core/agent/prompt-builder.js +49 -8
  8. package/src/core/agent/run-agent.js +43 -53
  9. package/src/core/agent/security.js +1 -1
  10. package/src/core/agent/self-memory.js +4 -2
  11. package/src/core/agent/skills/index-store.js +2 -2
  12. package/src/core/agent/skills/loader.js +3 -22
  13. package/src/core/agent/super-agent.js +0 -2
  14. package/src/core/agent/tool-summary.js +65 -0
  15. package/src/core/agent/tools/handlers/call-runtime.js +4 -4
  16. package/src/core/agent/tools/handlers/list-commitments.js +80 -0
  17. package/src/core/agent/tools/handlers/list-tasks.js +66 -27
  18. package/src/core/agent/tools/handlers/record-commitment.js +68 -0
  19. package/src/core/agent/tools/handlers/search-sessions.js +1 -1
  20. package/src/core/agent/tools/handlers/send-telegram.js +68 -2
  21. package/src/core/agent/tools/handlers/set-permission-mode.js +11 -4
  22. package/src/core/agent/tools/names.js +64 -0
  23. package/src/core/agent/tools/registry.js +9 -0
  24. package/src/core/agent/tools/tool-call-parser.js +70 -1
  25. package/src/core/apc/context-copy.js +1 -1
  26. package/src/core/apc/frontmatter.js +85 -0
  27. package/src/core/apc/parser.js +9 -21
  28. package/src/core/apc/paths.js +8 -8
  29. package/src/core/apc/scaffold.js +5 -4
  30. package/src/core/channels/telegram/ask-callbacks.js +35 -0
  31. package/src/core/channels/telegram/config.js +201 -0
  32. package/src/core/channels/telegram/dispatch.js +3 -0
  33. package/src/core/channels/telegram/reply.js +30 -5
  34. package/src/core/config/index.js +25 -183
  35. package/src/core/config/paths.js +57 -1
  36. package/src/core/config/redact.js +22 -0
  37. package/src/core/confirmation/adapters/web.js +1 -1
  38. package/src/core/daemon/service.js +238 -0
  39. package/src/core/deck/manifest.js +12 -12
  40. package/src/core/desktop/autostart.js +3 -2
  41. package/src/core/desktop/process.js +4 -4
  42. package/src/core/engines/gemini.js +322 -60
  43. package/src/core/engines/openai-compatible.js +21 -2
  44. package/src/core/engines/presets.js +2 -2
  45. package/src/core/http-tools/browser.js +1 -1
  46. package/src/core/http-tools/catalog.js +551 -0
  47. package/src/core/http-tools/fetch.js +1 -1
  48. package/src/core/http-tools/glob.js +3 -3
  49. package/src/core/http-tools/grep.js +2 -9
  50. package/src/core/http-tools/inline-handlers.js +59 -0
  51. package/src/core/http-tools/registry.js +31 -615
  52. package/src/core/http-tools/search.js +2 -2
  53. package/src/core/identity/self.js +6 -7
  54. package/src/core/identity/telegram.js +3 -3
  55. package/src/core/logging.js +6 -5
  56. package/src/core/mcp/sources.js +12 -16
  57. package/src/core/memory/consolidate.js +225 -0
  58. package/src/core/memory/indexer.js +2 -5
  59. package/src/core/nudge/index.js +192 -0
  60. package/src/core/nudge/policy.js +143 -0
  61. package/src/core/nudge/store.js +141 -0
  62. package/src/core/profiles/bundled/secretary/PROFILE.md +8 -9
  63. package/src/core/profiles/bundled/secretary/config.schema.json +33 -3
  64. package/src/core/profiles/bundled/secretary/routines/day-close.json +7 -3
  65. package/src/core/profiles/bundled/secretary/routines/day-open.json +7 -3
  66. package/src/core/profiles/bundled/secretary/routines/watch.json +13 -0
  67. package/src/core/profiles/lifecycle.js +0 -2
  68. package/src/core/profiles/store.js +2 -7
  69. package/src/core/routines/runner.js +103 -4
  70. package/src/core/routines/signals.js +270 -0
  71. package/src/core/runtime-skills/apx-agency-agents/SKILL.md +2 -2
  72. package/src/core/runtime-skills/apx-profile/SKILL.md +3 -3
  73. package/src/core/runtime-skills/apx-project/SKILL.md +1 -1
  74. package/src/core/runtime-skills/apx-task/SKILL.md +8 -8
  75. package/src/core/runtime-skills/apx-telegram/SKILL.md +4 -4
  76. package/src/core/runtime-skills/apx-voice/SKILL.md +4 -4
  77. package/src/core/runtimes/detect.js +2 -2
  78. package/src/core/sessions/index.js +800 -0
  79. package/src/core/stores/code-sessions.js +3 -14
  80. package/src/core/stores/commitments.js +331 -0
  81. package/src/core/stores/engine-sessions.js +0 -4
  82. package/src/core/stores/messages.js +4 -5
  83. package/src/core/stores/organization.js +9 -11
  84. package/src/core/stores/routines.js +23 -14
  85. package/src/core/stores/runtime-callbacks.js +2 -1
  86. package/src/core/util/json-file.js +128 -0
  87. package/src/core/util/thinking.js +51 -0
  88. package/src/core/vars/sources.js +14 -21
  89. package/src/core/voice/stt-models.js +1 -1
  90. package/src/core/voice/tts.js +5 -4
  91. package/src/host/daemon/api/admin-config.js +5 -5
  92. package/src/host/daemon/api/admin.js +8 -7
  93. package/src/host/daemon/api/agents.js +16 -16
  94. package/src/host/daemon/api/artifact-preview.js +8 -8
  95. package/src/host/daemon/api/artifacts.js +7 -7
  96. package/src/host/daemon/api/code.js +8 -8
  97. package/src/host/daemon/api/commitments.js +135 -0
  98. package/src/host/daemon/api/config.js +6 -6
  99. package/src/host/daemon/api/confirm.js +2 -2
  100. package/src/host/daemon/api/connections.js +2 -2
  101. package/src/host/daemon/api/conversations.js +12 -12
  102. package/src/host/daemon/api/deck.js +6 -6
  103. package/src/host/daemon/api/desktop.js +8 -8
  104. package/src/host/daemon/api/embeddings.js +4 -4
  105. package/src/host/daemon/api/engines.js +8 -7
  106. package/src/host/daemon/api/exec.js +5 -4
  107. package/src/host/daemon/api/files-project.js +6 -6
  108. package/src/host/daemon/api/health.js +2 -2
  109. package/src/host/daemon/api/identity.js +3 -3
  110. package/src/host/daemon/api/inbox.js +2 -2
  111. package/src/host/daemon/api/integrations.js +23 -19
  112. package/src/host/daemon/api/mcps.js +16 -12
  113. package/src/host/daemon/api/messages.js +5 -5
  114. package/src/host/daemon/api/nudges.js +112 -0
  115. package/src/host/daemon/api/organization.js +8 -8
  116. package/src/host/daemon/api/pairing.js +6 -6
  117. package/src/host/daemon/api/plugins.js +3 -3
  118. package/src/host/daemon/api/prefix.js +20 -0
  119. package/src/host/daemon/api/profiles.js +9 -9
  120. package/src/host/daemon/api/projects.js +5 -5
  121. package/src/host/daemon/api/routines.js +32 -8
  122. package/src/host/daemon/api/run.js +2 -2
  123. package/src/host/daemon/api/runtimes.js +6 -6
  124. package/src/host/daemon/api/self-memory.js +50 -0
  125. package/src/host/daemon/api/sessions-search.js +18 -11
  126. package/src/host/daemon/api/sessions.js +6 -6
  127. package/src/host/daemon/api/shared.js +59 -13
  128. package/src/host/daemon/api/skills.js +12 -12
  129. package/src/host/daemon/api/super-agent.js +4 -4
  130. package/src/host/daemon/api/tasks.js +11 -11
  131. package/src/host/daemon/api/telegram.js +61 -24
  132. package/src/host/daemon/api/tools.js +7 -7
  133. package/src/host/daemon/api/top-level.js +7 -7
  134. package/src/host/daemon/api/transcribe.js +6 -6
  135. package/src/host/daemon/api/tts.js +3 -3
  136. package/src/host/daemon/api/vars.js +11 -8
  137. package/src/host/daemon/api/voice.js +9 -7
  138. package/src/host/daemon/api/web.js +28 -32
  139. package/src/host/daemon/api.js +83 -48
  140. package/src/host/daemon/callback-reconciler.js +16 -0
  141. package/src/host/daemon/db.js +1 -1
  142. package/src/host/daemon/desktop-ws.js +7 -3
  143. package/src/host/daemon/index.js +11 -5
  144. package/src/host/daemon/plugins/desktop/index.js +8 -2
  145. package/src/host/daemon/plugins/telegram/index.js +7 -2
  146. package/src/host/daemon/stt-venv.js +20 -81
  147. package/src/host/daemon/wakeup.js +18 -4
  148. package/src/interfaces/acp/index.js +3 -3
  149. package/src/interfaces/acp/session.js +2 -2
  150. package/src/interfaces/cli/commands/a2a.js +2 -2
  151. package/src/interfaces/cli/commands/agent.js +3 -3
  152. package/src/interfaces/cli/commands/artifact.js +13 -13
  153. package/src/interfaces/cli/commands/chat.js +3 -3
  154. package/src/interfaces/cli/commands/command.js +2 -2
  155. package/src/interfaces/cli/commands/commitment.js +154 -0
  156. package/src/interfaces/cli/commands/config.js +4 -4
  157. package/src/interfaces/cli/commands/daemon.js +74 -18
  158. package/src/interfaces/cli/commands/desktop.js +7 -14
  159. package/src/interfaces/cli/commands/exec.js +2 -2
  160. package/src/interfaces/cli/commands/log.js +3 -4
  161. package/src/interfaces/cli/commands/mcp.js +9 -9
  162. package/src/interfaces/cli/commands/memory.js +75 -2
  163. package/src/interfaces/cli/commands/messages.js +5 -5
  164. package/src/interfaces/cli/commands/model.js +0 -18
  165. package/src/interfaces/cli/commands/nudge.js +130 -0
  166. package/src/interfaces/cli/commands/obsidian.js +5 -5
  167. package/src/interfaces/cli/commands/org.js +5 -5
  168. package/src/interfaces/cli/commands/pair.js +6 -6
  169. package/src/interfaces/cli/commands/plugins.js +2 -2
  170. package/src/interfaces/cli/commands/profile.js +10 -10
  171. package/src/interfaces/cli/commands/project-config.js +6 -6
  172. package/src/interfaces/cli/commands/project.js +10 -10
  173. package/src/interfaces/cli/commands/routine.js +8 -9
  174. package/src/interfaces/cli/commands/runtime.js +2 -2
  175. package/src/interfaces/cli/commands/search.js +0 -1
  176. package/src/interfaces/cli/commands/session.js +12 -40
  177. package/src/interfaces/cli/commands/sessions.js +21 -798
  178. package/src/interfaces/cli/commands/setup.js +16 -6
  179. package/src/interfaces/cli/commands/skills.js +1 -2
  180. package/src/interfaces/cli/commands/status.js +3 -3
  181. package/src/interfaces/cli/commands/task.js +8 -8
  182. package/src/interfaces/cli/commands/telegram.js +21 -21
  183. package/src/interfaces/cli/commands/voice.js +6 -6
  184. package/src/interfaces/cli/help/index.js +2245 -0
  185. package/src/interfaces/cli/http.js +9 -4
  186. package/src/interfaces/cli/index.js +14 -2857
  187. package/src/interfaces/cli/routes/acp.js +13 -0
  188. package/src/interfaces/cli/routes/agent.js +27 -0
  189. package/src/interfaces/cli/routes/artifact.js +28 -0
  190. package/src/interfaces/cli/routes/chat.js +11 -0
  191. package/src/interfaces/cli/routes/code.js +11 -0
  192. package/src/interfaces/cli/routes/command.js +21 -0
  193. package/src/interfaces/cli/routes/commitment.js +19 -0
  194. package/src/interfaces/cli/routes/config.js +16 -0
  195. package/src/interfaces/cli/routes/connections.js +11 -0
  196. package/src/interfaces/cli/routes/conversations.js +21 -0
  197. package/src/interfaces/cli/routes/daemon.js +25 -0
  198. package/src/interfaces/cli/routes/desktop.js +20 -0
  199. package/src/interfaces/cli/routes/env.js +13 -0
  200. package/src/interfaces/cli/routes/exec.js +11 -0
  201. package/src/interfaces/cli/routes/identity.js +11 -0
  202. package/src/interfaces/cli/routes/index.js +75 -0
  203. package/src/interfaces/cli/routes/init.js +11 -0
  204. package/src/interfaces/cli/routes/log.js +20 -0
  205. package/src/interfaces/cli/routes/mcp.js +22 -0
  206. package/src/interfaces/cli/routes/memory.js +19 -0
  207. package/src/interfaces/cli/routes/messages.js +16 -0
  208. package/src/interfaces/cli/routes/model.js +11 -0
  209. package/src/interfaces/cli/routes/nudge.js +17 -0
  210. package/src/interfaces/cli/routes/obsidian.js +17 -0
  211. package/src/interfaces/cli/routes/org.js +34 -0
  212. package/src/interfaces/cli/routes/overlay.js +10 -0
  213. package/src/interfaces/cli/routes/pair.js +17 -0
  214. package/src/interfaces/cli/routes/panel.js +16 -0
  215. package/src/interfaces/cli/routes/permission.js +11 -0
  216. package/src/interfaces/cli/routes/plugins.js +21 -0
  217. package/src/interfaces/cli/routes/profile.js +27 -0
  218. package/src/interfaces/cli/routes/project.js +41 -0
  219. package/src/interfaces/cli/routes/restart.js +15 -0
  220. package/src/interfaces/cli/routes/routine.js +28 -0
  221. package/src/interfaces/cli/routes/run.js +11 -0
  222. package/src/interfaces/cli/routes/search.js +11 -0
  223. package/src/interfaces/cli/routes/send.js +11 -0
  224. package/src/interfaces/cli/routes/session.js +26 -0
  225. package/src/interfaces/cli/routes/sessions.js +15 -0
  226. package/src/interfaces/cli/routes/setup.js +18 -0
  227. package/src/interfaces/cli/routes/skills.js +20 -0
  228. package/src/interfaces/cli/routes/status.js +12 -0
  229. package/src/interfaces/cli/routes/task.js +26 -0
  230. package/src/interfaces/cli/routes/telegram.js +39 -0
  231. package/src/interfaces/cli/routes/update.js +24 -0
  232. package/src/interfaces/cli/routes/voice.js +17 -0
  233. package/src/interfaces/desktop/main.js +6 -7
  234. package/src/interfaces/desktop/renderer.js +0 -5
  235. package/src/interfaces/mcp-server/index.js +15 -14
  236. package/src/interfaces/tui/_shims/globals.d.ts +8 -0
  237. package/src/interfaces/tui/tsconfig.json +4 -1
  238. package/src/interfaces/web/README.md +6 -6
  239. package/src/interfaces/web/dist/assets/index-CvEoGtTf.js +849 -0
  240. package/src/interfaces/web/dist/assets/index-CvEoGtTf.js.map +1 -0
  241. package/src/interfaces/web/dist/assets/index-DzBBXFaO.css +1 -0
  242. package/src/interfaces/web/dist/index.html +2 -2
  243. package/src/interfaces/web/package-lock.json +11 -10
  244. package/src/interfaces/web/src/components/AddProjectDialog.tsx +1 -1
  245. package/src/interfaces/web/src/components/Section.tsx +18 -3
  246. package/src/interfaces/web/src/components/agents/AgentFormFields.tsx +1 -1
  247. package/src/interfaces/web/src/components/chat/ChatList.tsx +2 -2
  248. package/src/interfaces/web/src/components/chat/MessageBubble.tsx +13 -0
  249. package/src/interfaces/web/src/components/chat/SkillPicker.tsx +1 -1
  250. package/src/interfaces/web/src/components/code/CodeFileTree.tsx +1 -1
  251. package/src/interfaces/web/src/components/code/CodeTerminal.tsx +1 -1
  252. package/src/interfaces/web/src/components/cron/CronPicker.tsx +196 -0
  253. package/src/interfaces/web/src/components/desktop/DesktopStatusCard.tsx +1 -1
  254. package/src/interfaces/web/src/components/files/FileBrowser.tsx +2 -2
  255. package/src/interfaces/web/src/components/inbox/InboxList.tsx +145 -0
  256. package/src/interfaces/web/src/components/memory/MemoryBrowser.tsx +36 -6
  257. package/src/interfaces/web/src/components/routines/ExecutionsList.tsx +1 -1
  258. package/src/interfaces/web/src/components/routines/RoutineDetail.tsx +16 -4
  259. package/src/interfaces/web/src/components/routines/RoutineEditor.tsx +14 -4
  260. package/src/interfaces/web/src/components/routines/shared.ts +14 -5
  261. package/src/interfaces/web/src/components/settings/DesktopSettingsPanel.tsx +1 -1
  262. package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +1 -1
  263. package/src/interfaces/web/src/components/settings/NudgePanel.tsx +183 -0
  264. package/src/interfaces/web/src/components/settings/ProfilePanel.tsx +36 -12
  265. package/src/interfaces/web/src/components/settings/SkillsInspectorPanel.tsx +1 -1
  266. package/src/interfaces/web/src/components/settings/SkillsManager.tsx +2 -2
  267. package/src/interfaces/web/src/components/tasks/TaskDetailPanel.tsx +1 -1
  268. package/src/interfaces/web/src/components/ui/filter-chips.tsx +47 -0
  269. package/src/interfaces/web/src/components/ui.tsx +1 -0
  270. package/src/interfaces/web/src/constants/index.ts +1 -0
  271. package/src/interfaces/web/src/hooks/useChat.ts +5 -1
  272. package/src/interfaces/web/src/hooks/useDaemonStatus.ts +1 -1
  273. package/src/interfaces/web/src/hooks/useDevices.ts +1 -1
  274. package/src/interfaces/web/src/hooks/useEngines.ts +1 -1
  275. package/src/interfaces/web/src/hooks/useGlobalConfig.ts +2 -2
  276. package/src/interfaces/web/src/hooks/useIdentity.ts +1 -1
  277. package/src/interfaces/web/src/hooks/useInbox.ts +1 -1
  278. package/src/interfaces/web/src/hooks/useNudges.ts +38 -0
  279. package/src/interfaces/web/src/hooks/useProfiles.ts +3 -3
  280. package/src/interfaces/web/src/hooks/useProjects.ts +1 -1
  281. package/src/interfaces/web/src/hooks/useTelegram.ts +3 -3
  282. package/src/interfaces/web/src/hooks/useTokenBootstrap.ts +3 -3
  283. package/src/interfaces/web/src/i18n/en.ts +127 -0
  284. package/src/interfaces/web/src/i18n/es.ts +127 -0
  285. package/src/interfaces/web/src/lib/api/admin.ts +11 -11
  286. package/src/interfaces/web/src/lib/api/agents.ts +14 -14
  287. package/src/interfaces/web/src/lib/api/artifacts.ts +11 -11
  288. package/src/interfaces/web/src/lib/api/code.ts +1 -1
  289. package/src/interfaces/web/src/lib/api/commitments.ts +57 -0
  290. package/src/interfaces/web/src/lib/api/conversations.ts +8 -8
  291. package/src/interfaces/web/src/lib/api/deck.ts +3 -3
  292. package/src/interfaces/web/src/lib/api/desktop.ts +8 -8
  293. package/src/interfaces/web/src/lib/api/embeddings.ts +3 -3
  294. package/src/interfaces/web/src/lib/api/engines.ts +3 -3
  295. package/src/interfaces/web/src/lib/api/filesystem.ts +2 -2
  296. package/src/interfaces/web/src/lib/api/health.ts +1 -1
  297. package/src/interfaces/web/src/lib/api/identity.ts +2 -2
  298. package/src/interfaces/web/src/lib/api/inbox.ts +1 -1
  299. package/src/interfaces/web/src/lib/api/integrations.ts +8 -8
  300. package/src/interfaces/web/src/lib/api/mcps.ts +6 -6
  301. package/src/interfaces/web/src/lib/api/messages.ts +3 -3
  302. package/src/interfaces/web/src/lib/api/notebook.ts +23 -0
  303. package/src/interfaces/web/src/lib/api/nudges.ts +53 -0
  304. package/src/interfaces/web/src/lib/api/organization.ts +7 -7
  305. package/src/interfaces/web/src/lib/api/profiles.ts +8 -8
  306. package/src/interfaces/web/src/lib/api/projectFiles.ts +5 -5
  307. package/src/interfaces/web/src/lib/api/projects.ts +12 -12
  308. package/src/interfaces/web/src/lib/api/routines.ts +7 -7
  309. package/src/interfaces/web/src/lib/api/sessions.ts +2 -2
  310. package/src/interfaces/web/src/lib/api/skills.ts +11 -11
  311. package/src/interfaces/web/src/lib/api/super_agent.ts +3 -3
  312. package/src/interfaces/web/src/lib/api/tasks.ts +12 -12
  313. package/src/interfaces/web/src/lib/api/telegram.ts +14 -14
  314. package/src/interfaces/web/src/lib/api/tools.ts +1 -1
  315. package/src/interfaces/web/src/lib/api/vars.ts +4 -4
  316. package/src/interfaces/web/src/lib/api/voice.ts +6 -6
  317. package/src/interfaces/web/src/lib/cron.ts +196 -0
  318. package/src/interfaces/web/src/lib/when.ts +32 -0
  319. package/src/interfaces/web/src/screens/InboxScreen.tsx +107 -77
  320. package/src/interfaces/web/src/screens/ProjectScreen.tsx +5 -2
  321. package/src/interfaces/web/src/screens/SettingsScreen.tsx +17 -3
  322. package/src/interfaces/web/src/screens/base/AgentDefaultsTab.tsx +1 -1
  323. package/src/interfaces/web/src/screens/base/CommitmentsTab.tsx +239 -0
  324. package/src/interfaces/web/src/screens/base/GlobalTasksTab.tsx +103 -20
  325. package/src/interfaces/web/src/screens/base/LogsTab.tsx +18 -3
  326. package/src/interfaces/web/src/screens/base/SessionsTab.tsx +1 -1
  327. package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +1 -1
  328. package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +1 -1
  329. package/src/interfaces/web/src/screens/modules/DesktopScreen.tsx +1 -1
  330. package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +1 -1
  331. package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +8 -8
  332. package/src/interfaces/web/src/screens/project/AgentsTab.tsx +2 -2
  333. package/src/interfaces/web/src/screens/project/ChatTab.tsx +24 -6
  334. package/src/interfaces/web/src/screens/project/ConfigTab.tsx +1 -1
  335. package/src/interfaces/web/src/screens/project/McpsTab.tsx +3 -3
  336. package/src/interfaces/web/src/screens/project/Overview.tsx +6 -6
  337. package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +15 -13
  338. package/src/interfaces/web/src/screens/project/StructureTab.tsx +1 -1
  339. package/src/interfaces/web/src/screens/project/TasksTab.tsx +1 -1
  340. package/src/interfaces/web/src/screens/project/VarsTab.tsx +1 -1
  341. package/src/interfaces/web/src/types/daemon.ts +10 -1
  342. package/src/interfaces/web/vite.config.ts +13 -18
  343. package/src/interfaces/web/dist/assets/index-BptlbKjU.js +0 -824
  344. package/src/interfaces/web/dist/assets/index-BptlbKjU.js.map +0 -1
  345. package/src/interfaces/web/dist/assets/index-D_EJEA1n.css +0 -1
  346. package/src/skills/apc-context/SKILL.md +0 -159
  347. /package/src/{host/daemon → core}/runtimes/_spawn.js +0 -0
  348. /package/src/{host/daemon → core}/runtimes/aider.js +0 -0
  349. /package/src/{host/daemon → core}/runtimes/antigravity.js +0 -0
  350. /package/src/{host/daemon → core}/runtimes/claude-code.js +0 -0
  351. /package/src/{host/daemon → core}/runtimes/codex.js +0 -0
  352. /package/src/{host/daemon → core}/runtimes/cursor-agent.js +0 -0
  353. /package/src/{host/daemon → core}/runtimes/gemini-cli.js +0 -0
  354. /package/src/{host/daemon → core}/runtimes/index.js +0 -0
  355. /package/src/{host/daemon → core}/runtimes/opencode.js +0 -0
  356. /package/src/{host/daemon → core}/runtimes/qwen-code.js +0 -0
@@ -0,0 +1,270 @@
1
+ // Signals — deterministic detection of things worth noticing.
2
+ //
3
+ // THE SPLIT THIS FILE EXISTS FOR: detection is cheap and mechanical; judgement
4
+ // is expensive and contextual. Mixing them means paying a language model every
5
+ // five minutes to conclude that nothing is happening. Everything here is a
6
+ // pure function over stored state — no model, no network, no clock beyond the
7
+ // `now` you pass in — so a watch routine that finds nothing costs nothing, and
8
+ // every rule below is testable with synthetic state.
9
+ //
10
+ // Thresholds are PARAMETERS, never constants. "Stale after 7 days" is a
11
+ // judgement about how someone works, and judgements belong to the profile.
12
+ //
13
+ // A signal is:
14
+ // { type, project_id, project_name, severity, subject, detected_at, payload }
15
+ //
16
+ // `subject` is a one-line human phrasing — the detector already knows exactly
17
+ // what it found, and making the model re-derive it from payload fields is how
18
+ // summaries drift from the data they claim to describe.
19
+ import { listTasks } from "#core/stores/tasks.js";
20
+ import { listCommitments } from "#core/stores/commitments.js";
21
+ import { nowIso } from "#core/util/time.js";
22
+
23
+ /** Every detector, keyed by the type it emits. */
24
+ export const SIGNAL_TYPES = Object.freeze([
25
+ "overdue_task",
26
+ "blocked_task",
27
+ "stale_project",
28
+ "commitment_due",
29
+ "overdue_commitment",
30
+ ]);
31
+
32
+ /** Defaults chosen to be quiet. A watcher that cries on day one gets turned off. */
33
+ export const DEFAULT_THRESHOLDS = Object.freeze({
34
+ blocked_hours: 48,
35
+ stale_project_days: 7,
36
+ commitment_lead_hours: 48,
37
+ /** Detectors to run. Empty = all of them. */
38
+ types: [],
39
+ });
40
+
41
+ // ---------------------------------------------------------------------------
42
+ // detectors — each takes (project, opts) and returns Signal[]
43
+ // ---------------------------------------------------------------------------
44
+
45
+ /** A task whose due date has passed and which nobody closed. */
46
+ function detectOverdueTasks(project, { now }) {
47
+ const today = now.slice(0, 10);
48
+ return listTasks(project.storagePath, { state: "open" })
49
+ .filter((t) => t.due && t.due < today)
50
+ .map((t) =>
51
+ signal(project, {
52
+ type: "overdue_task",
53
+ // A task one day late and one three weeks late are not the same event.
54
+ severity: daysBetween(t.due, today) >= 7 ? "high" : "normal",
55
+ subject: `"${t.title}" was due ${t.due}`,
56
+ payload: { task_id: t.id, title: t.title, due: t.due, days_late: daysBetween(t.due, today) },
57
+ }),
58
+ );
59
+ }
60
+
61
+ /**
62
+ * A task sitting in `blocked` long enough that nobody is coming back to it.
63
+ *
64
+ * Uses updated_at, not created_at: a task blocked this morning is a normal
65
+ * working state, and flagging it would train the user to ignore the watcher.
66
+ */
67
+ function detectBlockedTasks(project, { now, blocked_hours }) {
68
+ const cutoff = new Date(Date.parse(now) - blocked_hours * 3_600_000).toISOString();
69
+ return listTasks(project.storagePath, { state: "open", status: "blocked" })
70
+ .filter((t) => (t.updated_at || t.created_at || "") < cutoff)
71
+ .map((t) =>
72
+ signal(project, {
73
+ type: "blocked_task",
74
+ severity: "normal",
75
+ subject: `"${t.title}" has been blocked since ${(t.updated_at || t.created_at || "").slice(0, 10)}`,
76
+ payload: { task_id: t.id, title: t.title, since: t.updated_at || t.created_at },
77
+ }),
78
+ );
79
+ }
80
+
81
+ /**
82
+ * A project nobody has touched.
83
+ *
84
+ * WHAT "ACTIVITY" MEANS HERE: the newest task or commitment event in the
85
+ * project's store. APX has no single per-project activity timestamp, and
86
+ * folding every conversation on a five-minute tick would defeat the point of a
87
+ * cheap detector. So this measures what it can actually see, and the phrasing
88
+ * says so — "no task or commitment activity", not "nothing happened". A caller
89
+ * with a better timestamp can pass `last_activity_at` and it wins.
90
+ *
91
+ * Claiming more than the data supports is the failure mode that kills trust in
92
+ * a watcher: one confident "you have abandoned this" about a project the user
93
+ * worked on all week, and they stop believing the rest.
94
+ *
95
+ * Deliberately ONE signal per project rather than per silent item — the point
96
+ * is "you have forgotten about this", and saying it once is the whole message.
97
+ *
98
+ * A project with nothing recorded at all is skipped: a freshly registered
99
+ * project is not neglected, and greeting someone with "this is stale" the day
100
+ * they add it is exactly what gets a watcher muted.
101
+ */
102
+ function detectStaleProject(project, { now, stale_project_days }) {
103
+ const last = project.last_activity_at || lastRecordedActivity(project.storagePath);
104
+ if (!last) return [];
105
+ const days = daysBetween(last.slice(0, 10), now.slice(0, 10));
106
+ if (days < stale_project_days) return [];
107
+ const measured = project.last_activity_at ? "activity" : "task or commitment activity";
108
+ return [
109
+ signal(project, {
110
+ type: "stale_project",
111
+ severity: days >= stale_project_days * 3 ? "normal" : "low",
112
+ subject: `no ${measured} on ${project.name || project.path || "this project"} for ${days} days`,
113
+ payload: { days, last_activity_at: last, measured },
114
+ }),
115
+ ];
116
+ }
117
+
118
+ /** Newest task or commitment timestamp in a project store, or "" when empty. */
119
+ function lastRecordedActivity(storagePath) {
120
+ let newest = "";
121
+ const bump = (v) => { if (v && v > newest) newest = v; };
122
+ try {
123
+ for (const t of listTasks(storagePath, { state: "all" })) bump(t.updated_at || t.created_at);
124
+ } catch { /* unreadable → treated as no evidence, not as staleness */ }
125
+ try {
126
+ for (const c of listCommitments(storagePath, { state: "all" })) bump(c.updated_at || c.created_at);
127
+ } catch { /* same */ }
128
+ return newest;
129
+ }
130
+
131
+ /** A promise coming due inside the lead window — still time to keep it. */
132
+ function detectCommitmentsDue(project, { now, commitment_lead_hours }) {
133
+ const horizon = new Date(Date.parse(now) + commitment_lead_hours * 3_600_000).toISOString();
134
+ return listCommitments(project.storagePath, { state: "open" })
135
+ .filter((c) => c.due && c.due >= now && c.due <= horizon)
136
+ .map((c) =>
137
+ signal(project, {
138
+ type: "commitment_due",
139
+ // Higher than an equivalent task on purpose: someone is waiting, and a
140
+ // warning that arrives in time is worth more than one that arrives after.
141
+ severity: "high",
142
+ subject: `you promised ${c.counterparty}: ${c.body} — due ${c.due.slice(0, 10)}`,
143
+ payload: { commitment_id: c.id, counterparty: c.counterparty, due: c.due, body: c.body },
144
+ }),
145
+ );
146
+ }
147
+
148
+ /** A promise already past its date and still open. The costliest thing here. */
149
+ function detectOverdueCommitments(project, { now }) {
150
+ return listCommitments(project.storagePath, { state: "open", overdue: true, now })
151
+ .map((c) =>
152
+ signal(project, {
153
+ type: "overdue_commitment",
154
+ severity: "critical",
155
+ subject: `you owe ${c.counterparty}: ${c.body} — was due ${c.due.slice(0, 10)}`,
156
+ payload: {
157
+ commitment_id: c.id, counterparty: c.counterparty, due: c.due, body: c.body,
158
+ days_late: daysBetween(c.due.slice(0, 10), now.slice(0, 10)),
159
+ },
160
+ }),
161
+ );
162
+ }
163
+
164
+ const DETECTORS = {
165
+ overdue_task: detectOverdueTasks,
166
+ blocked_task: detectBlockedTasks,
167
+ stale_project: detectStaleProject,
168
+ commitment_due: detectCommitmentsDue,
169
+ overdue_commitment: detectOverdueCommitments,
170
+ };
171
+
172
+ // ---------------------------------------------------------------------------
173
+ // public API
174
+ // ---------------------------------------------------------------------------
175
+
176
+ /**
177
+ * Run the configured detectors over the given projects.
178
+ *
179
+ * @param {{id, name?, path?, storagePath, last_activity_at?}[]} projects
180
+ * @param {object} opts thresholds + `types` + `now` (ISO, injectable for tests)
181
+ * @returns {{ signals: object[], skipped: {id, error}[] }}
182
+ */
183
+ export function detectSignals(projects, opts = {}) {
184
+ const cfg = { ...DEFAULT_THRESHOLDS, ...opts, now: opts.now || nowIso() };
185
+ const wanted = Array.isArray(cfg.types) && cfg.types.length
186
+ ? cfg.types.filter((t) => t in DETECTORS)
187
+ : SIGNAL_TYPES;
188
+
189
+ const signals = [];
190
+ const skipped = [];
191
+
192
+ for (const project of projects || []) {
193
+ if (!project?.storagePath) continue;
194
+ for (const type of wanted) {
195
+ try {
196
+ signals.push(...DETECTORS[type](project, cfg));
197
+ } catch (e) {
198
+ // One unreadable log must not blank the whole sweep — and must not be
199
+ // silent either, or the watcher reports "all clear" when it is blind.
200
+ skipped.push({ id: project.id, type, error: e?.message || String(e) });
201
+ }
202
+ }
203
+ }
204
+
205
+ signals.sort(bySeverityThenDate);
206
+ return { signals, skipped };
207
+ }
208
+
209
+ const SEVERITY_RANK = { critical: 0, high: 1, normal: 2, low: 3 };
210
+
211
+ function bySeverityThenDate(a, b) {
212
+ const s = (SEVERITY_RANK[a.severity] ?? 9) - (SEVERITY_RANK[b.severity] ?? 9);
213
+ if (s !== 0) return s;
214
+ return String(a.subject).localeCompare(String(b.subject));
215
+ }
216
+
217
+ /**
218
+ * Render signals as the block a routine hands the model.
219
+ *
220
+ * Pre-rendered rather than passed as JSON because the model's job here is
221
+ * judgement — "is any of this worth interrupting for?" — not parsing.
222
+ */
223
+ export function formatSignals(signals) {
224
+ if (!signals?.length) return "";
225
+ const lines = signals.map(
226
+ (s) => `- [${s.severity}] ${s.project_name ? `${s.project_name}: ` : ""}${s.subject}`,
227
+ );
228
+ return lines.join("\n");
229
+ }
230
+
231
+ /** The highest severity present, for the interruption budget. */
232
+ export function peakSeverity(signals) {
233
+ let best = "low";
234
+ for (const s of signals || []) {
235
+ if ((SEVERITY_RANK[s.severity] ?? 9) < (SEVERITY_RANK[best] ?? 9)) best = s.severity;
236
+ }
237
+ return signals?.length ? best : "low";
238
+ }
239
+
240
+ /** Thresholds from a profile's config, falling back to the defaults. */
241
+ export function thresholdsFromConfig(profileConfig = {}) {
242
+ const pick = (key, fallback) => {
243
+ const v = Number.parseInt(profileConfig[key], 10);
244
+ return Number.isFinite(v) && v > 0 ? v : fallback;
245
+ };
246
+ return {
247
+ blocked_hours: pick("blocked_task_hours", DEFAULT_THRESHOLDS.blocked_hours),
248
+ stale_project_days: pick("stale_project_days", DEFAULT_THRESHOLDS.stale_project_days),
249
+ commitment_lead_hours: pick("commitment_lead_hours", DEFAULT_THRESHOLDS.commitment_lead_hours),
250
+ };
251
+ }
252
+
253
+ // ---------------------------------------------------------------------------
254
+
255
+ function signal(project, fields) {
256
+ return {
257
+ project_id: project.id ?? null,
258
+ project_name: project.name || project.path || "",
259
+ detected_at: nowIso(),
260
+ ...fields,
261
+ };
262
+ }
263
+
264
+ /** Whole days between two YYYY-MM-DD strings. Negative when `to` precedes `from`. */
265
+ function daysBetween(from, to) {
266
+ const a = Date.parse(`${String(from).slice(0, 10)}T00:00:00Z`);
267
+ const b = Date.parse(`${String(to).slice(0, 10)}T00:00:00Z`);
268
+ if (!Number.isFinite(a) || !Number.isFinite(b)) return 0;
269
+ return Math.round((b - a) / 86_400_000);
270
+ }
@@ -68,7 +68,7 @@ import_agent({ slug: "cody-developer", project: "<name-or-path>" })
68
68
 
69
69
  ## Web equivalents
70
70
 
71
- Agent defaults tab (`/p/0/agent-defaults`): same CRUD — "New" (POST `/agents/vault`), per-card "Edit" (PATCH `/agents/vault/:slug`, copy-on-write for bundled), "Delete"/"Hide" (DELETE), "Show removed" toggle with "Restore" button.
71
+ Agent defaults tab (`/p/0/agent-defaults`): same CRUD — "New" (POST `/api/agents/vault`), per-card "Edit" (PATCH `/api/agents/vault/:slug`, copy-on-write for bundled), "Delete"/"Hide" (DELETE), "Show removed" toggle with "Restore" button.
72
72
 
73
73
  ## Which agent to use
74
74
 
@@ -107,7 +107,7 @@ is_master: false
107
107
  |---|---|
108
108
  | `role` | Shown in CLI/web; appears as "Role: …" in prompt. |
109
109
  | `model` | Default model for engine routing. |
110
- | `description` | Shown in `/agents/vault` and AgentDefaultsTab cards. |
110
+ | `description` | Shown in `/api/agents/vault` and AgentDefaultsTab cards. |
111
111
  | `language` | Adds "Default language: <code>" to system prompt. |
112
112
  | `skills` | Per-agent skill names; bodies loaded by skill resolution. |
113
113
  | `tools` | Tool hints; actual callable tools depend on invocation surface. |
@@ -113,9 +113,9 @@ install. Check the real number with `apx profile show <id>` or
113
113
 
114
114
  ## HTTP
115
115
 
116
- `GET /profiles` · `GET /profiles/:id` (includes `preview`) · `GET /profiles/doctor` ·
117
- `POST /profiles/install` · `POST /profiles/use` · `POST /profiles/off` ·
118
- `PATCH /profiles/config` · `DELETE /profiles/:id`
116
+ `GET /api/profiles` · `GET /api/profiles/:id` (includes `preview`) · `GET /api/profiles/doctor` ·
117
+ `POST /api/profiles/install` · `POST /api/profiles/use` · `POST /api/profiles/off` ·
118
+ `PATCH /api/profiles/config` · `DELETE /api/profiles/:id`
119
119
 
120
120
  ## Gotchas
121
121
 
@@ -36,7 +36,7 @@ apx project config unset <project> super_agent.model # back to glo
36
36
  apx project config edit <project> # opens $EDITOR on project_only JSON
37
37
  ```
38
38
 
39
- Every `project config` write triggers `POST /admin/reload` so the daemon picks up changes without restart.
39
+ Every `project config` write triggers `POST /api/admin/reload` so the daemon picks up changes without restart.
40
40
 
41
41
  ## `<project>` argument resolution
42
42
 
@@ -79,14 +79,14 @@ apx task drop t_abc # "no longer needed; archive without completion"
79
79
  ## Endpoint surface
80
80
 
81
81
  ```
82
- GET /projects/:pid/tasks ?state=open|done|dropped|all&tag=X&agent=Y&due_before=ISO&limit=N
83
- POST /projects/:pid/tasks { title, body?, tags?, due?, agent?, source?, meta? }
84
- GET /projects/:pid/tasks/:id
85
- PATCH /projects/:pid/tasks/:id { patch: {...} }
86
- POST /projects/:pid/tasks/:id/done { by? }
87
- POST /projects/:pid/tasks/:id/drop { by? }
88
- POST /projects/:pid/tasks/:id/reopen
89
- GET /projects/:pid/tasks-summary → { open, done, dropped, overdue, total }
82
+ GET /api/projects/:pid/tasks ?state=open|done|dropped|all&tag=X&agent=Y&due_before=ISO&limit=N
83
+ POST /api/projects/:pid/tasks { title, body?, tags?, due?, agent?, source?, meta? }
84
+ GET /api/projects/:pid/tasks/:id
85
+ PATCH /api/projects/:pid/tasks/:id { patch: {...} }
86
+ POST /api/projects/:pid/tasks/:id/done { by? }
87
+ POST /api/projects/:pid/tasks/:id/drop { by? }
88
+ POST /api/projects/:pid/tasks/:id/reopen
89
+ GET /api/projects/:pid/tasks-summary → { open, done, dropped, overdue, total }
90
90
  ```
91
91
 
92
92
  ## Don't
@@ -71,17 +71,17 @@ apx telegram send "text" --chat 123456789
71
71
  apx telegram send "text" --interrupt # bypass pending-agent queue (also: --force)
72
72
 
73
73
  # Media (daemon HTTP API — no dedicated CLI subcommand yet)
74
- curl -X POST http://127.0.0.1:7430/telegram/send_photo \
74
+ curl -X POST http://127.0.0.1:7430/api/telegram/send_photo \
75
75
  -H "Authorization: Bearer $(cat ~/.apx/daemon.token)" \
76
76
  -H "Content-Type: application/json" \
77
77
  -d '{"photo":"/abs/path.png","caption":"...","channel":"clientes"}'
78
- curl -X POST http://127.0.0.1:7430/telegram/send_voice \
78
+ curl -X POST http://127.0.0.1:7430/api/telegram/send_voice \
79
79
  -H "Authorization: Bearer $(cat ~/.apx/daemon.token)" \
80
80
  -H "Content-Type: application/json" \
81
81
  -d '{"audio":"/abs/path.ogg","duration":5,"channel":"default"}'
82
82
  ```
83
83
 
84
- Every `channel` CRUD write triggers `POST /admin/reload` so polling picks up the new wiring without restart.
84
+ Every `channel` CRUD write triggers `POST /api/admin/reload` so polling picks up the new wiring without restart.
85
85
 
86
86
  ## What "pin to project" does
87
87
 
@@ -92,7 +92,7 @@ On a message to a channel with `project: "iacrmar"`:
92
92
 
93
93
  ## What "master agent" does
94
94
 
95
- With `route_to_agent: "reviewer"`, messages go through `/projects/:pid/agents/reviewer/chat` instead of `/super-agent/chat`. The agent's `AGENT.md` + memory is used. No tools (project agents are `exec_agent`-shaped — text in, text out). Single LLM call. Use this for persona channels (reviewer, sales, support) instead of the general assistant. Empty = super-agent (default).
95
+ With `route_to_agent: "reviewer"`, messages go through `/api/projects/:pid/agents/reviewer/chat` instead of `/api/super-agent/chat`. The agent's `AGENT.md` + memory is used. No tools (project agents are `exec_agent`-shaped — text in, text out). Single LLM call. Use this for persona channels (reviewer, sales, support) instead of the general assistant. Empty = super-agent (default).
96
96
 
97
97
  ## Anti-examples
98
98
 
@@ -117,16 +117,16 @@ apx voice say "Hello from APX" --provider gemini
117
117
 
118
118
  ## Unified voice channel
119
119
 
120
- `POST /voice/turn` is one round-trip: send audio (or text), get back `{ user_text, reply_text, reply_audio_path }`. STT in, agent loop, TTS out. For overlay and future "voice room" clients.
120
+ `POST /api/voice/turn` is one round-trip: send audio (or text), get back `{ user_text, reply_text, reply_audio_path }`. STT in, agent loop, TTS out. For overlay and future "voice room" clients.
121
121
 
122
122
  ```bash
123
- curl -X POST http://127.0.0.1:7430/voice/turn \
123
+ curl -X POST http://127.0.0.1:7430/api/voice/turn \
124
124
  -H "Authorization: Bearer $(cat ~/.apx/daemon.token)" \
125
125
  -H "Content-Type: application/json" \
126
126
  -d '{"text":"Hello APX","channel":"voice"}'
127
127
  ```
128
128
 
129
- Telegram voice messages and overlay mascot still have their own STT pipelines — they don't go through `/voice/turn` yet.
129
+ Telegram voice messages and overlay mascot still have their own STT pipelines — they don't go through `/api/voice/turn` yet.
130
130
 
131
131
  ## Anti-examples
132
132
 
@@ -146,4 +146,4 @@ Telegram voice messages and overlay mascot still have their own STT pipelines
146
146
 
147
147
  - Paste base64 audio into chat. Use file paths or `send_voice` / `send_audio`.
148
148
  - Switch providers mid-routine without testing — quality varies a lot across Piper voices and cloud engines.
149
- - Expect TTS streaming yet — `apx voice say` returns a complete file. `/tts/stream` is open work.
149
+ - Expect TTS streaming yet — `apx voice say` returns a complete file. `/api/tts/stream` is open work.
@@ -1,8 +1,8 @@
1
1
  // Best-effort detection of installed agent CLIs and LLM runners.
2
2
  // We just probe the binary with `--version` (or equivalent) and don't fail if
3
3
  // it isn't there — caller decides what to do with absence.
4
- import { runProcess } from "#host/daemon/runtimes/_spawn.js";
5
- import { resolveAntigravityCli } from "#host/daemon/runtimes/antigravity.js";
4
+ import { runProcess } from "./_spawn.js";
5
+ import { resolveAntigravityCli } from "./antigravity.js";
6
6
 
7
7
  const PROBES = [
8
8
  // Coding-agent CLIs (runtimes/)