@agentprojectcontext/apx 1.77.3 → 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 (293) 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 +6 -6
  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-BptlbKjU.js → index-CBR_-QyA.js} +52 -52
  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 +3 -3
  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-BptlbKjU.js.map +0 -1
  283. package/src/skills/apc-context/SKILL.md +0 -159
  284. /package/src/{host/daemon → core}/runtimes/_spawn.js +0 -0
  285. /package/src/{host/daemon → core}/runtimes/aider.js +0 -0
  286. /package/src/{host/daemon → core}/runtimes/antigravity.js +0 -0
  287. /package/src/{host/daemon → core}/runtimes/claude-code.js +0 -0
  288. /package/src/{host/daemon → core}/runtimes/codex.js +0 -0
  289. /package/src/{host/daemon → core}/runtimes/cursor-agent.js +0 -0
  290. /package/src/{host/daemon → core}/runtimes/gemini-cli.js +0 -0
  291. /package/src/{host/daemon → core}/runtimes/index.js +0 -0
  292. /package/src/{host/daemon → core}/runtimes/opencode.js +0 -0
  293. /package/src/{host/daemon → core}/runtimes/qwen-code.js +0 -0
@@ -220,7 +220,7 @@ export const TTS_PROVIDER_ORDER: TtsProviderId[] = ["piper", "elevenlabs", "open
220
220
  */
221
221
  export async function fetchTtsAudioUrl(audioPath: string): Promise<string> {
222
222
  const token = getToken();
223
- const res = await fetch(`/voice/tts?path=${encodeURIComponent(audioPath)}`, {
223
+ const res = await fetch(`/api/voice/tts?path=${encodeURIComponent(audioPath)}`, {
224
224
  headers: token ? { authorization: `Bearer ${token}` } : {},
225
225
  });
226
226
  if (!res.ok) {
@@ -233,13 +233,13 @@ export async function fetchTtsAudioUrl(audioPath: string): Promise<string> {
233
233
 
234
234
  export const Voice = {
235
235
  /** List TTS engines + availability + the configured default provider. */
236
- providers: () => http.get<TtsProvidersResponse>("/tts/providers"),
236
+ providers: () => http.get<TtsProvidersResponse>("/api/tts/providers"),
237
237
 
238
238
  /** Detected hardware + the recommended local STT backend (Metal/CUDA/CPU). */
239
- sttHardware: () => http.get<SttHardwareResponse>("/transcribe/hardware"),
239
+ sttHardware: () => http.get<SttHardwareResponse>("/api/transcribe/hardware"),
240
240
 
241
241
  /** Model catalog + on-disk status for a local backend ("faster" | "mlx"). */
242
- sttModels: (backend: string) => http.get<SttModelsResponse>(`/transcribe/models?backend=${backend}`),
242
+ sttModels: (backend: string) => http.get<SttModelsResponse>(`/api/transcribe/models?backend=${backend}`),
243
243
 
244
244
  /**
245
245
  * Synthesize speech. Returns the audio file path (server-side); the web
@@ -247,7 +247,7 @@ export const Voice = {
247
247
  * is irrelevant for the web (the daemon never plays for HTTP callers).
248
248
  */
249
249
  say: (body: { text: string; provider?: string; voice?: string; language?: string; format?: string; style?: string }) =>
250
- http.post<TtsSayResult>("/tts/say", body),
250
+ http.post<TtsSayResult>("/api/tts/say", body),
251
251
 
252
252
  /**
253
253
  * One bidirectional voice turn (STT → agent → TTS). The web uses the
@@ -261,5 +261,5 @@ export const Voice = {
261
261
  provider?: string;
262
262
  voice?: string;
263
263
  language?: string;
264
- }) => http.post<VoiceTurnResult>("/voice/turn", body),
264
+ }) => http.post<VoiceTurnResult>("/api/voice/turn", body),
265
265
  };
@@ -21,7 +21,7 @@ type VaultAgent = AgentEntry & { source?: "bundled" | "user" | "user-override" }
21
21
  export function AgentDefaultsTab() {
22
22
  const toast = useToast();
23
23
  const [showRemoved, setShowRemoved] = useState(false);
24
- const swrKey = showRemoved ? "/agents/vault?include_removed=1" : "/agents/vault";
24
+ const swrKey = showRemoved ? "/api/agents/vault?include_removed=1" : "/api/agents/vault";
25
25
  const vault = useSWR(swrKey, () => Agents.vault({ includeRemoved: showRemoved }));
26
26
  const items = (vault.data || []) as VaultAgent[];
27
27
 
@@ -16,7 +16,7 @@ export function GlobalTasksTab() {
16
16
  const [status, setStatus] = useState<TaskStatus | "">("");
17
17
  const effectiveStatus = state === "open" ? status : "";
18
18
  const paged = usePagedQuery({
19
- key: `/tasks?state=${state}&status=${effectiveStatus}`,
19
+ key: `/api/tasks?state=${state}&status=${effectiveStatus}`,
20
20
  fetchPage: (limit, offset) => Tasks.globalPage({ state, limit, offset, status: effectiveStatus }),
21
21
  resetKey: `${state}|${effectiveStatus}`,
22
22
  });
@@ -79,7 +79,7 @@ function LogRow({ m }: { m: MessageEntry }) {
79
79
 
80
80
  function DaemonErrors() {
81
81
  const [open, setOpen] = useState(false);
82
- const logs = useSWR(open ? "/admin/logs?errors" : null, () => Admin.logs("errors", 200));
82
+ const logs = useSWR(open ? "/api/admin/logs?errors" : null, () => Admin.logs("errors", 200));
83
83
  const entries = logs.data?.entries || [];
84
84
  return (
85
85
  <details className="mb-3 rounded-lg border border-border bg-muted/20" onToggle={(e) => setOpen((e.target as HTMLDetailsElement).open)}>
@@ -116,8 +116,8 @@ export function LogsTab({ pid }: { pid?: string }) {
116
116
  const ch = channel.trim() || undefined;
117
117
 
118
118
  const key = isGlobal
119
- ? `/messages/global?channel=${ch ?? ""}`
120
- : `/projects/${pid}/messages?channel=${ch ?? ""}`;
119
+ ? `/api/messages/global?channel=${ch ?? ""}`
120
+ : `/api/projects/${pid}/messages?channel=${ch ?? ""}`;
121
121
  const list = useSWR<MessageEntry[]>(key, () =>
122
122
  isGlobal
123
123
  ? Messages.global({ channel: ch, limit: 300 })
@@ -34,7 +34,7 @@ export function SessionsTab({ pid }: { pid?: string } = {}) {
34
34
  }, [input]);
35
35
 
36
36
  const paged = usePagedQuery<SessionRow>({
37
- key: `/sessions?engine=${engine}&q=${query}&deep=${deep ? 1 : 0}&cwd=${cwd || ""}`,
37
+ key: `/api/sessions?engine=${engine}&q=${query}&deep=${deep ? 1 : 0}&cwd=${cwd || ""}`,
38
38
  fetchPage: (limit, offset) =>
39
39
  Sessions.page({ engine: engine || undefined, q: query || undefined, deep, cwd, limit, offset }),
40
40
  resetKey: `${engine}|${query}|${deep ? 1 : 0}|${cwd || ""}`,
@@ -50,7 +50,7 @@ function ResizeHandleH() {
50
50
  // what the session changed vs its git baseline.
51
51
  export function CodeScreen() {
52
52
  const toast = useToast();
53
- const projects = useSWR("/projects", () => Projects.list());
53
+ const projects = useSWR("/api/projects", () => Projects.list());
54
54
  const projectList = useMemo(() => projects.data || [], [projects.data]);
55
55
 
56
56
  const [pid, setPid] = useState<string>("");
@@ -16,7 +16,7 @@ import { t } from "../../i18n";
16
16
  export function DeckScreen() {
17
17
  const toast = useToast();
18
18
  const { data, error, isLoading, mutate } = useSWR(
19
- "/deck/manifest",
19
+ "/api/deck/manifest",
20
20
  () => Deck.manifest(),
21
21
  { refreshInterval: 30_000 }
22
22
  );
@@ -12,7 +12,7 @@ import { t } from "../../i18n";
12
12
  // shortcut, appearance, activation) live in Settings → Desktop.
13
13
  export function DesktopScreen() {
14
14
  const { data: msgs, isLoading: msgsLoading, mutate: mutateMsgs } = useSWR(
15
- "/messages/global?channel=desktop",
15
+ "/api/messages/global?channel=desktop",
16
16
  () => fetchDesktopMessages(40),
17
17
  { refreshInterval: 8000 },
18
18
  );
@@ -23,7 +23,7 @@ export function VoiceScreen() {
23
23
  isLoading: provLoading,
24
24
  error: provError,
25
25
  mutate: mutateProviders,
26
- } = useSWR("/tts/providers", () => Voice.providers());
26
+ } = useSWR("/api/tts/providers", () => Voice.providers());
27
27
 
28
28
  // editing holds the engine id being configured. "__new__" opens the modal in
29
29
  // "create custom provider" mode.
@@ -61,12 +61,12 @@ export function AgentDetailScreen({ pid }: { pid: string }) {
61
61
  const [tab, setTab] = useState<TabKey>("overview");
62
62
  const TABS = buildTabs();
63
63
 
64
- const detail = useSWR(`/projects/${pid}/agents/${slug}`, () => Agents.get(pid, slug));
65
- const agents = useSWR(`/projects/${pid}/agents`, () => Agents.list(pid));
66
- const routines = useSWR(`/projects/${pid}/routines`, () => Routines.list(pid));
67
- const records = useSWR(`/projects/${pid}/messages?agent=${slug}`, () => Messages.project(pid, { agent: slug, limit: 200 }));
68
- const threads = useSWR(`/projects/${pid}/agents/${slug}/conversations`, () => Conversations.list(pid, slug));
69
- const tasks = useSWR(`/projects/${pid}/tasks?all`, () => Tasks.list(pid, "all"));
64
+ const detail = useSWR(`/api/projects/${pid}/agents/${slug}`, () => Agents.get(pid, slug));
65
+ const agents = useSWR(`/api/projects/${pid}/agents`, () => Agents.list(pid));
66
+ const routines = useSWR(`/api/projects/${pid}/routines`, () => Routines.list(pid));
67
+ const records = useSWR(`/api/projects/${pid}/messages?agent=${slug}`, () => Messages.project(pid, { agent: slug, limit: 200 }));
68
+ const threads = useSWR(`/api/projects/${pid}/agents/${slug}/conversations`, () => Conversations.list(pid, slug));
69
+ const tasks = useSWR(`/api/projects/${pid}/tasks?all`, () => Tasks.list(pid, "all"));
70
70
 
71
71
  const a = detail.data;
72
72
  const myRoutines = routinesForAgent(routines.data || [], slug);
@@ -318,7 +318,7 @@ function Stat({ label, value, icon: I }: { label: string; value: number; icon: t
318
318
  // bare textarea.
319
319
  function MemoryEditor({ pid, slug, onSaved }: { pid: string; slug: string; onSaved: () => void }) {
320
320
  const toast = useToast();
321
- const body = useSWR(`/memory/${pid}/agent:${slug}`, () => Agents.memory.get(pid, slug).then((r) => r.body));
321
+ const body = useSWR(`/api/memory/${pid}/agent:${slug}`, () => Agents.memory.get(pid, slug).then((r) => r.body));
322
322
 
323
323
  const file = useMemo<FileContent | null>(() => {
324
324
  if (body.data === undefined) return null;
@@ -425,7 +425,7 @@ function Field2({ label, value }: { label: string; value: string }) {
425
425
  }
426
426
 
427
427
  function ToolsPicker({ value, onChange }: { value: string; onChange: (v: string) => void }) {
428
- const cat = useSWR("/tools", () => Tools.list());
428
+ const cat = useSWR("/api/tools", () => Tools.list());
429
429
  const selected = csv(value);
430
430
  const catalog = cat.data || [];
431
431
  const toggle = (name: string) => {
@@ -89,7 +89,7 @@ function buildTree(agents: AgentEntry[]) {
89
89
  export function AgentsTab({ pid }: { pid: string }) {
90
90
  const navigate = useNavigate();
91
91
  const toast = useToast();
92
- const list = useSWR(`/projects/${pid}/agents?stats=1`, () => Agents.list(pid, { stats: true }));
92
+ const list = useSWR(`/api/projects/${pid}/agents?stats=1`, () => Agents.list(pid, { stats: true }));
93
93
  const [view, setView] = useState<"hierarchy" | "list">("hierarchy");
94
94
  const [creating, setCreating] = useState(false);
95
95
 
@@ -154,7 +154,7 @@ function ImportVaultDialog({
154
154
  open, onClose, onImported, pid, existing,
155
155
  }: { open: boolean; onClose: () => void; onImported: () => void; pid: string; existing: string[] }) {
156
156
  const toast = useToast();
157
- const vault = useSWR(open ? "/agents/vault" : null, () => Agents.vault());
157
+ const vault = useSWR(open ? "/api/agents/vault" : null, () => Agents.vault());
158
158
  const [busy, setBusy] = useState("");
159
159
  const items = vault.data || [];
160
160
 
@@ -23,7 +23,7 @@ const ROBY_SLUG = "__super_agent__";
23
23
  export function ChatTab({ pid }: { pid: string }) {
24
24
  const toast = useToast();
25
25
  const [params, setSearchParams] = useSearchParams();
26
- const agents = useSWR(`/projects/${pid}/agents`, () => Agents.list(pid));
26
+ const agents = useSWR(`/api/projects/${pid}/agents`, () => Agents.list(pid));
27
27
  const [creating, setCreating] = useState(false);
28
28
  const [model, setModel] = useState("");
29
29
  const [dismissedAskKey, setDismissedAskKey] = useState<string | null>(null);
@@ -147,10 +147,10 @@ export function ChatTab({ pid }: { pid: string }) {
147
147
  try {
148
148
  if (selected.kind === "conv") {
149
149
  await Conversations.remove(pid, selected.agentSlug, selected.convId);
150
- void mutate(`/projects/${pid}/agents/${selected.agentSlug}/conversations`);
150
+ void mutate(`/api/projects/${pid}/agents/${selected.agentSlug}/conversations`);
151
151
  } else if (selected.kind === "thread") {
152
152
  await Conversations.removeThread(pid, selected.channel, selected.threadId);
153
- void mutate(`/projects/${pid}/super-agent/threads`);
153
+ void mutate(`/api/projects/${pid}/super-agent/threads`);
154
154
  }
155
155
  toast.success(t("project.chat.deleted"));
156
156
  setConfirmDelete(false);
@@ -19,7 +19,7 @@ export function ConfigTab({ pid }: { pid: string }) {
19
19
  const toast = useToast();
20
20
  const navigate = useNavigate();
21
21
  const { project, mutate: mutateProject } = useProject(pid);
22
- const cfg = useSWR(`/projects/${pid}/config`, () => Projects.config.show(pid));
22
+ const cfg = useSWR(`/api/projects/${pid}/config`, () => Projects.config.show(pid));
23
23
  const isBase = String(pid) === "0";
24
24
 
25
25
  if (cfg.isLoading) return <Loading />;
@@ -73,9 +73,9 @@ function sourceLabel(source: string): string {
73
73
 
74
74
  export function McpsTab({ pid }: { pid: string }) {
75
75
  const toast = useToast();
76
- const list = useSWR(`/projects/${pid}/mcps`, () => Mcps.list(pid));
77
- const conflicts = useSWR(`/projects/${pid}/mcps/check`, () => Mcps.check(pid));
78
- const vars = useSWR<VarsList>(`/projects/${pid}/vars`, () => Vars.list(pid));
76
+ const list = useSWR(`/api/projects/${pid}/mcps`, () => Mcps.list(pid));
77
+ const conflicts = useSWR(`/api/projects/${pid}/mcps/check`, () => Mcps.check(pid));
78
+ const vars = useSWR<VarsList>(`/api/projects/${pid}/vars`, () => Vars.list(pid));
79
79
  const [dialog, setDialog] = useState<DialogMode>(null);
80
80
  const [activeMcp, setActiveMcp] = useState<string | null>(null);
81
81
  const [results, setResults] = useState<Record<string, McpResult>>({});
@@ -14,12 +14,12 @@ import type { AgentEntry, RoutineEntry, TaskEntry } from "../../types/daemon";
14
14
  // automation), what's in flight (task workflow), and what just happened.
15
15
  export function Overview({ pid }: { pid: string }) {
16
16
  const navigate = useNavigate();
17
- const tasks = useSWR(`/projects/${pid}/tasks?state=open`, () => Tasks.list(pid), { refreshInterval: 20_000 });
18
- const summary = useSWR(`/projects/${pid}/tasks-summary`, () => Tasks.summary(pid), { refreshInterval: 20_000 });
19
- const routines = useSWR(`/projects/${pid}/routines`, () => Routines.list(pid));
20
- const agents = useSWR(`/projects/${pid}/agents`, () => Agents.list(pid));
21
- const mcps = useSWR(`/projects/${pid}/mcps`, () => Mcps.list(pid));
22
- const artifacts = useSWR(`/projects/${pid}/artifacts`, () => Artifacts.list(pid));
17
+ const tasks = useSWR(`/api/projects/${pid}/tasks?state=open`, () => Tasks.list(pid), { refreshInterval: 20_000 });
18
+ const summary = useSWR(`/api/projects/${pid}/tasks-summary`, () => Tasks.summary(pid), { refreshInterval: 20_000 });
19
+ const routines = useSWR(`/api/projects/${pid}/routines`, () => Routines.list(pid));
20
+ const agents = useSWR(`/api/projects/${pid}/agents`, () => Agents.list(pid));
21
+ const mcps = useSWR(`/api/projects/${pid}/mcps`, () => Mcps.list(pid));
22
+ const artifacts = useSWR(`/api/projects/${pid}/artifacts`, () => Artifacts.list(pid));
23
23
 
24
24
  const agentList = agents.data ?? [];
25
25
  const orchestrators = agentList.filter((a) => a.is_master || a.type === "orchestrator");
@@ -15,7 +15,7 @@ import { RoutineEditor } from "../../components/routines/RoutineEditor";
15
15
  // editing is behind a button, delete uses the shared <Dialog>.
16
16
  export function RoutinesTab({ pid }: { pid: string }) {
17
17
  const toast = useToast();
18
- const list = useSWR(`/projects/${pid}/routines`, () => Routines.list(pid));
18
+ const list = useSWR(`/api/projects/${pid}/routines`, () => Routines.list(pid));
19
19
  const [params, setParams] = useSearchParams();
20
20
  const [editing, setEditing] = useState<Partial<RoutineEntry> | null>(null);
21
21
  const [confirmDelete, setConfirmDelete] = useState<RoutineEntry | null>(null);
@@ -56,7 +56,7 @@ export function RoutinesTab({ pid }: { pid: string }) {
56
56
  // Refresh the routine list (last status) and its executions list.
57
57
  await Promise.all([
58
58
  list.mutate(),
59
- globalMutate(`/projects/${pid}/routines/${r.name}/runs`),
59
+ globalMutate(`/api/projects/${pid}/routines/${r.name}/runs`),
60
60
  ]);
61
61
  } catch (e: any) { toast.error(e?.message || t("project.routines.run_error")); }
62
62
  finally { setRunning(null); }
@@ -12,7 +12,7 @@ import type { OrgArea, OrgRole } from "../../types/daemon";
12
12
 
13
13
  export function StructureTab({ pid }: { pid: string }) {
14
14
  const toast = useToast();
15
- const org = useSWR(`/projects/${pid}/organization`, () => Org.get(pid));
15
+ const org = useSWR(`/api/projects/${pid}/organization`, () => Org.get(pid));
16
16
 
17
17
  const [areaDialog, setAreaDialog] = useState<{ editing?: OrgArea | null } | null>(null);
18
18
  const [roleDialog, setRoleDialog] = useState<{ editing?: OrgRole | null; presetArea?: string | null } | null>(null);
@@ -18,7 +18,7 @@ export function TasksTab({ pid }: { pid: string }) {
18
18
  // dedupingInterval:0 so switching the state filter always revalidates the
19
19
  // target page instead of showing the stale cached one from a prior switch.
20
20
  const paged = usePagedQuery({
21
- key: `/projects/${pid}/tasks?state=${state}`,
21
+ key: `/api/projects/${pid}/tasks?state=${state}`,
22
22
  fetchPage: (limit, offset) => Tasks.listPage(pid, { state, limit, offset }),
23
23
  resetKey: state,
24
24
  swr: { dedupingInterval: 0, revalidateOnFocus: true },
@@ -23,7 +23,7 @@ export function VarsTab({ pid }: { pid: string }) {
23
23
  );
24
24
  const [revealAll, setRevealAll] = useState(false);
25
25
  const list = useSWR<VarsList>(
26
- `/projects/${pid}/vars?reveal=${revealAll ? 1 : 0}`,
26
+ `/api/projects/${pid}/vars?reveal=${revealAll ? 1 : 0}`,
27
27
  () => Vars.list(pid, { reveal: revealAll }),
28
28
  );
29
29
  const [openCreate, setOpenCreate] = useState<{ name?: string; value?: string; scope?: VarScope } | null>(null);
@@ -6,28 +6,23 @@ import path from "node:path";
6
6
  // Vite config for the APX admin panel.
7
7
  //
8
8
  // - Single SPA, no SSR (this is a local admin tool).
9
- // - During `vite dev`, every daemon API prefix is proxied to the running
10
- // daemon so we develop the UI with hot reload against REAL data. Frontend
11
- // routes (/, /settings, /p/:id) are NOT listed, so vite serves index.html
12
- // for them (SPA routing).
9
+ // - During `vite dev`, /api is proxied to the running daemon so we develop the
10
+ // UI with hot reload against REAL data. Frontend routes (/, /settings,
11
+ // /p/:id) live outside /api, so vite serves index.html for them (SPA
12
+ // routing). `ws: true` also carries the /api/desktop/ws upgrade through.
13
13
  // - `vite build` emits to ./dist; the daemon serves that folder when present.
14
+ //
15
+ // This used to be a hand-maintained list of every daemon prefix, kept in sync
16
+ // by hand with two other copies (the SPA fallback and the auth allowlist) —
17
+ // and it drifted. Now the daemon mounts everything under /api
18
+ // (src/host/daemon/api/prefix.js), so one entry covers the whole surface and
19
+ // a new route can never be missed here.
14
20
 
15
21
  const DAEMON_TARGET = process.env.APX_DAEMON_URL || "http://127.0.0.1:7430";
16
22
 
17
- // Keep in sync with API_PREFIXES in src/host/daemon/api/shared.js — that's the
18
- // source of truth for what is a daemon route. A missing prefix means `vite dev`
19
- // silently serves the SPA shell for that call instead of the real response
20
- // (e.g. an empty /pair/list).
21
- const API_PREFIXES = [
22
- "/health", "/admin", "/projects", "/telegram", "/engines", "/runtimes",
23
- "/messages", "/sessions", "/tools", "/mcp", "/voice", "/tts", "/desktop", "/overlay",
24
- "/transcribe", "/run", "/files", "/memory", "/env", "/pair", "/deck",
25
- "/super-agent", "/identity", "/agents", "/tasks", "/code",
26
- ];
27
-
28
- const proxy = Object.fromEntries(
29
- API_PREFIXES.map((p) => [p, { target: DAEMON_TARGET, changeOrigin: false, ws: true }])
30
- );
23
+ const proxy = {
24
+ "/api": { target: DAEMON_TARGET, changeOrigin: false, ws: true },
25
+ };
31
26
 
32
27
  export default defineConfig({
33
28
  plugins: [react(), tailwindcss()],