@agentprojectcontext/apx 1.77.2 → 1.78.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 (294) 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 +13 -48
  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/tools/handlers/call-runtime.js +4 -4
  15. package/src/core/agent/tools/handlers/search-sessions.js +1 -1
  16. package/src/core/agent/tools/handlers/set-permission-mode.js +11 -4
  17. package/src/core/agent/tools/names.js +58 -0
  18. package/src/core/apc/context-copy.js +1 -1
  19. package/src/core/apc/frontmatter.js +85 -0
  20. package/src/core/apc/parser.js +9 -21
  21. package/src/core/apc/paths.js +8 -8
  22. package/src/core/apc/scaffold.js +5 -4
  23. package/src/core/channels/telegram/config.js +201 -0
  24. package/src/core/config/index.js +25 -183
  25. package/src/core/config/paths.js +54 -1
  26. package/src/core/confirmation/adapters/web.js +1 -1
  27. package/src/core/deck/manifest.js +12 -12
  28. package/src/core/desktop/autostart.js +3 -2
  29. package/src/core/desktop/process.js +4 -4
  30. package/src/core/engines/presets.js +2 -2
  31. package/src/core/http-tools/browser.js +1 -1
  32. package/src/core/http-tools/catalog.js +551 -0
  33. package/src/core/http-tools/fetch.js +1 -1
  34. package/src/core/http-tools/glob.js +3 -3
  35. package/src/core/http-tools/grep.js +2 -9
  36. package/src/core/http-tools/inline-handlers.js +59 -0
  37. package/src/core/http-tools/registry.js +31 -615
  38. package/src/core/http-tools/search.js +2 -2
  39. package/src/core/identity/self.js +6 -7
  40. package/src/core/identity/telegram.js +3 -3
  41. package/src/core/logging.js +6 -5
  42. package/src/core/mcp/sources.js +12 -16
  43. package/src/core/memory/indexer.js +2 -5
  44. package/src/core/profiles/lifecycle.js +0 -2
  45. package/src/core/profiles/store.js +2 -7
  46. package/src/core/routines/runner.js +1 -1
  47. package/src/core/runtime-skills/apx-agency-agents/SKILL.md +2 -2
  48. package/src/core/runtime-skills/apx-profile/SKILL.md +3 -3
  49. package/src/core/runtime-skills/apx-project/SKILL.md +1 -1
  50. package/src/core/runtime-skills/apx-task/SKILL.md +8 -8
  51. package/src/core/runtime-skills/apx-telegram/SKILL.md +4 -4
  52. package/src/core/runtime-skills/apx-voice/SKILL.md +4 -4
  53. package/src/core/runtimes/detect.js +2 -2
  54. package/src/core/sessions/index.js +800 -0
  55. package/src/core/stores/code-sessions.js +3 -14
  56. package/src/core/stores/engine-sessions.js +0 -4
  57. package/src/core/stores/messages.js +0 -5
  58. package/src/core/stores/organization.js +9 -11
  59. package/src/core/stores/routines.js +6 -11
  60. package/src/core/stores/runtime-callbacks.js +2 -1
  61. package/src/core/util/json-file.js +128 -0
  62. package/src/core/vars/sources.js +14 -21
  63. package/src/core/voice/stt-models.js +1 -1
  64. package/src/core/voice/tts.js +5 -4
  65. package/src/host/daemon/api/admin-config.js +5 -5
  66. package/src/host/daemon/api/admin.js +8 -7
  67. package/src/host/daemon/api/agents.js +16 -16
  68. package/src/host/daemon/api/artifact-preview.js +8 -8
  69. package/src/host/daemon/api/artifacts.js +7 -7
  70. package/src/host/daemon/api/code.js +8 -8
  71. package/src/host/daemon/api/config.js +6 -6
  72. package/src/host/daemon/api/confirm.js +2 -2
  73. package/src/host/daemon/api/connections.js +2 -2
  74. package/src/host/daemon/api/conversations.js +12 -12
  75. package/src/host/daemon/api/deck.js +6 -6
  76. package/src/host/daemon/api/desktop.js +8 -8
  77. package/src/host/daemon/api/embeddings.js +4 -4
  78. package/src/host/daemon/api/engines.js +8 -7
  79. package/src/host/daemon/api/exec.js +5 -4
  80. package/src/host/daemon/api/files-project.js +6 -6
  81. package/src/host/daemon/api/health.js +2 -2
  82. package/src/host/daemon/api/identity.js +3 -3
  83. package/src/host/daemon/api/inbox.js +2 -2
  84. package/src/host/daemon/api/integrations.js +23 -19
  85. package/src/host/daemon/api/mcps.js +16 -12
  86. package/src/host/daemon/api/messages.js +5 -5
  87. package/src/host/daemon/api/organization.js +8 -8
  88. package/src/host/daemon/api/pairing.js +10 -7
  89. package/src/host/daemon/api/plugins.js +3 -3
  90. package/src/host/daemon/api/prefix.js +20 -0
  91. package/src/host/daemon/api/profiles.js +9 -9
  92. package/src/host/daemon/api/projects.js +5 -5
  93. package/src/host/daemon/api/routines.js +8 -8
  94. package/src/host/daemon/api/run.js +2 -2
  95. package/src/host/daemon/api/runtimes.js +6 -6
  96. package/src/host/daemon/api/sessions-search.js +18 -11
  97. package/src/host/daemon/api/sessions.js +6 -6
  98. package/src/host/daemon/api/shared.js +59 -13
  99. package/src/host/daemon/api/skills.js +12 -12
  100. package/src/host/daemon/api/super-agent.js +4 -4
  101. package/src/host/daemon/api/tasks.js +11 -11
  102. package/src/host/daemon/api/telegram.js +19 -20
  103. package/src/host/daemon/api/tools.js +7 -7
  104. package/src/host/daemon/api/top-level.js +7 -7
  105. package/src/host/daemon/api/transcribe.js +6 -6
  106. package/src/host/daemon/api/tts.js +3 -3
  107. package/src/host/daemon/api/vars.js +11 -8
  108. package/src/host/daemon/api/voice.js +6 -6
  109. package/src/host/daemon/api/web.js +28 -32
  110. package/src/host/daemon/api.js +77 -48
  111. package/src/host/daemon/db.js +1 -1
  112. package/src/host/daemon/desktop-ws.js +7 -3
  113. package/src/host/daemon/index.js +11 -5
  114. package/src/host/daemon/plugins/desktop/index.js +1 -1
  115. package/src/host/daemon/plugins/telegram/index.js +1 -1
  116. package/src/host/daemon/stt-venv.js +20 -81
  117. package/src/host/daemon/wakeup.js +1 -1
  118. package/src/interfaces/acp/index.js +3 -3
  119. package/src/interfaces/acp/session.js +2 -2
  120. package/src/interfaces/cli/commands/a2a.js +2 -2
  121. package/src/interfaces/cli/commands/agent.js +3 -3
  122. package/src/interfaces/cli/commands/artifact.js +13 -13
  123. package/src/interfaces/cli/commands/chat.js +3 -3
  124. package/src/interfaces/cli/commands/command.js +2 -2
  125. package/src/interfaces/cli/commands/config.js +4 -4
  126. package/src/interfaces/cli/commands/daemon.js +17 -18
  127. package/src/interfaces/cli/commands/desktop.js +7 -14
  128. package/src/interfaces/cli/commands/exec.js +2 -2
  129. package/src/interfaces/cli/commands/log.js +3 -4
  130. package/src/interfaces/cli/commands/mcp.js +9 -9
  131. package/src/interfaces/cli/commands/memory.js +2 -2
  132. package/src/interfaces/cli/commands/messages.js +5 -5
  133. package/src/interfaces/cli/commands/model.js +0 -18
  134. package/src/interfaces/cli/commands/obsidian.js +5 -5
  135. package/src/interfaces/cli/commands/org.js +5 -5
  136. package/src/interfaces/cli/commands/pair.js +6 -6
  137. package/src/interfaces/cli/commands/plugins.js +2 -2
  138. package/src/interfaces/cli/commands/profile.js +10 -10
  139. package/src/interfaces/cli/commands/project-config.js +6 -6
  140. package/src/interfaces/cli/commands/project.js +10 -10
  141. package/src/interfaces/cli/commands/routine.js +8 -9
  142. package/src/interfaces/cli/commands/runtime.js +2 -2
  143. package/src/interfaces/cli/commands/search.js +0 -1
  144. package/src/interfaces/cli/commands/session.js +12 -40
  145. package/src/interfaces/cli/commands/sessions.js +21 -798
  146. package/src/interfaces/cli/commands/setup.js +16 -6
  147. package/src/interfaces/cli/commands/skills.js +1 -2
  148. package/src/interfaces/cli/commands/status.js +3 -3
  149. package/src/interfaces/cli/commands/task.js +8 -8
  150. package/src/interfaces/cli/commands/telegram.js +21 -21
  151. package/src/interfaces/cli/commands/voice.js +6 -6
  152. package/src/interfaces/cli/help/index.js +2245 -0
  153. package/src/interfaces/cli/http.js +9 -4
  154. package/src/interfaces/cli/index.js +14 -2857
  155. package/src/interfaces/cli/routes/acp.js +13 -0
  156. package/src/interfaces/cli/routes/agent.js +27 -0
  157. package/src/interfaces/cli/routes/artifact.js +28 -0
  158. package/src/interfaces/cli/routes/chat.js +11 -0
  159. package/src/interfaces/cli/routes/code.js +11 -0
  160. package/src/interfaces/cli/routes/command.js +21 -0
  161. package/src/interfaces/cli/routes/config.js +16 -0
  162. package/src/interfaces/cli/routes/connections.js +11 -0
  163. package/src/interfaces/cli/routes/conversations.js +21 -0
  164. package/src/interfaces/cli/routes/daemon.js +19 -0
  165. package/src/interfaces/cli/routes/desktop.js +20 -0
  166. package/src/interfaces/cli/routes/env.js +13 -0
  167. package/src/interfaces/cli/routes/exec.js +11 -0
  168. package/src/interfaces/cli/routes/identity.js +11 -0
  169. package/src/interfaces/cli/routes/index.js +71 -0
  170. package/src/interfaces/cli/routes/init.js +11 -0
  171. package/src/interfaces/cli/routes/log.js +20 -0
  172. package/src/interfaces/cli/routes/mcp.js +22 -0
  173. package/src/interfaces/cli/routes/memory.js +11 -0
  174. package/src/interfaces/cli/routes/messages.js +16 -0
  175. package/src/interfaces/cli/routes/model.js +11 -0
  176. package/src/interfaces/cli/routes/obsidian.js +17 -0
  177. package/src/interfaces/cli/routes/org.js +34 -0
  178. package/src/interfaces/cli/routes/overlay.js +10 -0
  179. package/src/interfaces/cli/routes/pair.js +17 -0
  180. package/src/interfaces/cli/routes/panel.js +16 -0
  181. package/src/interfaces/cli/routes/permission.js +11 -0
  182. package/src/interfaces/cli/routes/plugins.js +21 -0
  183. package/src/interfaces/cli/routes/profile.js +27 -0
  184. package/src/interfaces/cli/routes/project.js +41 -0
  185. package/src/interfaces/cli/routes/restart.js +15 -0
  186. package/src/interfaces/cli/routes/routine.js +28 -0
  187. package/src/interfaces/cli/routes/run.js +11 -0
  188. package/src/interfaces/cli/routes/search.js +11 -0
  189. package/src/interfaces/cli/routes/send.js +11 -0
  190. package/src/interfaces/cli/routes/session.js +26 -0
  191. package/src/interfaces/cli/routes/sessions.js +15 -0
  192. package/src/interfaces/cli/routes/setup.js +18 -0
  193. package/src/interfaces/cli/routes/skills.js +20 -0
  194. package/src/interfaces/cli/routes/status.js +12 -0
  195. package/src/interfaces/cli/routes/task.js +26 -0
  196. package/src/interfaces/cli/routes/telegram.js +39 -0
  197. package/src/interfaces/cli/routes/update.js +24 -0
  198. package/src/interfaces/cli/routes/voice.js +17 -0
  199. package/src/interfaces/desktop/main.js +6 -7
  200. package/src/interfaces/desktop/renderer.js +0 -5
  201. package/src/interfaces/mcp-server/index.js +15 -14
  202. package/src/interfaces/tui/_shims/globals.d.ts +8 -0
  203. package/src/interfaces/tui/tsconfig.json +4 -1
  204. package/src/interfaces/web/README.md +6 -6
  205. package/src/interfaces/web/dist/assets/index-CBR_-QyA.js +824 -0
  206. package/src/interfaces/web/dist/assets/index-CBR_-QyA.js.map +1 -0
  207. package/src/interfaces/web/dist/index.html +1 -1
  208. package/src/interfaces/web/src/components/AddProjectDialog.tsx +1 -1
  209. package/src/interfaces/web/src/components/agents/AgentFormFields.tsx +1 -1
  210. package/src/interfaces/web/src/components/chat/ChatList.tsx +2 -2
  211. package/src/interfaces/web/src/components/chat/SkillPicker.tsx +1 -1
  212. package/src/interfaces/web/src/components/code/CodeFileTree.tsx +1 -1
  213. package/src/interfaces/web/src/components/code/CodeTerminal.tsx +1 -1
  214. package/src/interfaces/web/src/components/desktop/DesktopStatusCard.tsx +1 -1
  215. package/src/interfaces/web/src/components/files/FileBrowser.tsx +2 -2
  216. package/src/interfaces/web/src/components/memory/MemoryBrowser.tsx +2 -2
  217. package/src/interfaces/web/src/components/routines/ExecutionsList.tsx +1 -1
  218. package/src/interfaces/web/src/components/routines/RoutineEditor.tsx +2 -2
  219. package/src/interfaces/web/src/components/settings/DesktopSettingsPanel.tsx +1 -1
  220. package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +1 -1
  221. package/src/interfaces/web/src/components/settings/SkillsInspectorPanel.tsx +1 -1
  222. package/src/interfaces/web/src/components/settings/SkillsManager.tsx +2 -2
  223. package/src/interfaces/web/src/components/tasks/TaskDetailPanel.tsx +1 -1
  224. package/src/interfaces/web/src/hooks/useDaemonStatus.ts +1 -1
  225. package/src/interfaces/web/src/hooks/useDevices.ts +1 -1
  226. package/src/interfaces/web/src/hooks/useEngines.ts +1 -1
  227. package/src/interfaces/web/src/hooks/useGlobalConfig.ts +2 -2
  228. package/src/interfaces/web/src/hooks/useIdentity.ts +1 -1
  229. package/src/interfaces/web/src/hooks/useInbox.ts +1 -1
  230. package/src/interfaces/web/src/hooks/useProfiles.ts +3 -3
  231. package/src/interfaces/web/src/hooks/useProjects.ts +1 -1
  232. package/src/interfaces/web/src/hooks/useTelegram.ts +3 -3
  233. package/src/interfaces/web/src/hooks/useTokenBootstrap.ts +30 -7
  234. package/src/interfaces/web/src/lib/api/admin.ts +11 -11
  235. package/src/interfaces/web/src/lib/api/agents.ts +14 -14
  236. package/src/interfaces/web/src/lib/api/artifacts.ts +11 -11
  237. package/src/interfaces/web/src/lib/api/code.ts +1 -1
  238. package/src/interfaces/web/src/lib/api/conversations.ts +8 -8
  239. package/src/interfaces/web/src/lib/api/deck.ts +3 -3
  240. package/src/interfaces/web/src/lib/api/desktop.ts +8 -8
  241. package/src/interfaces/web/src/lib/api/embeddings.ts +3 -3
  242. package/src/interfaces/web/src/lib/api/engines.ts +3 -3
  243. package/src/interfaces/web/src/lib/api/filesystem.ts +2 -2
  244. package/src/interfaces/web/src/lib/api/health.ts +1 -1
  245. package/src/interfaces/web/src/lib/api/identity.ts +2 -2
  246. package/src/interfaces/web/src/lib/api/inbox.ts +1 -1
  247. package/src/interfaces/web/src/lib/api/integrations.ts +8 -8
  248. package/src/interfaces/web/src/lib/api/mcps.ts +6 -6
  249. package/src/interfaces/web/src/lib/api/messages.ts +3 -3
  250. package/src/interfaces/web/src/lib/api/organization.ts +7 -7
  251. package/src/interfaces/web/src/lib/api/profiles.ts +8 -8
  252. package/src/interfaces/web/src/lib/api/projectFiles.ts +5 -5
  253. package/src/interfaces/web/src/lib/api/projects.ts +12 -12
  254. package/src/interfaces/web/src/lib/api/routines.ts +7 -7
  255. package/src/interfaces/web/src/lib/api/sessions.ts +2 -2
  256. package/src/interfaces/web/src/lib/api/skills.ts +11 -11
  257. package/src/interfaces/web/src/lib/api/super_agent.ts +3 -3
  258. package/src/interfaces/web/src/lib/api/tasks.ts +12 -12
  259. package/src/interfaces/web/src/lib/api/telegram.ts +14 -14
  260. package/src/interfaces/web/src/lib/api/tools.ts +1 -1
  261. package/src/interfaces/web/src/lib/api/vars.ts +4 -4
  262. package/src/interfaces/web/src/lib/api/voice.ts +6 -6
  263. package/src/interfaces/web/src/screens/base/AgentDefaultsTab.tsx +1 -1
  264. package/src/interfaces/web/src/screens/base/GlobalTasksTab.tsx +1 -1
  265. package/src/interfaces/web/src/screens/base/LogsTab.tsx +3 -3
  266. package/src/interfaces/web/src/screens/base/SessionsTab.tsx +1 -1
  267. package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +1 -1
  268. package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +1 -1
  269. package/src/interfaces/web/src/screens/modules/DesktopScreen.tsx +1 -1
  270. package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +1 -1
  271. package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +8 -8
  272. package/src/interfaces/web/src/screens/project/AgentsTab.tsx +2 -2
  273. package/src/interfaces/web/src/screens/project/ChatTab.tsx +3 -3
  274. package/src/interfaces/web/src/screens/project/ConfigTab.tsx +1 -1
  275. package/src/interfaces/web/src/screens/project/McpsTab.tsx +3 -3
  276. package/src/interfaces/web/src/screens/project/Overview.tsx +6 -6
  277. package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +2 -2
  278. package/src/interfaces/web/src/screens/project/StructureTab.tsx +1 -1
  279. package/src/interfaces/web/src/screens/project/TasksTab.tsx +1 -1
  280. package/src/interfaces/web/src/screens/project/VarsTab.tsx +1 -1
  281. package/src/interfaces/web/vite.config.ts +13 -18
  282. package/src/interfaces/web/dist/assets/index-BWWpTTSd.js +0 -824
  283. package/src/interfaces/web/dist/assets/index-BWWpTTSd.js.map +0 -1
  284. package/src/skills/apc-context/SKILL.md +0 -159
  285. /package/src/{host/daemon → core}/runtimes/_spawn.js +0 -0
  286. /package/src/{host/daemon → core}/runtimes/aider.js +0 -0
  287. /package/src/{host/daemon → core}/runtimes/antigravity.js +0 -0
  288. /package/src/{host/daemon → core}/runtimes/claude-code.js +0 -0
  289. /package/src/{host/daemon → core}/runtimes/codex.js +0 -0
  290. /package/src/{host/daemon → core}/runtimes/cursor-agent.js +0 -0
  291. /package/src/{host/daemon → core}/runtimes/gemini-cli.js +0 -0
  292. /package/src/{host/daemon → core}/runtimes/index.js +0 -0
  293. /package/src/{host/daemon → core}/runtimes/opencode.js +0 -0
  294. /package/src/{host/daemon → core}/runtimes/qwen-code.js +0 -0
