@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
@@ -2,6 +2,10 @@ import fs from "node:fs";
2
2
  import { findApfRoot } from "#core/apc/parser.js";
3
3
  import { agentMemoryPath, readAgentMemory, writeAgentMemory, ensureAgentRuntimeDir } from "#core/agent/memory.js";
4
4
  import { http } from "../http.js";
5
+ import {
6
+ proposeConsolidation, applyConsolidation, revertConsolidation, notebookSize,
7
+ } from "#core/memory/consolidate.js";
8
+ import { readSelfMemory } from "#core/agent/self-memory.js";
5
9
 
6
10
  function requireRoot() {
7
11
  const root = findApfRoot();
@@ -12,9 +16,9 @@ function requireRoot() {
12
16
  async function nudgeDaemon(root) {
13
17
  try {
14
18
  if (!(await http.ping())) return;
15
- const projects = await http.get("/projects", { autoStart: false });
19
+ const projects = await http.get("/api/projects", { autoStart: false });
16
20
  const me = projects.find((p) => p.path === root);
17
- if (me) await http.post(`/projects/${me.id}/rebuild`, undefined, { autoStart: false });
21
+ if (me) await http.post(`/api/projects/${me.id}/rebuild`, undefined, { autoStart: false });
18
22
  } catch {}
19
23
  }
20
24
 
@@ -66,3 +70,72 @@ function readStdinSync() {
66
70
  } catch {}
67
71
  return chunks.join("");
68
72
  }
73
+
74
+
75
+ // ── The super-agent's own notebook (~/.apx/memory.md) ────────────────────────
76
+ //
77
+ // Distinct from `apx memory <agent-slug>` above, which is a PROJECT agent's
78
+ // memory. This one ships in every super-agent prompt on every channel, which
79
+ // is why its size is worth showing and its growth worth controlling.
80
+
81
+ export async function cmdMemoryNotebook() {
82
+ const s = notebookSize();
83
+ console.log(`\nnotebook: ${s.entries} entries · ${s.chars} chars · ~${s.approx_tokens} tokens`);
84
+ // The number that matters: this is paid on every turn, of every channel.
85
+ console.log(` ${s.consolidated} of them written by consolidation.`);
86
+ console.log(" This file is injected into every super-agent prompt.\n");
87
+ const body = readSelfMemory();
88
+ if (body.trim()) process.stdout.write(body.endsWith("\n") ? body : body + "\n");
89
+ }
90
+
91
+ /**
92
+ * apx memory consolidate [--apply] [--limit N]
93
+ *
94
+ * Candidates arrive on STDIN, one per line. The DISTILLING is the caller's job
95
+ * — a routine with a model behind it, or a person — and the JUDGEMENT about
96
+ * what survives lives in core, so the same rules apply whoever proposes.
97
+ *
98
+ * Proposes by default. Writing needs --apply, because a background job that
99
+ * silently edits the file the agent believes about itself is not something to
100
+ * switch on quietly.
101
+ */
102
+ export async function cmdMemoryConsolidate(args) {
103
+ const raw = readStdinSync();
104
+ const candidates = raw.split("\n").map((l) => l.replace(/^[-*]\s*/, "").trim()).filter(Boolean);
105
+ if (!candidates.length) {
106
+ console.error("apx memory consolidate: no candidates on stdin (one fact per line)");
107
+ process.exit(1);
108
+ }
109
+
110
+ const limits = args?.flags?.limit ? { max_candidates: Number(args.flags.limit) } : undefined;
111
+ const { kept, rejected } = proposeConsolidation(candidates, limits ? { limits } : {});
112
+
113
+ if (!kept.length) {
114
+ console.log("nothing worth saving.");
115
+ for (const r of rejected) console.log(` skipped: ${r.reason} — ${r.text.slice(0, 60)}`);
116
+ return;
117
+ }
118
+
119
+ if (!args?.flags?.apply) {
120
+ console.log(`would save ${kept.length}:`);
121
+ for (const k of kept) console.log(` + ${k}`);
122
+ if (rejected.length) {
123
+ console.log(`\nskipped ${rejected.length}:`);
124
+ for (const r of rejected) console.log(` - ${r.reason} — ${r.text.slice(0, 60)}`);
125
+ }
126
+ console.log("\nNothing was written. Add --apply to save.");
127
+ return;
128
+ }
129
+
130
+ const { written } = applyConsolidation(kept);
131
+ console.log(`saved ${written.length} to the notebook:`);
132
+ for (const w of written) console.log(` + ${w}`);
133
+ console.log("\nUndo: apx memory revert");
134
+ }
135
+
136
+ export async function cmdMemoryRevert(args) {
137
+ const { removed } = revertConsolidation(args?.flags?.since ? { since: String(args.flags.since) } : {});
138
+ console.log(removed
139
+ ? `removed ${removed} consolidated ${removed === 1 ? "entry" : "entries"} — hand-written notes untouched`
140
+ : "nothing to revert (no consolidated entries)");
141
+ }
@@ -22,7 +22,7 @@ export async function cmdMessagesTail(args) {
22
22
  // Read from global store — no project needed
23
23
  const params = new URLSearchParams({ limit: String(n) });
24
24
  if (channel) params.set("channel", channel);
25
- const rows = await http.get(`/messages/global?${params}`);
25
+ const rows = await http.get(`/api/messages/global?${params}`);
26
26
  if (rows.length === 0) {
27
27
  console.log("(no messages)");
28
28
  return;
@@ -39,7 +39,7 @@ export async function cmdMessagesTail(args) {
39
39
  const params = new URLSearchParams({ limit: String(n) });
40
40
  if (args.flags.agent && args.flags.agent !== true) params.set("agent", args.flags.agent);
41
41
  if (channel) params.set("channel", channel);
42
- const rows = await http.get(`/projects/${pid}/messages?${params}`);
42
+ const rows = await http.get(`/api/projects/${pid}/messages?${params}`);
43
43
  if (rows.length === 0) {
44
44
  console.log("(no messages)");
45
45
  return;
@@ -82,7 +82,7 @@ export async function cmdMessagesChat(args) {
82
82
  if (isGlobal) {
83
83
  const params = new URLSearchParams({ limit: String(n) });
84
84
  if (channel) params.set("channel", channel);
85
- const rows = await http.get(`/messages/global?${params}`);
85
+ const rows = await http.get(`/api/messages/global?${params}`);
86
86
  printChatRows(rows);
87
87
  return;
88
88
  }
@@ -91,7 +91,7 @@ export async function cmdMessagesChat(args) {
91
91
  const params = new URLSearchParams({ limit: String(n) });
92
92
  if (args.flags.agent && args.flags.agent !== true) params.set("agent", args.flags.agent);
93
93
  if (channel) params.set("channel", channel);
94
- const rows = await http.get(`/projects/${pid}/messages?${params}`);
94
+ const rows = await http.get(`/api/projects/${pid}/messages?${params}`);
95
95
  printChatRows(rows.reverse());
96
96
  }
97
97
 
@@ -99,7 +99,7 @@ export async function cmdMessagesSearch(args) {
99
99
  const q = args._[0];
100
100
  if (!q) throw new Error("apx messages search: missing <query>");
101
101
  const pid = await resolveProjectId(args?.flags?.project);
102
- const rows = await http.get(`/projects/${pid}/messages/search?q=${encodeURIComponent(q)}`);
102
+ const rows = await http.get(`/api/projects/${pid}/messages/search?q=${encodeURIComponent(q)}`);
103
103
  if (rows.length === 0) {
104
104
  console.log("(no matches)");
105
105
  return;
@@ -18,24 +18,6 @@ function providersFromFallback(cfg) {
18
18
  return seen.length ? seen : [...DEFAULT_FALLBACK_ORDER];
19
19
  }
20
20
 
21
- function parseValue(raw) {
22
- try {
23
- return JSON.parse(raw);
24
- } catch {
25
- return raw;
26
- }
27
- }
28
-
29
- function setNested(obj, keyPath, value) {
30
- const parts = keyPath.split(".");
31
- let cur = obj;
32
- for (let i = 0; i < parts.length - 1; i++) {
33
- const p = parts[i];
34
- if (!cur[p] || typeof cur[p] !== "object") cur[p] = {};
35
- cur = cur[p];
36
- }
37
- cur[parts[parts.length - 1]] = value;
38
- }
39
21
 
40
22
  function ensureFallback(cfg) {
41
23
  cfg.super_agent = cfg.super_agent || {};
@@ -0,0 +1,130 @@
1
+ // apx nudge — the interruption budget: what APX said without being asked,
2
+ // what you thought of it, and how much room is left.
3
+ //
4
+ // apx nudge status
5
+ // apx nudge list [--limit N] [--kind K] [--project P] [--rated | --unrated]
6
+ // apx nudge set [--enabled true|false] [--daily-max N] [--quiet 22:00-07:30]
7
+ // [--cooldown N] [--project-cooldown N] [--kind-cooldown N]
8
+ // apx nudge check --kind K [--severity critical]
9
+ // apx nudge feedback <id> --useful | --noise [--note "..."]
10
+ import { http } from "../http.js";
11
+
12
+ export const NUDGE_USAGE = {
13
+ status: "apx nudge status",
14
+ list: "apx nudge list [--limit N] [--kind K] [--project P] [--rated|--unrated]",
15
+ set: "apx nudge set [--enabled true|false] [--daily-max N] [--quiet HH:MM-HH:MM] [--cooldown N] [--project-cooldown N] [--kind-cooldown N]",
16
+ check: "apx nudge check --kind K [--severity low|normal|high|critical]",
17
+ feedback: 'apx nudge feedback <id> --useful|--noise [--note "..."]',
18
+ };
19
+
20
+ function fail(sub, msg) {
21
+ console.error(`apx nudge ${sub}: ${msg}`);
22
+ console.error(`Usage: ${NUDGE_USAGE[sub]}`);
23
+ process.exit(1);
24
+ }
25
+
26
+ function shortTs(iso) {
27
+ if (!iso) return "";
28
+ return String(iso).replace(/T/, " ").replace(/Z$/, "").slice(0, 16);
29
+ }
30
+
31
+ export async function cmdNudgeStatus() {
32
+ const { policy, source, user_overrides } = await http.get("/api/nudges/policy");
33
+ const { meta } = await http.get("/api/nudges?limit=1");
34
+ const stats = meta?.stats || { total: 0, today: 0, rated: 0, by_kind: [] };
35
+
36
+ if (!policy.enabled) {
37
+ console.log("interruption budget: OFF — every unrequested message goes out.");
38
+ console.log(" Nothing is blocked, but everything is still recorded below.");
39
+ console.log(" Turn it on: apx nudge set --enabled true --daily-max 3");
40
+ } else {
41
+ const left = policy.daily_max > 0 ? Math.max(0, policy.daily_max - stats.today) : "∞";
42
+ console.log(`interruption budget: ON — ${stats.today} sent today, ${left} left`);
43
+ if (policy.daily_max > 0) console.log(` Daily max: ${policy.daily_max}`);
44
+ if (policy.quiet_hours) console.log(` Quiet hours: ${policy.quiet_hours}`);
45
+ if (policy.cooldown_minutes) console.log(` Cooldown: ${policy.cooldown_minutes}m between any two`);
46
+ if (policy.project_cooldown_minutes) console.log(` Per project: ${policy.project_cooldown_minutes}m`);
47
+ if (policy.kind_cooldown_minutes) console.log(` Per kind: ${policy.kind_cooldown_minutes}m`);
48
+ console.log(` Critical: ${policy.critical_bypasses_budget ? "may bypass (logged)" : "no bypass"}`);
49
+ }
50
+ // Provenance matters: a number the user did not choose should say who did.
51
+ console.log(` Set by: ${source.join(" → ")}`);
52
+ if (Object.keys(user_overrides || {}).length) {
53
+ console.log(` Your overrides: ${Object.entries(user_overrides).map(([k, v]) => `${k}=${v}`).join(", ")}`);
54
+ }
55
+
56
+ console.log("");
57
+ console.log(`recorded: ${stats.total} total, ${stats.rated} rated`);
58
+ for (const k of stats.by_kind.slice(0, 8)) {
59
+ const verdict = k.useful || k.noise ? ` (👍 ${k.useful} / 👎 ${k.noise})` : "";
60
+ console.log(` ${k.kind.padEnd(18)} ${String(k.sent).padStart(4)}${verdict}`);
61
+ }
62
+ }
63
+
64
+ export async function cmdNudgeList(args) {
65
+ const q = new URLSearchParams();
66
+ if (args?.flags?.limit) q.set("limit", args.flags.limit);
67
+ if (args?.flags?.kind) q.set("kind", args.flags.kind);
68
+ if (args?.flags?.project) q.set("project_id", args.flags.project);
69
+ if (args?.flags?.rated) q.set("with_feedback", "1");
70
+ if (args?.flags?.unrated) q.set("with_feedback", "0");
71
+
72
+ const { data } = await http.get(`/api/nudges?${q.toString()}`);
73
+ if (!data?.length) {
74
+ console.log("(nothing sent unprompted yet)");
75
+ return;
76
+ }
77
+ const idW = Math.max(...data.map((r) => r.id.length), 2);
78
+ const kindW = Math.max(...data.map((r) => String(r.kind).length), 4);
79
+ for (const row of data) {
80
+ const rating = row.feedback ? (row.feedback.useful ? "👍" : "👎") : " ";
81
+ const flag = row.bypassed_budget ? " ⚠︎bypass" : "";
82
+ console.log(
83
+ `${row.id.padEnd(idW)} ${shortTs(row.at)} ${rating} ` +
84
+ `${String(row.kind).padEnd(kindW)} ${String(row.preview || "").slice(0, 60)}${flag}`
85
+ );
86
+ }
87
+ }
88
+
89
+ export async function cmdNudgeSet(args) {
90
+ const f = args?.flags || {};
91
+ const body = {};
92
+ if (f.enabled !== undefined) body.enabled = String(f.enabled) !== "false";
93
+ if (f["daily-max"] !== undefined) body.daily_max = Number(f["daily-max"]);
94
+ if (f.quiet !== undefined) body.quiet_hours = String(f.quiet);
95
+ if (f.cooldown !== undefined) body.cooldown_minutes = Number(f.cooldown);
96
+ if (f["project-cooldown"] !== undefined) body.project_cooldown_minutes = Number(f["project-cooldown"]);
97
+ if (f["kind-cooldown"] !== undefined) body.kind_cooldown_minutes = Number(f["kind-cooldown"]);
98
+ if (!Object.keys(body).length) fail("set", "nothing to set");
99
+
100
+ const { policy, source } = await http.put("/api/nudges/policy", body);
101
+ console.log(`budget updated (${source.join(" → ")})`);
102
+ console.log(` enabled: ${policy.enabled} · daily max: ${policy.daily_max || "∞"} · quiet: ${policy.quiet_hours || "none"}`);
103
+ console.log(" Applies to the next unrequested message; nothing to restart.");
104
+ }
105
+
106
+ export async function cmdNudgeCheck(args) {
107
+ const kind = args?.flags?.kind;
108
+ if (!kind) fail("check", "--kind required");
109
+ const r = await http.post("/api/nudges/check", {
110
+ kind,
111
+ severity: args?.flags?.severity || "normal",
112
+ project_id: args?.flags?.project || null,
113
+ });
114
+ console.log(r.allowed ? `would send — ${r.reason}` : `would be held — ${r.reason}`);
115
+ if (!r.allowed && r.retry_after_ms) {
116
+ console.log(` Retry in ~${Math.ceil(r.retry_after_ms / 60000)} min.`);
117
+ }
118
+ }
119
+
120
+ export async function cmdNudgeFeedback(args) {
121
+ const id = args?._?.[0];
122
+ if (!id) fail("feedback", "nudge id required");
123
+ const f = args?.flags || {};
124
+ if (!f.useful && !f.noise) fail("feedback", "--useful or --noise required");
125
+ await http.post(`/api/nudges/${encodeURIComponent(id)}/feedback`, {
126
+ useful: !!f.useful,
127
+ note: f.note || "",
128
+ });
129
+ console.log(f.useful ? "noted: useful" : "noted: not useful");
130
+ }
@@ -34,9 +34,9 @@ export async function cmdObsidianSet(args) {
34
34
  if (args.flags.memory || args.flags["memory-sync"]) body.memory_sync = true;
35
35
 
36
36
  const q = scopeQuery(scope);
37
- await http.post(`/projects/${pid}/integrations/${SLUG}/configure${q}`, body);
37
+ await http.post(`/api/projects/${pid}/integrations/${SLUG}/configure${q}`, body);
38
38
  try {
39
- const r = await http.post(`/projects/${pid}/integrations/${SLUG}/validate${q}`, {});
39
+ const r = await http.post(`/api/projects/${pid}/integrations/${SLUG}/validate${q}`, {});
40
40
  const badge = r.is_vault ? "Obsidian vault" : "folder (no .obsidian)";
41
41
  console.log(`✓ Obsidian connected (${scope}) — ${r.vault_name} · ${r.note_count} notes · ${badge}`);
42
42
  console.log(` ${r.vault_path}`);
@@ -50,7 +50,7 @@ export async function cmdObsidianSet(args) {
50
50
  export async function cmdObsidianStatus(args) {
51
51
  const scope = resolveScope(args.flags);
52
52
  const pid = await resolveProjectId(args?.flags?.project);
53
- const s = await http.get(`/projects/${pid}/integrations/${SLUG}${scopeQuery(scope)}`);
53
+ const s = await http.get(`/api/projects/${pid}/integrations/${SLUG}${scopeQuery(scope)}`);
54
54
  if (!s || s.status === "disconnected") {
55
55
  console.log(`(Obsidian not configured in scope "${scope}")`);
56
56
  return;
@@ -66,7 +66,7 @@ export async function cmdObsidianStatus(args) {
66
66
  export async function cmdObsidianSync(args) {
67
67
  const scope = resolveScope(args.flags);
68
68
  const pid = await resolveProjectId(args?.flags?.project);
69
- const r = await http.post(`/projects/${pid}/integrations/${SLUG}/action/sync_memory${scopeQuery(scope)}`, {});
69
+ const r = await http.post(`/api/projects/${pid}/integrations/${SLUG}/action/sync_memory${scopeQuery(scope)}`, {});
70
70
  console.log(`✓ Synced ${r.count} memory file(s) → vault folder "${r.folder}" (${r.changed} changed)`);
71
71
  for (const n of r.notes || []) console.log(` ${n.changed ? "↑" : "="} ${n.note}`);
72
72
  }
@@ -74,6 +74,6 @@ export async function cmdObsidianSync(args) {
74
74
  export async function cmdObsidianRemove(args) {
75
75
  const scope = resolveScope(args.flags);
76
76
  const pid = await resolveProjectId(args?.flags?.project);
77
- await http.delete(`/projects/${pid}/integrations/${SLUG}${scopeQuery(scope)}`);
77
+ await http.delete(`/api/projects/${pid}/integrations/${SLUG}${scopeQuery(scope)}`);
78
78
  console.log(`Removed Obsidian integration (scope: ${scope})`);
79
79
  }
@@ -27,7 +27,7 @@ function fail(key, msg) {
27
27
 
28
28
  export async function cmdOrgShow(args) {
29
29
  const pid = await resolveProjectId(args?.flags?.project);
30
- const org = await http.get(`/projects/${pid}/organization`);
30
+ const org = await http.get(`/api/projects/${pid}/organization`);
31
31
  if (!org.areas.length && !org.roles.length) {
32
32
  console.log("(no organization structure yet)");
33
33
  return;
@@ -44,7 +44,7 @@ export async function cmdOrgAreaAdd(args) {
44
44
  const name = (args._ || []).slice(1).join(" ").trim();
45
45
  if (!name) return fail("areaAdd", "name required");
46
46
  const pid = await resolveProjectId(args?.flags?.project);
47
- const area = await http.post(`/projects/${pid}/organization/areas`, {
47
+ const area = await http.post(`/api/projects/${pid}/organization/areas`, {
48
48
  name, slug: args.flags?.slug, goal: args.flags?.goal,
49
49
  });
50
50
  console.log(`added area ${area.name} (${area.slug})`);
@@ -54,7 +54,7 @@ export async function cmdOrgAreaRm(args) {
54
54
  const slug = (args._ || [])[1];
55
55
  if (!slug) return fail("areaRm", "slug required");
56
56
  const pid = await resolveProjectId(args?.flags?.project);
57
- await http.delete(`/projects/${pid}/organization/areas/${encodeURIComponent(slug)}`);
57
+ await http.delete(`/api/projects/${pid}/organization/areas/${encodeURIComponent(slug)}`);
58
58
  console.log(`removed area ${slug}`);
59
59
  }
60
60
 
@@ -62,7 +62,7 @@ export async function cmdOrgRoleAdd(args) {
62
62
  const name = (args._ || []).slice(1).join(" ").trim();
63
63
  if (!name) return fail("roleAdd", "name required");
64
64
  const pid = await resolveProjectId(args?.flags?.project);
65
- const role = await http.post(`/projects/${pid}/organization/roles`, {
65
+ const role = await http.post(`/api/projects/${pid}/organization/roles`, {
66
66
  name, slug: args.flags?.slug, area: args.flags?.area, description: args.flags?.desc,
67
67
  });
68
68
  console.log(`added role ${role.name} (${role.slug})${role.area ? ` in ${role.area}` : ""}`);
@@ -72,6 +72,6 @@ export async function cmdOrgRoleRm(args) {
72
72
  const slug = (args._ || [])[1];
73
73
  if (!slug) return fail("roleRm", "slug required");
74
74
  const pid = await resolveProjectId(args?.flags?.project);
75
- await http.delete(`/projects/${pid}/organization/roles/${encodeURIComponent(slug)}`);
75
+ await http.delete(`/api/projects/${pid}/organization/roles/${encodeURIComponent(slug)}`);
76
76
  console.log(`removed role ${slug}`);
77
77
  }
@@ -34,7 +34,7 @@ const fmt = {
34
34
  // pointing at 127.0.0.1 works through the USB bridge. For pure WiFi
35
35
  // pairing, the user should bind APX_HOST=0.0.0.0 and we'll emit the
36
36
  // LAN IP here instead.
37
- function pickHostForQr({ host, port }) {
37
+ function pickHostForQr({ host }) {
38
38
  if (host && host !== "0.0.0.0" && host !== "::" && host !== "127.0.0.1") {
39
39
  return host;
40
40
  }
@@ -74,7 +74,7 @@ async function runPairing(args, channel) {
74
74
  // 1. Ask daemon for a pairing nonce.
75
75
  let init;
76
76
  try {
77
- init = await http.post("/pair/init", {});
77
+ init = await http.post("/api/pair/init", {});
78
78
  } catch (e) {
79
79
  console.error(fmt.red(`pair init failed: ${e.message}`));
80
80
  process.exit(1);
@@ -117,7 +117,7 @@ async function runPairing(args, channel) {
117
117
  while (Date.now() < deadline) {
118
118
  await sleep(1500);
119
119
  try {
120
- const s = await http.get(`/pair/status/${init.pairing_id}`);
120
+ const s = await http.get(`/api/pair/status/${init.pairing_id}`);
121
121
  if (s.status === "confirmed") {
122
122
  console.log(` ${fmt.green("●")} ${fmt.bold("paired")} ${fmt.gray("·")} ${s.device_label || ""}`);
123
123
  console.log(` ${fmt.gray("client_id:")} ${s.client_id}`);
@@ -138,7 +138,7 @@ async function runPairing(args, channel) {
138
138
  }
139
139
 
140
140
  export async function cmdPairList() {
141
- const { clients } = await http.get("/pair/list");
141
+ const { clients } = await http.get("/api/pair/list");
142
142
  if (!clients.length) {
143
143
  console.log(`\n ${fmt.dim("no paired devices")}\n`);
144
144
  return;
@@ -160,12 +160,12 @@ export async function cmdPairRevoke(args = {}) {
160
160
  process.exit(1);
161
161
  }
162
162
  // Allow short prefix: resolve via /pair/list.
163
- const { clients } = await http.get("/pair/list");
163
+ const { clients } = await http.get("/api/pair/list");
164
164
  const match = clients.find((c) => c.id === id || c.id.startsWith(id));
165
165
  if (!match) {
166
166
  console.error(fmt.red(`no paired device matches "${id}"`));
167
167
  process.exit(1);
168
168
  }
169
- await http.delete(`/pair/revoke/${match.id}`);
169
+ await http.delete(`/api/pair/revoke/${match.id}`);
170
170
  console.log(` ${fmt.green("●")} revoked ${match.label} ${fmt.gray(`(${match.id.slice(0, 8)})`)}`);
171
171
  }
@@ -1,7 +1,7 @@
1
1
  import { http } from "../http.js";
2
2
 
3
3
  export async function cmdPluginsList() {
4
- const data = await http.get("/plugins");
4
+ const data = await http.get("/api/plugins");
5
5
  const ids = Object.keys(data);
6
6
  if (ids.length === 0) {
7
7
  console.log("(no plugins loaded)");
@@ -18,6 +18,6 @@ export async function cmdPluginsList() {
18
18
  export async function cmdPluginStatus(args) {
19
19
  const id = args._[0];
20
20
  if (!id) throw new Error("apx plugins status: missing <plugin-id>");
21
- const s = await http.get(`/plugins/${id}/status`);
21
+ const s = await http.get(`/api/plugins/${id}/status`);
22
22
  console.log(JSON.stringify(s, null, 2));
23
23
  }
@@ -73,7 +73,7 @@ function printDoctor(report) {
73
73
  // ── list ────────────────────────────────────────────────────────────────────
74
74
 
75
75
  export async function cmdProfileList() {
76
- const { active, profiles } = await http.get("/profiles");
76
+ const { active, profiles } = await http.get("/api/profiles");
77
77
  if (!profiles.length) {
78
78
  console.log("(no profiles available)");
79
79
  return;
@@ -94,7 +94,7 @@ export async function cmdProfileShow(args) {
94
94
  const id = args._[0];
95
95
  if (!id) fail("show", "missing <id>");
96
96
 
97
- const p = await http.get(`/profiles/${encodeURIComponent(id)}`);
97
+ const p = await http.get(`/api/profiles/${encodeURIComponent(id)}`);
98
98
  console.log(`${p.name} (${p.id}) v${p.version || "?"} — ${p.source}${p.active ? " — ACTIVE" : ""}`);
99
99
  if (p.description) console.log(p.description);
100
100
  console.log(`languages: ${p.languages.join(", ") || "en"}`);
@@ -119,7 +119,7 @@ export async function cmdProfileInstall(args) {
119
119
  const source = args._[0];
120
120
  if (!source) fail("install", "missing <id|path>");
121
121
 
122
- const r = await http.post("/profiles/install", { source, force: !!args?.flags?.force });
122
+ const r = await http.post("/api/profiles/install", { source, force: !!args?.flags?.force });
123
123
  console.log(`installed ${r.profile.name} (${r.profile.id}) v${r.profile.version || "?"}`);
124
124
  console.log(` prompt: ~${r.tokens} tokens`);
125
125
  printWarnings(r.warnings);
@@ -133,7 +133,7 @@ export async function cmdProfileUse(args) {
133
133
  const id = args._[0];
134
134
  if (!id) fail("use", "missing <id>");
135
135
 
136
- const r = await http.post("/profiles/use", { id, force: !!args?.flags?.force });
136
+ const r = await http.post("/api/profiles/use", { id, force: !!args?.flags?.force });
137
137
  console.log(`active profile: ${r.profile.name} (${r.profile.id})`);
138
138
  printWarnings(r.warnings);
139
139
 
@@ -146,7 +146,7 @@ export async function cmdProfileUse(args) {
146
146
  }
147
147
 
148
148
  export async function cmdProfileOff() {
149
- const r = await http.post("/profiles/off", {});
149
+ const r = await http.post("/api/profiles/off", {});
150
150
  if (!r.was) {
151
151
  console.log("no profile was active — nothing to do");
152
152
  return;
@@ -185,14 +185,14 @@ async function interactiveConfig(profile) {
185
185
  }
186
186
 
187
187
  export async function cmdProfileConfig(args) {
188
- const { active } = await http.get("/profiles");
188
+ const { active } = await http.get("/api/profiles");
189
189
  const id = args?.flags?.profile || active;
190
190
  if (!id) {
191
191
  console.error("apx profile config: no profile is active — run: apx profile use <id>");
192
192
  process.exit(1);
193
193
  }
194
194
 
195
- const profile = await http.get(`/profiles/${encodeURIComponent(id)}?preview=0`);
195
+ const profile = await http.get(`/api/profiles/${encodeURIComponent(id)}?preview=0`);
196
196
 
197
197
  let values = parseSetFlags(args?.flags);
198
198
  if (args?.flags?.interactive) {
@@ -217,7 +217,7 @@ export async function cmdProfileConfig(args) {
217
217
  return;
218
218
  }
219
219
 
220
- const r = await http.patch("/profiles/config", { values, id });
220
+ const r = await http.patch("/api/profiles/config", { values, id });
221
221
  console.log(`updated: ${r.changed.join(", ")}`);
222
222
  for (const k of r.changed) console.log(` ${k.padEnd(24)} ${r.config[k]}`);
223
223
 
@@ -233,14 +233,14 @@ export async function cmdProfileConfig(args) {
233
233
  export async function cmdProfileDoctor(args) {
234
234
  const id = args._[0];
235
235
  const q = id ? `?id=${encodeURIComponent(id)}` : "";
236
- printDoctor(await http.get(`/profiles/doctor${q}`));
236
+ printDoctor(await http.get(`/api/profiles/doctor${q}`));
237
237
  }
238
238
 
239
239
  export async function cmdProfileUninstall(args) {
240
240
  const id = args._[0];
241
241
  if (!id) fail("uninstall", "missing <id>");
242
242
 
243
- const r = await http.delete(`/profiles/${encodeURIComponent(id)}`);
243
+ const r = await http.delete(`/api/profiles/${encodeURIComponent(id)}`);
244
244
  console.log(`uninstalled "${r.id}" (${r.source})`);
245
245
  if (r.routines?.removed?.length) console.log(` routines removed: ${r.routines.removed.join(", ")}`);
246
246
  if (r.routines?.kept?.length) {
@@ -18,7 +18,7 @@ import { resolveProjectId } from "./project.js";
18
18
 
19
19
  async function reloadDaemon() {
20
20
  try {
21
- await http.post("/admin/reload", {});
21
+ await http.post("/api/admin/reload", {});
22
22
  } catch (e) {
23
23
  console.log(`⚠️ reload failed: ${e.message} (changes saved, restart daemon to apply)`);
24
24
  }
@@ -65,7 +65,7 @@ async function projectIdFromArg(target) {
65
65
  export async function cmdProjectConfigShow(args) {
66
66
  const target = args._[0];
67
67
  const id = await projectIdFromArg(target);
68
- const data = await http.get(`/projects/${id}/config`);
68
+ const data = await http.get(`/api/projects/${id}/config`);
69
69
  const key = args.flags.key;
70
70
  if (key) {
71
71
  const eff = readDotted(data.effective || {}, key);
@@ -89,7 +89,7 @@ export async function cmdProjectConfigSet(args) {
89
89
  if (raw === undefined) throw new Error("apx project config set: missing <value>");
90
90
  const id = await projectIdFromArg(target);
91
91
  const value = coerceValue(raw);
92
- await http.patch(`/projects/${id}/config`, { set: { [dotted]: value } });
92
+ await http.patch(`/api/projects/${id}/config`, { set: { [dotted]: value } });
93
93
  await reloadDaemon();
94
94
  console.log(`✅ set ${dotted} = ${JSON.stringify(value)}`);
95
95
  }
@@ -99,7 +99,7 @@ export async function cmdProjectConfigUnset(args) {
99
99
  const dotted = args._[1];
100
100
  if (!dotted) throw new Error("apx project config unset: missing <dotted.key>");
101
101
  const id = await projectIdFromArg(target);
102
- await http.patch(`/projects/${id}/config`, { unset: [dotted] });
102
+ await http.patch(`/api/projects/${id}/config`, { unset: [dotted] });
103
103
  await reloadDaemon();
104
104
  console.log(`✅ unset ${dotted}`);
105
105
  }
@@ -107,7 +107,7 @@ export async function cmdProjectConfigUnset(args) {
107
107
  export async function cmdProjectConfigEdit(args) {
108
108
  const target = args._[0];
109
109
  const id = await projectIdFromArg(target);
110
- const data = await http.get(`/projects/${id}/config`);
110
+ const data = await http.get(`/api/projects/${id}/config`);
111
111
  const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "apx-cfg-"));
112
112
  const tmpFile = path.join(tmpDir, "config.json");
113
113
  fs.writeFileSync(tmpFile, JSON.stringify(data.project_only || {}, null, 2) + "\n");
@@ -125,7 +125,7 @@ export async function cmdProjectConfigEdit(args) {
125
125
  throw new Error(`invalid JSON after edit: ${e.message}`);
126
126
  }
127
127
  fs.rmSync(tmpDir, { recursive: true, force: true });
128
- await http.put(`/projects/${id}/config`, updated);
128
+ await http.put(`/api/projects/${id}/config`, updated);
129
129
  await reloadDaemon();
130
130
  console.log(`✅ saved project_only config for #${id}`);
131
131
  }
@@ -12,12 +12,12 @@ function requireRoot() {
12
12
 
13
13
  export async function cmdProjectAdd(args) {
14
14
  const target = args._[0] || requireRoot();
15
- const result = await http.post("/projects", { path: path.resolve(target) });
15
+ const result = await http.post("/api/projects", { path: path.resolve(target) });
16
16
  console.log(`Registered #${result.id}: ${result.path}`);
17
17
  }
18
18
 
19
19
  export async function cmdProjectList() {
20
- const projects = await http.get("/projects");
20
+ const projects = await http.get("/api/projects");
21
21
  if (projects.length === 0) {
22
22
  console.log("(no projects registered — try `apx project add .`)");
23
23
  return;
@@ -31,7 +31,7 @@ export async function cmdProjectList() {
31
31
  export async function cmdProjectRemove(args) {
32
32
  const target = args._[0];
33
33
  if (!target) throw new Error("apx project remove: missing <path|id>");
34
- const projects = await http.get("/projects");
34
+ const projects = await http.get("/api/projects");
35
35
  let id;
36
36
  if (/^\d+$/.test(target)) id = parseInt(target, 10);
37
37
  else {
@@ -40,7 +40,7 @@ export async function cmdProjectRemove(args) {
40
40
  if (!found) throw new Error(`not registered: ${target}`);
41
41
  id = found.id;
42
42
  }
43
- await http.delete(`/projects/${id}`);
43
+ await http.delete(`/api/projects/${id}`);
44
44
  console.log(`Removed project #${id}`);
45
45
  }
46
46
 
@@ -51,19 +51,19 @@ export async function cmdProjectRebuild(args) {
51
51
  if (/^\d+$/.test(target)) id = parseInt(target, 10);
52
52
  else {
53
53
  const abs = path.resolve(target);
54
- const projects = await http.get("/projects");
54
+ const projects = await http.get("/api/projects");
55
55
  const found = projects.find((p) => p.path === abs);
56
56
  if (!found) throw new Error(`not registered: ${target}`);
57
57
  id = found.id;
58
58
  }
59
59
  } else {
60
60
  const root = requireRoot();
61
- const projects = await http.get("/projects");
61
+ const projects = await http.get("/api/projects");
62
62
  const found = projects.find((p) => p.path === root);
63
63
  if (!found) throw new Error(`current project not registered — run \`apx project add .\``);
64
64
  id = found.id;
65
65
  }
66
- const result = await http.post(`/projects/${id}/rebuild`);
66
+ const result = await http.post(`/api/projects/${id}/rebuild`);
67
67
  console.log(`Rebuilt project #${id}: ${result.agents} agents`);
68
68
  }
69
69
 
@@ -78,7 +78,7 @@ export async function resolveProjectId(target) {
78
78
  if (typeof target === "number" || /^\d+$/.test(String(target))) {
79
79
  return parseInt(target, 10);
80
80
  }
81
- const projects = await http.get("/projects");
81
+ const projects = await http.get("/api/projects");
82
82
  const tgt = String(target);
83
83
 
84
84
  // exact path
@@ -112,10 +112,10 @@ export async function resolveProjectId(target) {
112
112
  // Fall back to the default project (id=0) — always available, no .apc/ required.
113
113
  return 0;
114
114
  }
115
- const projects = await http.get("/projects");
115
+ const projects = await http.get("/api/projects");
116
116
  const found = projects.find((p) => p.path === root);
117
117
  if (found) return found.id;
118
118
  // auto-register
119
- const result = await http.post("/projects", { path: root });
119
+ const result = await http.post("/api/projects", { path: root });
120
120
  return result.id;
121
121
  }