@agentprojectcontext/apx 1.32.0 → 1.32.2

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 (219) hide show
  1. package/package.json +6 -1
  2. package/skills/apc-context/SKILL.md +5 -2
  3. package/skills/apx/SKILL.md +3 -3
  4. package/skills/apx-agency-agents/SKILL.md +5 -5
  5. package/skills/apx-agent/SKILL.md +7 -7
  6. package/skills/apx-mcp/SKILL.md +6 -4
  7. package/skills/apx-mcp-builder/SKILL.md +4 -7
  8. package/skills/apx-project/SKILL.md +4 -5
  9. package/skills/apx-routine/SKILL.md +14 -12
  10. package/skills/apx-runtime/SKILL.md +5 -3
  11. package/skills/apx-sessions/SKILL.md +5 -5
  12. package/skills/apx-skill-builder/SKILL.md +10 -6
  13. package/skills/apx-task/SKILL.md +8 -8
  14. package/skills/apx-telegram/SKILL.md +23 -7
  15. package/skills/apx-voice/SKILL.md +8 -6
  16. package/src/core/{agent-system.js → agent/build-agent-system.js} +10 -12
  17. package/src/core/agent/index.js +0 -2
  18. package/src/core/{agent-memory.js → agent/memory.js} +2 -2
  19. package/src/core/agent/model-router.js +21 -43
  20. package/src/core/agent/prompt-builder.js +17 -63
  21. package/src/core/agent/prompts/action-discipline.md +17 -0
  22. package/src/core/agent/prompts/channels/code.md +8 -12
  23. package/src/core/agent/prompts/channels/desktop.md +6 -4
  24. package/src/core/agent/prompts/channels/routine.md +10 -1
  25. package/src/core/agent/prompts/channels/telegram.md +5 -0
  26. package/src/core/agent/prompts/channels/web_code.md +20 -0
  27. package/src/core/agent/prompts/modes/voice.md +2 -2
  28. package/src/core/agent/prompts/super-agent-base.md +2 -2
  29. package/src/core/agent/run-agent.js +37 -35
  30. package/src/core/agent/runtime-bridge.js +42 -0
  31. package/src/core/agent/self-memory.js +19 -9
  32. package/src/core/agent/skills/catalog.js +65 -0
  33. package/src/core/agent/skills/index.js +6 -0
  34. package/src/{host/daemon/skills-loader.js → core/agent/skills/loader.js} +3 -3
  35. package/src/core/agent/skills/rag.js +91 -0
  36. package/src/core/agent/skills/trigger.js +71 -0
  37. package/src/{host/daemon → core/agent}/super-agent.js +5 -5
  38. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/add-project.js +3 -4
  39. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/call-agent.js +2 -2
  40. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/call-mcp.js +1 -2
  41. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/call-runtime.js +10 -11
  42. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/create-task.js +1 -1
  43. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/discover-tools.js +1 -1
  44. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/edit-file.js +1 -2
  45. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/import-agent.js +4 -5
  46. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-agents.js +1 -1
  47. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-skills.js +7 -2
  48. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-tasks.js +1 -1
  49. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-vault-agents.js +1 -1
  50. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/load-skill.js +1 -1
  51. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/read-agent-memory.js +1 -1
  52. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/read-self-memory.js +1 -1
  53. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/remember.js +1 -1
  54. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/run-shell.js +1 -2
  55. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/search-messages.js +1 -1
  56. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/search-sessions.js +1 -1
  57. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/send-telegram.js +0 -2
  58. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/set-identity.js +1 -3
  59. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/set-permission-mode.js +1 -3
  60. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/tail-messages.js +1 -1
  61. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/transcribe-audio.js +1 -1
  62. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/write-file.js +1 -2
  63. package/src/core/agent/tools/helpers.js +74 -0
  64. package/src/{host/daemon/super-agent-tools → core/agent/tools}/registry-bridge.js +3 -3
  65. package/src/{host/daemon/super-agent-tools/index.js → core/agent/tools/registry.js} +31 -32
  66. package/src/core/apc/agents-vault.js +37 -0
  67. package/src/core/{scaffold.js → apc/scaffold.js} +4 -5
  68. package/src/core/{config.js → config/index.js} +21 -27
  69. package/src/core/config/paths.js +32 -0
  70. package/src/core/constants/actors.js +8 -0
  71. package/src/core/constants/channels.js +19 -0
  72. package/src/core/constants/index.js +5 -0
  73. package/src/core/constants/permissions.js +17 -0
  74. package/src/core/constants/roles.js +9 -0
  75. package/src/core/engines/_streaming.js +63 -0
  76. package/src/core/engines/anthropic.js +11 -22
  77. package/src/core/engines/ollama.js +7 -16
  78. package/src/core/identity/index.js +8 -0
  79. package/src/core/{identity.js → identity/self.js} +5 -5
  80. package/src/core/{telegram-identity.js → identity/telegram.js} +1 -1
  81. package/src/core/logging.js +1 -1
  82. package/src/core/mascot.js +1 -1
  83. package/src/core/memory/active-threads.js +10 -10
  84. package/src/core/memory/broker.js +9 -9
  85. package/src/core/memory/compactor.js +2 -2
  86. package/src/core/memory/index.js +2 -2
  87. package/src/core/memory/indexer.js +1 -1
  88. package/src/core/{code-sessions-store.js → stores/code-sessions.js} +3 -7
  89. package/src/core/{messages-store.js → stores/messages.js} +6 -4
  90. package/src/core/stores/routine-memory.js +71 -0
  91. package/src/core/{routines-store.js → stores/routines.js} +1 -3
  92. package/src/core/stores/runtime-sessions.js +99 -0
  93. package/src/core/{tasks-store.js → stores/tasks.js} +3 -8
  94. package/src/core/update-check.js +1 -1
  95. package/src/core/util/ids.js +14 -0
  96. package/src/core/util/index.js +2 -0
  97. package/src/core/util/text-similarity.js +52 -0
  98. package/src/core/util/time.js +9 -0
  99. package/src/core/voice/tts.js +1 -1
  100. package/src/host/daemon/api/admin-config.js +4 -3
  101. package/src/host/daemon/api/admin.js +1 -1
  102. package/src/host/daemon/api/agents.js +4 -25
  103. package/src/host/daemon/api/artifacts.js +1 -1
  104. package/src/host/daemon/api/code.js +48 -16
  105. package/src/host/daemon/api/confirm.js +1 -1
  106. package/src/host/daemon/api/connections.js +2 -2
  107. package/src/host/daemon/api/conversations.js +2 -2
  108. package/src/host/daemon/api/deck.js +1 -1
  109. package/src/host/daemon/api/desktop.js +1 -1
  110. package/src/host/daemon/api/embeddings.js +4 -4
  111. package/src/host/daemon/api/engines.js +2 -2
  112. package/src/host/daemon/api/exec.js +3 -3
  113. package/src/host/daemon/api/identity.js +1 -1
  114. package/src/host/daemon/api/mcps.js +1 -1
  115. package/src/host/daemon/api/messages.js +1 -1
  116. package/src/host/daemon/api/runtimes.js +9 -8
  117. package/src/host/daemon/api/sessions-search.js +1 -1
  118. package/src/host/daemon/api/sessions.js +2 -2
  119. package/src/host/daemon/api/shared.js +5 -4
  120. package/src/host/daemon/api/skills.js +30 -0
  121. package/src/host/daemon/api/super-agent.js +29 -9
  122. package/src/host/daemon/api/tasks.js +2 -2
  123. package/src/host/daemon/api/telegram.js +1 -1
  124. package/src/host/daemon/api/tools.js +6 -6
  125. package/src/host/daemon/api/tts.js +2 -2
  126. package/src/host/daemon/api/voice.js +14 -12
  127. package/src/host/daemon/api.js +2 -0
  128. package/src/host/daemon/compact.js +1 -1
  129. package/src/host/daemon/db.js +4 -4
  130. package/src/host/daemon/desktop-ws.js +1 -1
  131. package/src/host/daemon/index.js +4 -4
  132. package/src/host/daemon/plugins/{desktop.js → desktop/index.js} +11 -6
  133. package/src/host/daemon/plugins/index.js +2 -2
  134. package/src/host/daemon/plugins/{telegram.js → telegram/index.js} +66 -195
  135. package/src/host/daemon/plugins/telegram/media.js +162 -0
  136. package/src/host/daemon/projects-helpers.js +54 -0
  137. package/src/host/daemon/routines.js +28 -12
  138. package/src/host/daemon/smoke.js +2 -2
  139. package/src/host/daemon/token-store.js +1 -1
  140. package/src/host/daemon/transcription.js +2 -2
  141. package/src/host/daemon/wakeup.js +2 -2
  142. package/src/interfaces/cli/commands/agent.js +3 -3
  143. package/src/interfaces/cli/commands/command.js +1 -1
  144. package/src/interfaces/cli/commands/config.js +3 -2
  145. package/src/interfaces/cli/commands/desktop.js +1 -1
  146. package/src/interfaces/cli/commands/exec.js +2 -1
  147. package/src/interfaces/cli/commands/identity.js +2 -2
  148. package/src/interfaces/cli/commands/init.js +1 -1
  149. package/src/interfaces/cli/commands/mcp.js +1 -1
  150. package/src/interfaces/cli/commands/memory.js +2 -2
  151. package/src/interfaces/cli/commands/model.js +16 -6
  152. package/src/interfaces/cli/commands/project.js +1 -1
  153. package/src/interfaces/cli/commands/routine.js +58 -0
  154. package/src/interfaces/cli/commands/search.js +1 -1
  155. package/src/interfaces/cli/commands/session.js +4 -4
  156. package/src/interfaces/cli/commands/setup.js +4 -3
  157. package/src/interfaces/cli/commands/skills.js +25 -4
  158. package/src/interfaces/cli/commands/status.js +1 -1
  159. package/src/interfaces/cli/commands/sys.js +11 -4
  160. package/src/interfaces/cli/commands/update.js +1 -1
  161. package/src/interfaces/cli/index.js +4 -4
  162. package/src/interfaces/cli/postinstall.js +2 -2
  163. package/src/interfaces/mcp-server/index.js +1 -1
  164. package/src/interfaces/tui/component/prompt/index.tsx +3 -1
  165. package/src/interfaces/tui/context/sdk-apx.tsx +47 -7
  166. package/src/interfaces/tui/context/sync-apx.tsx +20 -2
  167. package/src/interfaces/tui/context/sync.tsx +2 -1
  168. package/src/interfaces/tui/routes/session/index.tsx +151 -136
  169. package/src/interfaces/tui/routes/session/sidebar-apx.tsx +37 -15
  170. package/src/interfaces/tui/run.ts +2 -0
  171. package/src/interfaces/web/dist/assets/index-34U_Mp1M.css +1 -0
  172. package/src/interfaces/web/dist/assets/index-BkybwwRn.js +570 -0
  173. package/src/interfaces/web/dist/assets/index-BkybwwRn.js.map +1 -0
  174. package/src/interfaces/web/dist/index.html +2 -2
  175. package/src/interfaces/web/package-lock.json +3 -3
  176. package/src/interfaces/web/src/App.tsx +51 -32
  177. package/src/interfaces/web/src/components/RobyBubble.tsx +12 -6
  178. package/src/interfaces/web/src/components/UiSelect.tsx +1 -1
  179. package/src/interfaces/web/src/components/chat/SkillPicker.tsx +77 -0
  180. package/src/interfaces/web/src/components/code/CodeProjectPicker.tsx +1 -1
  181. package/src/interfaces/web/src/components/code/CodeSidePanel.tsx +33 -18
  182. package/src/interfaces/web/src/components/common/TabLayout.tsx +9 -5
  183. package/src/interfaces/web/src/components/common/TabNav.tsx +3 -3
  184. package/src/interfaces/web/src/components/layout/ProjectSidebar.tsx +4 -2
  185. package/src/interfaces/web/src/hooks/useChat.ts +47 -2
  186. package/src/interfaces/web/src/hooks/useNavCollapseCtx.tsx +59 -0
  187. package/src/interfaces/web/src/hooks/usePersonaName.ts +11 -0
  188. package/src/interfaces/web/src/i18n/en.ts +7 -7
  189. package/src/interfaces/web/src/i18n/es.ts +7 -7
  190. package/src/interfaces/web/src/lib/api/skills.ts +25 -0
  191. package/src/interfaces/web/src/lib/api.ts +1 -0
  192. package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +18 -18
  193. package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +5 -18
  194. package/src/interfaces/web/src/screens/modules/DesktopScreen.tsx +1 -8
  195. package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +39 -40
  196. package/src/interfaces/web/src/screens/project/ChatTab.tsx +12 -9
  197. package/src/skills/apc-context/SKILL.md +159 -0
  198. package/src/core/agent/ghost-guard.js +0 -24
  199. package/src/core/agent/prompts/channels/terminal.md +0 -16
  200. package/src/host/daemon/apc-runtime-context.js +0 -124
  201. package/src/host/daemon/super-agent-tools/helpers.js +0 -124
  202. package/src/host/daemon/tool-call-parser.js +0 -2
  203. package/src/interfaces/web/dist/assets/index-63P_ji1a.js +0 -571
  204. package/src/interfaces/web/dist/assets/index-63P_ji1a.js.map +0 -1
  205. package/src/interfaces/web/dist/assets/index-DLWy6dYz.css +0 -1
  206. /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/ask-questions.js +0 -0
  207. /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-files.js +0 -0
  208. /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-mcps.js +0 -0
  209. /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-projects.js +0 -0
  210. /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/read-file.js +0 -0
  211. /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/search-files.js +0 -0
  212. /package/src/core/agent/{pseudo-tools.js → tools/pseudo-tools.js} +0 -0
  213. /package/src/core/agent/{tool-call-parser.js → tools/tool-call-parser.js} +0 -0
  214. /package/src/core/{parser.js → apc/parser.js} +0 -0
  215. /package/src/core/{apc-skill-sync.js → apc/skill-sync.js} +0 -0
  216. /package/src/core/{artifacts-store.js → stores/artifacts.js} +0 -0
  217. /package/src/{host/daemon → core/stores}/engine-sessions.js +0 -0
  218. /package/src/core/{session-store.js → stores/sessions.js} +0 -0
  219. /package/src/host/daemon/plugins/{telegram-ask.js → telegram/ask.js} +0 -0