@@ -3,7 +3,7 @@
3
3
  // 2. Brave Search API (requires BRAVE_API_KEY env)
4
4
  // 3. Puppeteer Google fallback (requires puppeteer installed)
5
5
  //
6
- // Endpoint: POST /tools/search
6
+ // Endpoint: POST /api/tools/search
7
7
  // Body: { query, mode: "auto"|"ddg"|"brave"|"browser", limit? }
8
8
 
9
9
  import { browser_navigate, browser_get_text, browser_evaluate } from "./browser.js";
@@ -302,7 +302,7 @@ export function buildSearchRouter(express) {
302
302
  }
303
303
  });
304
304
 
305
- // GET convenience: /tools/search?q=...&mode=auto&limit=5
305
+ // GET convenience: /api/tools/search?q=...&mode=auto&limit=5
306
306
  router.get("/", async (req, res) => {
307
307
  const { q, query, mode, limit } = req.query;
308
308
  try {
@@ -1,23 +1,22 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import os from "node:os";
3
+ import { IDENTITY_PATH } from "../config/paths.js";
4
+
5
+ export { IDENTITY_PATH };
4
6
  import { SUPERAGENT_ACTOR_ID } from "../constants/actors.js";
7
+ import { readJson } from "#core/util/json-file.js";
5
8
 
6
9
  // Re-export so callers that already imported the actor id from here keep
7
10
  // working. The single source of truth lives in core/constants/actors.js.
8
11
  export { SUPERAGENT_ACTOR_ID };
9
12
 
10
- export const IDENTITY_PATH = path.join(os.homedir(), ".apx", "identity.json");
13
+
11
14
 
12
15
  // Shown when no persona is configured yet. Brand of the app, not a persona.
13
16
  export const SUPERAGENT_DISPLAY_FALLBACK = "APX";
14
17
 
15
18
  export function readIdentity() {
16
- try {
17
- return JSON.parse(fs.readFileSync(IDENTITY_PATH, "utf8"));
18
- } catch {
19
- return null;
20
- }
19
+ return readJson(IDENTITY_PATH, null);
21
20
  }
22
21
 
23
22
  // Resolve the super-agent's DISPLAY name (the persona shown to users). Order:
@@ -37,7 +37,7 @@ export function resolveSender({ cfg, channelName, from, chatType }) {
37
37
  const isOwner =
38
38
  channel?.owner_user_id != null &&
39
39
  String(channel.owner_user_id) === String(userId);
40
- const role = isOwner ? "owner" : contact?.role || "guest";
40
+ const role = isOwner ? SENDER_ROLES.OWNER : contact?.role || SENDER_ROLES.GUEST;
41
41
  return {
42
42
  userId,
43
43
  username,
@@ -115,11 +115,11 @@ export function registerSender({ cfg, channelName, from, chatType }) {
115
115
  if (kind === "claim") {
116
116
  upsertTelegramChannel(disk, channelName, { owner_user_id: userId });
117
117
  upsertContact(disk, userId, {
118
- name, username, role: "owner", first_seen: now, last_seen: now,
118
+ name, username, role: SENDER_ROLES.OWNER, first_seen: now, last_seen: now,
119
119
  });
120
120
  } else if (kind === "guest") {
121
121
  upsertContact(disk, userId, {
122
- name, username, role: "guest", first_seen: now, last_seen: now,
122
+ name, username, role: SENDER_ROLES.GUEST, first_seen: now, last_seen: now,
123
123
  });
124
124
  } else {
125
125
  upsertContact(disk, userId, { last_seen: now });
@@ -1,14 +1,15 @@
1
1
  import fs from "node:fs";
2
- import path from "node:path";
3
- import { APX_HOME } from "./config/index.js";
4
2
  import { maskSecretValues } from "./config/secret-values.js";
3
+ import { LOG_DIR, APX_LOG_PATH, ERROR_TRACE_PATH } from "./config/paths.js";
4
+
5
+ // Canonical definitions live in config/paths.js; re-exported so the existing
6
+ // `import { APX_LOG_PATH } from "#core/logging.js"` call sites keep working.
7
+ export { LOG_DIR, APX_LOG_PATH, ERROR_TRACE_PATH };
5
8
 
6
- export const LOG_DIR = path.join(APX_HOME, "logs");
7
- export const ERROR_TRACE_PATH = path.join(LOG_DIR, "errors.jsonl");
8
9
  // Unified daemon log. Every module (daemon, telegram, whisper, super-agent,
9
10
  // tools, desktop) writes here with one consistent format so the user can
10
11
  // follow the whole system from a single tail.
11
- export const APX_LOG_PATH = path.join(LOG_DIR, "apx.log");
12
+
12
13
 
13
14
  const SECRET_KEY_RE = /(token|secret|password|api[_-]?key|authorization|bot[_-]?token)/i;
14
15
 
@@ -34,12 +34,14 @@
34
34
  // instead, then to true.
35
35
 
36
36
  import fs from "node:fs";
37
- import os from "node:os";
38
37
  import path from "node:path";
38
+ import { apxHome } from "#core/config/paths.js";
39
39
  import { apcMcpsFile } from "#core/apc/paths.js";
40
+ import { readJson } from "#core/util/json-file.js";
40
41
 
41
- const APX_HOME = path.join(os.homedir(), ".apx");
42
- const GLOBAL_MCPS_FILE = path.join(APX_HOME, "mcps.json");
42
+
43
+ // Resolved per call: the global store must follow APX_HOME if it moves.
44
+ const globalMcpsFile = () => path.join(apxHome(), "mcps.json");
43
45
  const RUNTIME_MCPS_FILENAME = "mcps.json";
44
46
 
45
47
  // Project-relative sources (file path resolved against projectRoot).
@@ -63,15 +65,9 @@ export const SOURCES = [
63
65
  { id: "global", file: "~/.apx/mcps.json", key: "mcpServers", scope: "global" },
64
66
  ];
65
67
 
66
- function readJsonSafe(absPath) {
67
- if (!absPath) return null;
68
- if (!fs.existsSync(absPath)) return null;
69
- try {
70
- return JSON.parse(fs.readFileSync(absPath, "utf8"));
71
- } catch {
72
- return null;
73
- }
74
- }
68
+ // readJsonSafe is the shared readJson(); secrets are written with SECRET_MODE.
69
+ const readJsonSafe = (absPath) => readJson(absPath, null);
70
+
75
71
 
76
72
  // Resolve the runtime mcps.json path for a given project. `storagePath` is the
77
73
  // project's ~/.apx/projects/<apxId>/ directory.
@@ -81,7 +77,7 @@ export function runtimeMcpsPath(storagePath) {
81
77
  }
82
78
 
83
79
  export function globalMcpsPath() {
84
- return GLOBAL_MCPS_FILE;
80
+ return globalMcpsFile();
85
81
  }
86
82
 
87
83
  // Aggregate all MCP sources for a project, in priority order.
@@ -119,7 +115,7 @@ export function loadAll(projectRoot, opts = {}) {
119
115
  // last. global
120
116
  pipeline.push({
121
117
  id: "global",
122
- abs: GLOBAL_MCPS_FILE,
118
+ abs: globalMcpsFile(),
123
119
  key: "mcpServers",
124
120
  });
125
121
 
@@ -229,7 +225,7 @@ export function writeRuntimeMcps(storagePath, json) {
229
225
  // ---------------------------------------------------------------------------
230
226
 
231
227
  export function readGlobalMcps() {
232
- const p = GLOBAL_MCPS_FILE;
228
+ const p = globalMcpsFile();
233
229
  if (!fs.existsSync(p)) return { mcpServers: {} };
234
230
  try {
235
231
  const json = JSON.parse(fs.readFileSync(p, "utf8"));
@@ -241,7 +237,7 @@ export function readGlobalMcps() {
241
237
  }
242
238
 
243
239
  export function writeGlobalMcps(json) {
244
- const p = GLOBAL_MCPS_FILE;
240
+ const p = globalMcpsFile();
245
241
  fs.mkdirSync(path.dirname(p), { recursive: true });
246
242
  fs.writeFileSync(p, JSON.stringify(json, null, 2) + "\n");
247
243
  }
@@ -23,6 +23,7 @@ import { GLOBAL_MESSAGES_DIR, APX_HOME } from "../config/index.js";
23
23
  import { SELF_MEMORY_PATH, parseSelfMemoryEntries } from "../agent/self-memory.js";
24
24
  import { apcMemoryFile } from "../apc/paths.js";
25
25
  import { embedBatch, embedOne } from "./embeddings.js";
26
+ import { readJson } from "#core/util/json-file.js";
26
27
 
27
28
  export const CURSOR_PATH = path.join(APX_HOME, "memory-cursor.json");
28
29
 
@@ -48,11 +49,7 @@ function readIfExists(p) {
48
49
  }
49
50
 
50
51
  function readCursor(cursorPath) {
51
- try {
52
- return JSON.parse(fs.readFileSync(cursorPath, "utf8"));
53
- } catch {
54
- return { channels: {} };
55
- }
52
+ return readJson(cursorPath, { channels: {} });
56
53
  }
57
54
 
58
55
  function writeCursor(cursorPath, cursor) {
@@ -23,9 +23,7 @@ import {
23
23
  } from "../stores/routines.js";
24
24
 
25
25
  import {
26
- PROFILES_DIR,
27
26
  MANIFEST_FILE,
28
- CONFIG_SCHEMA_FILE,
29
27
  PROFILE_ID_RE,
30
28
  userProfileDir,
31
29
  } from "./paths.js";
@@ -29,14 +29,9 @@ import {
29
29
  promptFileFor,
30
30
  } from "./paths.js";
31
31
  import { schemaDefaults } from "./manifest.js";
32
+ import { readJson } from "#core/util/json-file.js";
33
+
32
34
 
33
- function readJson(file) {
34
- try {
35
- return JSON.parse(fs.readFileSync(file, "utf8"));
36
- } catch {
37
- return null;
38
- }
39
- }
40
35
 
41
36
  function readDirIds(dir) {
42
37
  if (!fs.existsSync(dir)) return [];
@@ -1,5 +1,5 @@
1
1
  // Routine execution — the domain logic any caller can invoke (daemon
2
- // scheduler, CLI `apx routine run`, HTTP `/projects/:pid/routines/:name/run`,
2
+ // scheduler, CLI `apx routine run`, HTTP `/api/projects/:pid/routines/:name/run`,
3
3
  // MCP server, future scripts). The runner orchestrates a 3-phase pipeline:
4
4
  // 1. pre_commands (shell)
5
5
  // 2. handler (heartbeat / exec_agent / super_agent / telegram / shell)
@@ -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/)