@@ -286,8 +286,8 @@ export const en = {
286
286
  chat: {
287
287
  title: "Chat with agent",
288
288
  subtitle: "Direct conversations with project agents. The super-agent does not intervene.",
289
- roby_title: "Chat with Roby",
290
- roby_subtitle: "Chat with Roby — the APX super-agent. Can use tools (projects, tasks, mcps, agents).",
289
+ superagent_title: "Chat with {persona}",
290
+ superagent_subtitle: "Chat with {persona} — the APX super-agent. Can use tools (projects, tasks, mcps, agents).",
291
291
  empty: "Send a message to start the conversation.",
292
292
  placeholder: "Type something and press enter to send (shift+enter = new line)",
293
293
  send: "Send",
@@ -710,13 +710,13 @@ export const en = {
710
710
  delete_btn: "Delete",
711
711
  },
712
712
 
713
- roby: {
714
- title: "Roby",
713
+ superagent: {
714
+ title: "{persona}",
715
715
  badge: "super-agent · APX",
716
716
  desc: "Quick chat with your super-agent. Has access to tools (projects, tasks, mcps, agents); for a longer persistent thread, open Chats.",
717
- empty: "Send Roby a message to get started.",
718
- thinking: "Roby is thinking…",
719
- talk: "Talk to Roby",
717
+ empty: "Send {persona} a message to get started.",
718
+ thinking: "{persona} is thinking…",
719
+ talk: "Talk to {persona}",
720
720
  new_chat: "New chat",
721
721
  placeholder: "Type and press enter to send (shift+enter = new line)…",
722
722
  },
@@ -287,8 +287,8 @@ export const es = {
287
287
  chat: {
288
288
  title: "Chat con agente",
289
289
  subtitle: "Conversaciones directas con agentes del proyecto. El super-agent no interviene.",
290
- roby_title: "Chat con Roby",
291
- roby_subtitle: "Chat con Roby — el super-agente APX. Puede usar tools (proyectos, tasks, mcps, agentes).",
290
+ superagent_title: "Chat con {persona}",
291
+ superagent_subtitle: "Chat con {persona} — el super-agente APX. Puede usar tools (proyectos, tasks, mcps, agentes).",
292
292
  empty: "Mandá un mensaje para arrancar la conversación.",
293
293
  placeholder: "Escribí algo y enter para enviar (shift+enter = nueva línea)",
294
294
  send: "Enviar",
@@ -711,13 +711,13 @@ export const es = {
711
711
  delete_btn: "Borrar",
712
712
  },
713
713
 
714
- roby: {
715
- title: "Roby",
714
+ superagent: {
715
+ title: "{persona}",
716
716
  badge: "super-agent · APX",
717
717
  desc: "Conversación rápida con tu super-agente. Tiene acceso a tools (proyectos, tasks, mcps, agentes); para un hilo más largo y persistente, abrí Chats.",
718
- empty: "Mandale un mensaje a Roby para arrancar.",
719
- thinking: "Roby está pensando…",
720
- talk: "Hablar con Roby",
718
+ empty: "Mandale un mensaje a {persona} para arrancar.",
719
+ thinking: "{persona} está pensando…",
720
+ talk: "Hablar con {persona}",
721
721
  new_chat: "Nuevo chat",
722
722
  placeholder: "Escribí y enter para enviar (shift+enter = nueva línea)…",
723
723
  },
@@ -0,0 +1,25 @@
1
+ import { http } from "../http";
2
+
3
+ export type SkillEntry = {
4
+ slug: string;
5
+ source: "bundled" | "user" | "project" | string;
6
+ description: string;
7
+ };
8
+
9
+ export type SkillsList = {
10
+ count: number;
11
+ skills: SkillEntry[];
12
+ };
13
+
14
+ export const Skills = {
15
+ /**
16
+ * List installed skills (bundled + user + optional project-scoped). The
17
+ * description is already condensed for one-line rendering.
18
+ */
19
+ list: (projectPath?: string) =>
20
+ http.get<SkillsList>(
21
+ projectPath
22
+ ? `/skills?project_path=${encodeURIComponent(projectPath)}`
23
+ : "/skills",
24
+ ),
25
+ };
@@ -22,6 +22,7 @@ export * from "./api/voice";
22
22
  export * from "./api/deck";
23
23
  export * from "./api/code";
24
24
  export * from "./api/artifacts";
25
+ export * from "./api/skills";
25
26
 
26
27
  // Re-export the daemon types so older imports of "../lib/api" still work.
27
28
  export type {
@@ -1,8 +1,8 @@
1
1
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
2
  import useSWR from "swr";
3
- import { Code2 } from "lucide-react";
4
3
  import { Code, Projects } from "../../lib/api";
5
4
  import { Badge, Empty, Loading } from "../../components/ui";
5
+ import { useSetPageLabel } from "../../hooks/useNavCollapseCtx";
6
6
  import { MessageList } from "../../components/chat/MessageList";
7
7
  import { CodeProjectPicker } from "../../components/code/CodeProjectPicker";
8
8
  import { CodeSessionList } from "../../components/code/CodeSessionList";
@@ -209,6 +209,11 @@ export function CodeScreen() {
209
209
 
210
210
  const hasProjects = !projects.isLoading && projectList.length > 0;
211
211
  const turns: CodeTurn[] = useMemo(() => msgs as unknown as CodeTurn[], [msgs]);
212
+ const activeTitle = useMemo(
213
+ () => sessions.data?.find((s) => s.id === sid)?.title || "",
214
+ [sessions.data, sid],
215
+ );
216
+ useSetPageLabel(activeTitle);
212
217
 
213
218
  // Detect unanswered ask_questions in the last assistant turn. Local "dismissed"
214
219
  // ref keys off the turn id so the panel re-appears for a fresh batch.
@@ -221,25 +226,17 @@ export function CodeScreen() {
221
226
  };
222
227
 
223
228
  return (
224
- <div className="flex h-full min-h-0 flex-col overflow-hidden p-4" data-testid="screen-code">
225
- <header className="mb-3 flex items-center justify-between gap-3">
226
- <div className="min-w-0">
227
- <h1 className="flex items-center gap-2 text-2xl font-bold tracking-tight">
228
- <Code2 size={22} /> {t("code_module.title")}
229
- </h1>
230
- <p className="text-sm text-muted-fg">{t("code_module.desc")}</p>
231
- </div>
232
- <Badge tone="success">{t("code_module.badge")}</Badge>
233
- </header>
234
-
229
+ <div className="flex h-full min-h-0" data-testid="screen-code">
235
230
  {projects.isLoading ? (
236
231
  <Loading />
237
232
  ) : !hasProjects ? (
238
- <Empty>{t("code_module.no_projects")}</Empty>
233
+ <div className="grid flex-1 place-items-center">
234
+ <Empty>{t("code_module.no_projects")}</Empty>
235
+ </div>
239
236
  ) : (
240
- <div className="flex min-h-0 flex-1 overflow-hidden rounded-xl border border-border bg-card/40">
241
- {/* Left rail: project picker + session list */}
242
- <aside className="flex w-60 shrink-0 flex-col border-r border-border">
237
+ <>
238
+ {/* Left: project picker + session list */}
239
+ <aside className="flex w-52 shrink-0 flex-col border-r border-border">
243
240
  <div className="shrink-0 border-b border-border p-2">
244
241
  <CodeProjectPicker
245
242
  projects={projectList}
@@ -257,6 +254,9 @@ export function CodeScreen() {
257
254
  onRename={onRenameSession}
258
255
  onDelete={onDeleteSession}
259
256
  />
257
+ <div className="shrink-0 border-t border-border px-3 py-2">
258
+ <Badge tone="success">{t("code_module.badge")}</Badge>
259
+ </div>
260
260
  </aside>
261
261
 
262
262
  {/* Center: transcript + composer */}
@@ -300,7 +300,7 @@ export function CodeScreen() {
300
300
  </main>
301
301
 
302
302
  {/* Right: context + changes */}
303
- <aside className="hidden w-80 shrink-0 flex-col border-l border-border lg:flex">
303
+ <aside className="hidden w-72 shrink-0 flex-col border-l border-border lg:flex">
304
304
  <CodeSidePanel
305
305
  pid={pid}
306
306
  turns={turns}
@@ -309,7 +309,7 @@ export function CodeScreen() {
309
309
  onRefreshChanges={() => void changes.mutate()}
310
310
  />
311
311
  </aside>
312
- </div>
312
+ </>
313
313
  )}
314
314
  </div>
315
315
  );
@@ -76,24 +76,6 @@ export function DeckScreen() {
76
76
 
77
77
  return (
78
78
  <div className="mx-auto max-w-4xl space-y-6 p-6" data-testid="screen-deck">
79
- <header className="flex items-start justify-between gap-4">
80
- <div>
81
- <h1 className="text-2xl font-bold tracking-tight">Deck</h1>
82
- <p className="text-sm text-muted-fg">
83
- App companion · widgets y escritorios.
84
- </p>
85
- </div>
86
- <Button
87
- size="sm"
88
- variant="ghost"
89
- onClick={() => mutate()}
90
- disabled={isLoading}
91
- title="Recargar manifest"
92
- >
93
- <RefreshCw size={14} className={isLoading ? "animate-spin" : ""} />
94
- </Button>
95
- </header>
96
-
97
79
  {/* Daemon info card */}
98
80
  {data && <DaemonCard manifest={data} />}
99
81
 
@@ -107,6 +89,11 @@ export function DeckScreen() {
107
89
  ? "Error al cargar el manifest."
108
90
  : `${widgets.length} widgets · ${enabledCount} externos habilitados`
109
91
  }
92
+ action={
93
+ <Button size="sm" variant="ghost" onClick={() => mutate()} disabled={isLoading} title="Recargar manifest">
94
+ <RefreshCw size={14} className={isLoading ? "animate-spin" : ""} />
95
+ </Button>
96
+ }
110
97
  >
111
98
  {isLoading && <Loading label="Cargando manifest del Deck…" />}
112
99
 
@@ -96,15 +96,8 @@ export function DesktopScreen() {
96
96
 
97
97
  return (
98
98
  <div className="mx-auto max-w-6xl space-y-6 p-6" data-testid="screen-desktop">
99
- <header>
100
- <h1 className="text-2xl font-bold tracking-tight">Escritorio</h1>
101
- <p className="text-sm text-muted-fg">
102
- Ventana flotante de voz (Electron): atajo global, escucha por micrófono y muestra el chat.
103
- </p>
104
- </header>
105
-
106
99
  {/* ── Two-column layout: config on the left, last conversation on the right. ── */}
107
- <div className="grid gap-6 lg:grid-cols-[1fr_1fr]">
100
+ <div className="grid gap-6 xl:grid-cols-[1fr_1fr]">
108
101
  {/* ── LEFT: configuration + status ─────────────────────────────── */}
109
102
  <div className="space-y-6">
110
103
  <Section title="Estado" description="La ventana se lanza desde la terminal o por autostart.">
@@ -119,48 +119,47 @@ export function VoiceScreen() {
119
119
  };
120
120
 
121
121
  return (
122
- <div className="mx-auto max-w-4xl space-y-6 p-6" data-testid="screen-voice">
123
- <header>
124
- <h1 className="text-2xl font-bold tracking-tight">Voces</h1>
125
- <p className="text-sm text-muted-fg">
126
- Configurá el texto a voz (TTS) y la transcripción (STT), elegí el motor por defecto y probá la voz.
127
- </p>
128
- </header>
122
+ <div className="mx-auto max-w-6xl p-6" data-testid="screen-voice">
123
+ <div className="grid gap-6 xl:grid-cols-2">
124
+ {/* Left: TTS providers */}
125
+ <Section
126
+ title="Proveedores de voz (TTS)"
127
+ description="Motores de síntesis. El estado lo reporta el daemon en vivo. Elegí cuál usar por defecto."
128
+ >
129
+ {provLoading || cfgLoading ? (
130
+ <Loading />
131
+ ) : provError ? (
132
+ <Empty>No se pudieron cargar los proveedores: {(provError as Error).message}</Empty>
133
+ ) : (
134
+ <VoiceProviderList
135
+ engines={engines}
136
+ order={order}
137
+ mode={mode}
138
+ configuredProvider={configuredProvider}
139
+ onSetMode={setMode}
140
+ onSetDefault={setDefault}
141
+ onToggleEnabled={toggleEnabled}
142
+ onReorder={reorder}
143
+ onConfigure={(id) => setEditing(id)}
144
+ busy={busyDefault}
145
+ />
146
+ )}
147
+ </Section>
129
148
 
130
- <Section
131
- title="Proveedores de voz (TTS)"
132
- description="Motores de síntesis. El estado lo reporta el daemon en vivo. Elegí cuál usar por defecto."
133
- >
134
- {provLoading || cfgLoading ? (
135
- <Loading />
136
- ) : provError ? (
137
- <Empty>No se pudieron cargar los proveedores: {(provError as Error).message}</Empty>
138
- ) : (
139
- <VoiceProviderList
140
- engines={engines}
141
- order={order}
142
- mode={mode}
143
- configuredProvider={configuredProvider}
144
- onSetMode={setMode}
145
- onSetDefault={setDefault}
146
- onToggleEnabled={toggleEnabled}
147
- onReorder={reorder}
148
- onConfigure={(id) => setEditing(id)}
149
- busy={busyDefault}
150
- />
151
- )}
152
- </Section>
149
+ {/* Right: test + STT */}
150
+ <div className="space-y-6">
151
+ <Section title="Probar voz" description='Elegí con qué motor sintetizar y, si aplica, cómo querés que hable.'>
152
+ <VoiceTestCard engines={engines} defaultProvider={configuredProvider} mode={mode} />
153
+ </Section>
153
154
 
154
- <Section title="Probar voz" description='Elegí con qué motor sintetizar y, si aplica, cómo querés que hable.'>
155
- <VoiceTestCard engines={engines} defaultProvider={configuredProvider} mode={mode} />
156
- </Section>
157
-
158
- <Section
159
- title="Transcripción (STT)"
160
- description="Motor de voz a texto que usan el deck, Telegram y la CLI al escuchar."
161
- >
162
- {cfgLoading ? <Loading /> : <VoiceSttCard config={transcriptionCfg} onPatch={patchStt} />}
163
- </Section>
155
+ <Section
156
+ title="Transcripción (STT)"
157
+ description="Motor de voz a texto que usan el deck, Telegram y la CLI al escuchar."
158
+ >
159
+ {cfgLoading ? <Loading /> : <VoiceSttCard config={transcriptionCfg} onPatch={patchStt} />}
160
+ </Section>
161
+ </div>
162
+ </div>
164
163
 
165
164
  <VoiceProviderModal
166
165
  open={!!editing}
@@ -12,6 +12,7 @@ import { InlineAskPanel, pendingAskQuestions } from "../../components/chat/Inlin
12
12
  import { useChat } from "../../hooks/useChat";
13
13
  import { useToast } from "../../components/Toast";
14
14
  import { t } from "../../i18n";
15
+ import { usePersonaName } from "../../hooks/usePersonaName";
15
16
  import type { AgentEntry } from "../../types/daemon";
16
17
 
17
18
  // Virtual entry slug used in the agent dropdown to address the daemon-level
@@ -28,18 +29,19 @@ export function ChatTab({ pid }: { pid: string }) {
28
29
  const [model, setModel] = useState("");
29
30
  const [dismissedAskKey, setDismissedAskKey] = useState<string | null>(null);
30
31
  const { msgs, send: sendChat, stop, clear, streaming } = useChat(pid, (m) => toast.error(m));
32
+ const persona = usePersonaName();
31
33
 
32
34
  const agentList = agents.data || [];
33
- // Virtual options shown in the dropdown — Roby is always first, then the
34
- // real project agents. Roby works on every project (calls /projects/:pid
35
- // /super-agent/chat) so we expose it everywhere, not just /base.
35
+ // Virtual options shown in the dropdown — the super-agent is always first,
36
+ // then the real project agents. It works on every project (calls
37
+ // /projects/:pid/super-agent/chat) so we expose it everywhere, not just /base.
36
38
  const isRoby = (slug: string | null | undefined) => slug === ROBY_SLUG;
37
39
  const dropdownOptions = useMemo(
38
40
  () => [
39
- { value: ROBY_SLUG, label: "Roby (super-agent)" },
41
+ { value: ROBY_SLUG, label: `${persona} (super-agent)` },
40
42
  ...agentList.map((a) => ({ value: a.slug, label: a.slug })),
41
43
  ],
42
- [agentList],
44
+ [agentList, persona],
43
45
  );
44
46
  const activeAgent = useMemo(
45
47
  () => agentList.find((a) => a.slug === activeSlug) || agentList[0],
@@ -75,10 +77,11 @@ export function ChatTab({ pid }: { pid: string }) {
75
77
 
76
78
  if (agents.isLoading) return <Loading />;
77
79
 
78
- // Header subtitle differs: with Roby selected the chat goes through the
79
- // super-agent (it CAN call tools); a project agent is a direct LLM call.
80
+ // Header subtitle differs: with the super-agent selected the chat goes
81
+ // through the super-agent loop (it CAN call tools); a project agent is a
82
+ // direct LLM call.
80
83
  const headerSubtitle = activeIsRoby
81
- ? t("project.chat.roby_subtitle")
84
+ ? t("project.chat.superagent_subtitle", { persona })
82
85
  : t("project.chat.subtitle");
83
86
 
84
87
  return (
@@ -86,7 +89,7 @@ export function ChatTab({ pid }: { pid: string }) {
86
89
  <header className="flex shrink-0 items-center justify-between gap-3 border-b border-border px-4 py-3">
87
90
  <div className="min-w-0">
88
91
  <h2 className="text-sm font-semibold">
89
- {activeIsRoby ? t("project.chat.roby_title") : t("project.chat.title")}
92
+ {activeIsRoby ? t("project.chat.superagent_title", { persona }) : t("project.chat.title")}
90
93
  </h2>
91
94
  <p className="truncate text-[11px] text-muted-fg">{headerSubtitle}</p>
92
95
  </div>
@@ -0,0 +1,159 @@
1
+ ---
2
+ name: apc-context
3
+ description: "ALWAYS activate when the project has a .apc/ directory or AGENTS.md file. Do not wait to be asked. Read .apc/ before making any assumption about agents, memory, or project structure. Activate on: .apc/, AGENTS.md, 'which agents', 'list agents', 'agent context', 'who are the agents', any question about agents or memory in this project. IMPORTANT: if .apc/migrate.md exists, open the conversation with a migration offer before answering anything else. If the user declines, delete .apc/migrate.md immediately so it is not shown again."
4
+ homepage: https://github.com/agentprojectcontext/agentprojectcontext
5
+ ---
6
+
7
+ # Agent Project Context
8
+
9
+ This project uses APC. APC stores portable project context in `.apc/` and `AGENTS.md`.
10
+
11
+ APC does not store raw runtime sessions. Sessions, conversations, messages, caches, provider
12
+ threads, and private runtime memory stay in the IDE, CLI, daemon, or user-level store that created
13
+ them.
14
+
15
+ ## FIRST: check for pending migration
16
+
17
+ Before doing anything else, check if `.apc/migrate.md` exists:
18
+
19
+ ```bash
20
+ cat .apc/migrate.md 2>/dev/null
21
+ ```
22
+
23
+ If it exists, open with this offer before answering anything else:
24
+
25
+ > I see this project was initialized with Agent Project Context (APC).
26
+ >
27
+ > I found context files that may need migration:
28
+ > [list files from .apc/migrate.md]
29
+ >
30
+ > I can read them, separate durable project context from runtime/private state, and migrate only
31
+ > what belongs in APC.
32
+ >
33
+ > Want me to start?
34
+
35
+ If the user says no or later, delete `.apc/migrate.md` so the offer is not repeated.
36
+
37
+ ## Migration rule: think, do not copy
38
+
39
+ Read detected files first. Also read `AGENTS.md` if it exists.
40
+
41
+ Classify content:
42
+
43
+ | Content | Action |
44
+ |---|---|
45
+ | Agent definitions: name, model, description | Put in `.apc/agents/<name>.md` and/or `AGENTS.md` |
46
+ | Shared project rules, stack notes, commands, testing policy | Keep in `AGENTS.md` |
47
+ | Reusable instruction blocks | Move to `.apc/skills/<name>.md` |
48
+ | Durable safe facts useful to all contributors | Add to `.apc/agents/<name>/memory.md` only after curation |
49
+ | MCP expectations without secrets | Add to `.apc/mcps.json` |
50
+ | Raw sessions, transcripts, conversations, messages, tool logs | Do not move into `.apc/`; leave with source runtime |
51
+ | Secrets, tokens, credentials, private headers | Do not store in repository |
52
+ | IDE UI settings or personal aliases | Leave in IDE/user config |
53
+ | Instructions to store sessions under `.apc/` | Drop as obsolete |
54
+
55
+ After migration:
56
+
57
+ 1. Update `AGENTS.md` as the root project contract.
58
+ 2. Create or update `.apc/agents/`, `.apc/skills/`, `.apc/mcps.json` as needed.
59
+ 3. Do not create `.apc/**/sessions`, `.apc/messages`, or `.apc/conversations`.
60
+ 4. Delete obsolete source files only when their useful project context was migrated or intentionally dropped.
61
+ 5. Delete `.apc/migrate.md`.
62
+ 6. Summarize what moved, what stayed local, and what was dropped.
63
+
64
+ ## APC structure
65
+
66
+ ```text
67
+ AGENTS.md ← root project contract
68
+ .apc/
69
+ project.json ← project metadata
70
+ .gitignore ← safety guard
71
+ agents/<name>.md ← agent definition
72
+ agents/<name>/memory.md ← optional curated project memory
73
+ skills/<name>.md ← reusable project instructions
74
+ mcps.json ← MCP hints without secrets
75
+ ```
76
+
77
+ Do not store:
78
+
79
+ ```text
80
+ .apc/agents/<name>/sessions/
81
+ .apc/sessions/
82
+ .apc/conversations/
83
+ .apc/messages/
84
+ .apc/cache/
85
+ .apc/tmp/
86
+ .apc/private/
87
+ .apc/secrets/
88
+ ```
89
+
90
+ ## Visibility rules
91
+
92
+ | Data | Visibility | Commit? |
93
+ |---|---|---|
94
+ | Agent definitions, skills, project rules | `stable` / `project` | Yes |
95
+ | Curated safe `memory.md` | `project` | Yes, if team-safe |
96
+ | MCP hints without secrets | `project` | Yes |
97
+ | Sessions, conversations, messages | `local` | No; runtime-owned |
98
+ | Secrets, tokens, `*.secret.json`, `*.env` | `private` | Never |
99
+ | Caches, temp files, databases | `ephemeral` | No |
100
+
101
+ ## Operating rules
102
+
103
+ 1. Read `AGENTS.md` and relevant `.apc/` files before assuming project context.
104
+ 2. Read agent definitions from `.apc/agents/<name>.md` when present.
105
+ 3. Read curated project memory from `.apc/agents/<name>/memory.md` when present.
106
+ 4. Write only durable, safe, curated facts to APC memory.
107
+ 5. Never write raw sessions, transcripts, messages, conversations, or tool logs into `.apc/`.
108
+ 6. Keep secrets out of APC and out of git.
109
+ 7. Treat `.apc/mcps.json` as MCP configuration hints, not as an MCP implementation.
110
+
111
+ ## Normalization
112
+
113
+ If agent formats are broken or use legacy fields (role, skills in YAML), offer to normalize:
114
+
115
+ ```yaml
116
+ ---
117
+ name: agent-name
118
+ model: inherit
119
+ description: Semantic activation trigger
120
+ ---
121
+ ```
122
+
123
+ Identify and fix inconsistencies in `model` (use technical IDs or `inherit`) and ensure `description` is present for semantic activation.
124
+
125
+ ## Sessions
126
+
127
+ Sessions belong to the runtime that created them.
128
+
129
+ Examples:
130
+
131
+ ```text
132
+ Codex runtime storage
133
+ Claude Code runtime storage
134
+ OpenCode runtime storage
135
+ ~/.apx/projects/<project-id>/agents/<name>/sessions/
136
+ ```
137
+
138
+ At task end, provide the user a concise result. If project memory should be updated, write a short
139
+ sanitized fact to `.apc/agents/<name>/memory.md` only when useful and safe.
140
+
141
+ ## APX
142
+
143
+ Read `.apc/project.json` if present. It may contain an `apx` field:
144
+
145
+ - `"installed"`: APX is available; use `apx` commands when useful.
146
+ - `"declined"`: user chose not to install; do not suggest or run APX.
147
+ - missing or `null`: unknown; do not assume APX is available.
148
+
149
+ If APX is installed, it may manage runtime state outside the repository:
150
+
151
+ ```text
152
+ ~/.apx/projects/<project-id>/
153
+ ```
154
+
155
+ APX can provide a local daemon, MCP management, Telegram bridge, routines, and runtime dispatch
156
+ across Codex, Claude Code, OpenCode, Aider, or direct LLM engines. Those are APX runtime features,
157
+ not APC portable-core requirements.
158
+
159
+ Never use APX to write secrets or raw sessions into `.apc/`.
@@ -1,24 +0,0 @@
1
- export function isShortConfirmation(text) {
2
- return /^(yes|y|si|si dale|dale|ok|okay|confirm|confirmed|go|proceed|do it)\b/i
3
- .test(String(text || "").trim());
4
- }
5
-
6
- export function lastAssistantAskedForConfirmation(messages) {
7
- for (let i = messages.length - 1; i >= 0; i--) {
8
- if (messages[i]?.role !== "assistant") continue;
9
- return /\b(confirm|confirmation|ok|okay|permission|allowed|proceed|do it|dale)\b/i.test(messages[i].content || "");
10
- }
11
- return false;
12
- }
13
-
14
- export function isGhostResponse(text) {
15
- const t = String(text || "").trim();
16
- if (t.length > 200) return false;
17
- return /^(ok|okay|got it|understood|sure|of course|on it|dale|entendido|claro|voy|ya lo hago|dame un (segundo|momento)|un momento|let me|i (will|can|shall)|i'm (going|about)|give me a|ahora lo|enseguida|checking|looking|fetching|working on|stand by|please wait|un seg|dame sec)[\s.,!]*/i
18
- .test(t);
19
- }
20
-
21
- export function looksLikeActionRequest(text) {
22
- const t = String(text || "").trim().toLowerCase();
23
- return /\b(list|show|find|get|fetch|search|run|execute|create|add|make|start|stop|delete|update|send|check|read|write|look|tell me|dame|mostra|busca|ejecuta|crea|agrega|mandá|revisá|corré|borrá|arrancá)\b/.test(t);
24
- }
@@ -1,16 +0,0 @@
1
- # Channel context
2
- Channel: **terminal** (interactive APX sys session) — the same OpenCode-style coding surface as the web Code module, just in the terminal. You can read, search, edit files and run shell commands.
3
-
4
- - CWD: {{cwd}}
5
- - References to "this directory", "this project", "here", "current folder" mean the CWD above — use it as the path argument; do not ask for a path
6
-
7
- Working style — KEEP GOING UNTIL THE TASK IS DONE (build mode):
8
- - You are an autonomous coding agent. Once the user gives a task, complete the WHOLE thing in this turn: chain as many tool calls as needed (read → edit → run → verify), do not stop after one or two steps.
9
- - NEVER stop to ask "do you want me to…?" / "¿confirmás…?" / "should I continue?". You already have permission on this surface — just do it. Only ask if the task is truly ambiguous and you genuinely cannot proceed.
10
- - NEVER announce an action and then end your turn ("now I'll edit the file." → stop). If you say you will do something, immediately call the tool and actually do it in the same turn.
11
- - After each tool result, decide the next concrete step and take it. Keep iterating until the request is fully satisfied; only then write your final summary.
12
- - If something fails, read the error, fix it, and retry — don't hand the problem back to the user.
13
-
14
- Formatting:
15
- - Markdown OK; keep readable; use code diffs when editing.
16
- - Lead with the result; keep prose tight. Don't re-paste full tool output the user can already see.