@agentprojectcontext/apx 1.33.1 → 1.35.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 (208) hide show
  1. package/package.json +1 -1
  2. package/skills/apx/SKILL.md +49 -61
  3. package/src/core/agent/a2a/reply.js +48 -0
  4. package/src/core/agent/build-agent-system.js +136 -59
  5. package/src/core/agent/channels/voice-context.js +98 -0
  6. package/src/core/agent/memory.js +2 -1
  7. package/src/core/agent/prompt-builder.js +178 -124
  8. package/src/core/agent/prompts/channels/code.md +12 -10
  9. package/src/core/agent/prompts/channels/desktop.md +5 -32
  10. package/src/core/agent/prompts/channels/telegram.md +4 -15
  11. package/src/core/agent/prompts/channels/web_code.md +11 -11
  12. package/src/core/agent/prompts/core/agent-base.md +24 -0
  13. package/src/core/agent/prompts/core/project-agent.md +11 -0
  14. package/src/core/agent/prompts/core/super-agent.md +21 -0
  15. package/src/core/agent/prompts/discipline/action.md +10 -0
  16. package/src/core/agent/prompts/discipline/single-segment.md +6 -0
  17. package/src/core/agent/prompts/discipline/two-segment.md +11 -0
  18. package/src/core/agent/prompts/modes/code-build.md +1 -0
  19. package/src/core/agent/prompts/modes/code-plan.md +1 -0
  20. package/src/core/agent/prompts/modes/index.js +28 -0
  21. package/src/core/agent/self-memory.js +43 -1
  22. package/src/core/agent/skills/index-store.js +307 -0
  23. package/src/core/agent/skills/index.js +15 -1
  24. package/src/core/agent/skills/inspector.js +317 -0
  25. package/src/core/agent/skills/loader.js +22 -18
  26. package/src/core/agent/stream/turn-accumulator.js +73 -0
  27. package/src/core/agent/suggestions.js +37 -0
  28. package/src/core/agent/super-agent.js +7 -1
  29. package/src/core/agent/tools/handlers/_git.js +50 -0
  30. package/src/core/agent/tools/handlers/add-project.js +5 -2
  31. package/src/core/agent/tools/handlers/call-runtime.js +3 -2
  32. package/src/core/agent/tools/handlers/git-diff.js +44 -0
  33. package/src/core/agent/tools/handlers/git-log.js +38 -0
  34. package/src/core/agent/tools/handlers/git-show.js +34 -0
  35. package/src/core/agent/tools/handlers/git-status.js +61 -0
  36. package/src/core/agent/tools/handlers/transcribe-audio.js +1 -1
  37. package/src/core/agent/tools/helpers.js +2 -2
  38. package/src/core/agent/tools/names.js +169 -0
  39. package/src/core/agent/tools/registry-bridge.js +6 -14
  40. package/src/core/agent/tools/registry.js +103 -69
  41. package/src/core/apc/context-copy.js +27 -0
  42. package/src/core/apc/notes.js +19 -0
  43. package/src/core/apc/parser.js +12 -5
  44. package/src/core/apc/paths.js +87 -0
  45. package/src/core/apc/scaffold.js +82 -76
  46. package/src/core/apc/skill-sync.js +10 -0
  47. package/src/{host/daemon/plugins → core/channels}/telegram/dispatch.js +38 -16
  48. package/src/core/config/index.js +24 -2
  49. package/src/core/config/redact.js +95 -0
  50. package/src/core/constants/channels.js +2 -0
  51. package/src/core/constants/code-modes.js +10 -0
  52. package/src/core/constants/index.js +1 -0
  53. package/src/core/deck/manifest.js +186 -0
  54. package/src/core/engines/catalog.js +83 -0
  55. package/src/core/{tools → http-tools}/browser.js +0 -1
  56. package/src/core/{tools → http-tools}/fetch.js +0 -1
  57. package/src/core/{tools → http-tools}/glob.js +0 -1
  58. package/src/core/{tools → http-tools}/grep.js +0 -1
  59. package/src/core/{tools → http-tools}/registry.js +0 -1
  60. package/src/core/{tools → http-tools}/search.js +0 -1
  61. package/src/core/i18n/en.js +9 -0
  62. package/src/core/i18n/es.js +12 -0
  63. package/src/core/i18n/index.js +54 -0
  64. package/src/core/i18n/pt.js +9 -0
  65. package/src/core/identity/telegram.js +2 -1
  66. package/src/core/mcp/runner.js +272 -14
  67. package/src/core/mcp/sources.js +3 -2
  68. package/src/core/routines/index.js +16 -0
  69. package/src/{host/daemon/routines.js → core/routines/runner.js} +36 -103
  70. package/src/core/runtime-skills/apc-context/SKILL.md +159 -0
  71. package/src/core/runtime-skills/apx/SKILL.md +83 -0
  72. package/src/core/runtime-skills/apx-agency-agents/SKILL.md +125 -0
  73. package/src/core/runtime-skills/apx-agent/SKILL.md +97 -0
  74. package/src/core/runtime-skills/apx-mcp/SKILL.md +111 -0
  75. package/src/core/runtime-skills/apx-mcp-builder/SKILL.md +169 -0
  76. package/{skills → src/core/runtime-skills}/apx-project/SKILL.md +20 -29
  77. package/src/core/runtime-skills/apx-routine/SKILL.md +127 -0
  78. package/src/core/runtime-skills/apx-runtime/SKILL.md +99 -0
  79. package/src/core/runtime-skills/apx-sessions/SKILL.md +232 -0
  80. package/src/core/runtime-skills/apx-skill-builder/SKILL.md +129 -0
  81. package/{skills → src/core/runtime-skills}/apx-task/SKILL.md +18 -21
  82. package/src/core/runtime-skills/apx-telegram/SKILL.md +120 -0
  83. package/src/core/runtime-skills/apx-voice/SKILL.md +117 -0
  84. package/src/core/runtime-skills/{claude-code.md → claude-code/SKILL.md} +1 -0
  85. package/src/core/runtime-skills/{codex-cli.md → codex-cli/SKILL.md} +1 -0
  86. package/src/core/runtime-skills/{opencode-cli.md → opencode-cli/SKILL.md} +1 -0
  87. package/src/core/runtime-skills/{openrouter.md → openrouter/SKILL.md} +1 -0
  88. package/src/{host/daemon/env-detect.js → core/runtimes/detect.js} +1 -1
  89. package/src/core/stores/code-sessions.js +50 -2
  90. package/src/core/stores/routine-memory.js +1 -1
  91. package/src/core/stores/sessions-search.js +121 -0
  92. package/src/core/stores/sessions.js +38 -0
  93. package/src/core/vars/index.js +14 -0
  94. package/src/core/vars/interpolate.js +86 -0
  95. package/src/core/vars/sources.js +151 -0
  96. package/src/core/voice/audio-decode.js +38 -0
  97. package/src/core/voice/transcription.js +225 -0
  98. package/src/host/daemon/api/admin-config.js +5 -82
  99. package/src/host/daemon/api/agents.js +5 -5
  100. package/src/host/daemon/api/code.js +17 -169
  101. package/src/host/daemon/api/config.js +3 -4
  102. package/src/host/daemon/api/conversations.js +8 -29
  103. package/src/host/daemon/api/deck.js +37 -404
  104. package/src/host/daemon/api/engines.js +1 -80
  105. package/src/host/daemon/api/exec.js +1 -1
  106. package/src/host/daemon/api/mcps.js +32 -0
  107. package/src/host/daemon/api/routines.js +1 -1
  108. package/src/host/daemon/api/runtimes.js +4 -3
  109. package/src/host/daemon/api/sessions-search.js +24 -140
  110. package/src/host/daemon/api/sessions.js +12 -30
  111. package/src/host/daemon/api/shared.js +2 -1
  112. package/src/host/daemon/api/skills.js +140 -6
  113. package/src/host/daemon/api/super-agent.js +56 -1
  114. package/src/host/daemon/api/telegram.js +1 -11
  115. package/src/host/daemon/api/tools.js +6 -6
  116. package/src/host/daemon/api/transcribe.js +2 -2
  117. package/src/host/daemon/api/vars.js +137 -0
  118. package/src/host/daemon/api/voice.js +13 -290
  119. package/src/host/daemon/api.js +2 -0
  120. package/src/host/daemon/db.js +6 -6
  121. package/src/host/daemon/deck-exec.js +148 -0
  122. package/src/host/daemon/index.js +20 -3
  123. package/src/host/daemon/plugins/telegram/index.js +9 -9
  124. package/src/host/daemon/routines-scheduler.js +64 -0
  125. package/src/host/daemon/smoke.js +3 -2
  126. package/src/host/daemon/whisper-server.js +225 -0
  127. package/src/interfaces/cli/branding.js +53 -0
  128. package/src/interfaces/cli/commands/agent.js +3 -2
  129. package/src/interfaces/cli/commands/command.js +2 -3
  130. package/src/interfaces/cli/commands/messages.js +6 -2
  131. package/src/interfaces/cli/commands/pair.js +5 -4
  132. package/src/interfaces/cli/commands/search.js +1 -1
  133. package/src/interfaces/cli/commands/sessions.js +3 -2
  134. package/src/interfaces/cli/commands/skills.js +290 -55
  135. package/src/interfaces/cli/index.js +84 -2
  136. package/src/interfaces/web/dist/assets/index-C0fm31dY.js +618 -0
  137. package/src/interfaces/web/dist/assets/index-C0fm31dY.js.map +1 -0
  138. package/src/interfaces/web/dist/assets/index-UcAqlBO6.css +1 -0
  139. package/src/interfaces/web/dist/index.html +2 -2
  140. package/src/interfaces/web/package-lock.json +182 -182
  141. package/src/interfaces/web/src/components/ModelCombobox.tsx +2 -1
  142. package/src/interfaces/web/src/components/TelegramChannelDialog.tsx +1 -1
  143. package/src/interfaces/web/src/components/chat/AskAnswersCard.tsx +76 -0
  144. package/src/interfaces/web/src/components/chat/MessageBubble.tsx +37 -4
  145. package/src/interfaces/web/src/components/chat/MessageList.tsx +23 -1
  146. package/src/interfaces/web/src/components/chat/ModelPicker.tsx +3 -1
  147. package/src/interfaces/web/src/components/code/CodeArtifactsTab.tsx +4 -4
  148. package/src/interfaces/web/src/components/code/CodeChangesTab.tsx +1 -1
  149. package/src/interfaces/web/src/components/code/CodeFileTree.tsx +3 -2
  150. package/src/interfaces/web/src/components/code/CodeFileViewer.tsx +3 -2
  151. package/src/interfaces/web/src/components/code/CodeTerminal.tsx +3 -2
  152. package/src/interfaces/web/src/components/config/GlobalConfigEditor.tsx +2 -1
  153. package/src/interfaces/web/src/components/deck/WidgetRow.tsx +2 -1
  154. package/src/interfaces/web/src/components/inputs/KeyValueList.tsx +93 -0
  155. package/src/interfaces/web/src/components/inputs/VarTokenInput.tsx +449 -0
  156. package/src/interfaces/web/src/components/settings/DefaultRouterCard.tsx +2 -1
  157. package/src/interfaces/web/src/components/settings/EnginesPanel.tsx +2 -2
  158. package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +73 -4
  159. package/src/interfaces/web/src/components/settings/SkillsInspectorPanel.tsx +222 -0
  160. package/src/interfaces/web/src/components/settings/providers/ProviderCard.tsx +3 -2
  161. package/src/interfaces/web/src/components/settings/providers/ProviderModal.tsx +3 -2
  162. package/src/interfaces/web/src/components/ui/chat-input.tsx +5 -4
  163. package/src/interfaces/web/src/components/ui/sidebar.tsx +3 -2
  164. package/src/interfaces/web/src/components/voice/VoiceProviderModal.tsx +2 -1
  165. package/src/interfaces/web/src/constants/index.ts +1 -1
  166. package/src/interfaces/web/src/hooks/useChat.ts +19 -0
  167. package/src/interfaces/web/src/i18n/en.ts +175 -7
  168. package/src/interfaces/web/src/i18n/es.ts +180 -15
  169. package/src/interfaces/web/src/lib/api/mcps.ts +25 -0
  170. package/src/interfaces/web/src/lib/api/skills.ts +70 -0
  171. package/src/interfaces/web/src/lib/api/vars.ts +38 -0
  172. package/src/interfaces/web/src/lib/api.ts +1 -0
  173. package/src/interfaces/web/src/screens/ProjectScreen.tsx +8 -31
  174. package/src/interfaces/web/src/screens/SettingsScreen.tsx +6 -2
  175. package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +1 -1
  176. package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +4 -3
  177. package/src/interfaces/web/src/screens/modules/DesktopScreen.tsx +7 -6
  178. package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +4 -3
  179. package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +1 -1
  180. package/src/interfaces/web/src/screens/project/ConfigTab.tsx +132 -1
  181. package/src/interfaces/web/src/screens/project/McpsTab.tsx +549 -104
  182. package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +1 -1
  183. package/src/interfaces/web/src/screens/project/VarsTab.tsx +300 -0
  184. package/src/interfaces/web/src/types/daemon.ts +15 -0
  185. package/skills/apx-agency-agents/SKILL.md +0 -141
  186. package/skills/apx-agent/SKILL.md +0 -100
  187. package/skills/apx-mcp-builder/SKILL.md +0 -183
  188. package/skills/apx-routine/SKILL.md +0 -140
  189. package/skills/apx-runtime/SKILL.md +0 -117
  190. package/skills/apx-sessions/SKILL.md +0 -281
  191. package/skills/apx-skill-builder/SKILL.md +0 -153
  192. package/skills/apx-telegram/SKILL.md +0 -131
  193. package/skills/apx-voice/SKILL.md +0 -137
  194. package/src/core/agent/prompts/action-discipline.md +0 -24
  195. package/src/core/agent/prompts/super-agent-base.md +0 -42
  196. package/src/host/daemon/transcription.js +0 -538
  197. package/src/host/daemon/whisper-transcribe.py +0 -73
  198. package/src/interfaces/web/dist/assets/index-Aaiw8BZN.css +0 -1
  199. package/src/interfaces/web/dist/assets/index-DPqtjDjh.js +0 -602
  200. package/src/interfaces/web/dist/assets/index-DPqtjDjh.js.map +0 -1
  201. /package/src/{host/daemon → core/apc}/projects-helpers.js +0 -0
  202. /package/src/{host/daemon/plugins → core/channels}/telegram/ask.js +0 -0
  203. /package/src/{host/daemon/plugins → core/channels}/telegram/helpers.js +0 -0
  204. /package/src/{host/daemon/plugins → core/channels}/telegram/media.js +0 -0
  205. /package/src/core/{tools → http-tools}/index.js +0 -0
  206. /package/src/{host/daemon/compact.js → core/stores/conversations-compactor.js} +0 -0
  207. /package/src/{host/daemon → core/stores}/conversations.js +0 -0
  208. /package/src/{host/daemon → core/util}/thinking.js +0 -0
@@ -50,7 +50,7 @@ const SCHED_PRESETS = [
50
50
  { label: "días hábiles 9am", value: "cron 0 9 * * 1-5" },
51
51
  ];
52
52
 
53
- // Template/env vars the routine runner exposes (src/host/daemon/routines.js).
53
+ // Template/env vars the routine runner exposes (src/core/routines/runner.js).
54
54
  const VARS = [
55
55
  { v: "{{pre_output}}", where: "prompt", desc: "Salida de los pre-commands, inyectada en el prompt." },
56
56
  { v: "$APX_LLM_OUTPUT", where: "post", desc: "Respuesta del agente / super-agente." },
@@ -0,0 +1,300 @@
1
+ import { useEffect, useMemo, useState } from "react";
2
+ import useSWR from "swr";
3
+ import { Eye, EyeOff, Pencil, Plus, Trash2 } from "lucide-react";
4
+ import { Vars, type VarScope, type VarsList } from "../../lib/api";
5
+ import { Section } from "../../components/Section";
6
+ import { Badge, Button, Dialog, Empty, Field, Input, Loading, Switch } from "../../components/ui";
7
+ import { UiSelect } from "../../components/UiSelect";
8
+ import { useToast } from "../../components/Toast";
9
+ import { t } from "../../i18n";
10
+
11
+ interface Row {
12
+ name: string;
13
+ scope: VarScope;
14
+ masked: string;
15
+ revealed?: string;
16
+ }
17
+
18
+ export function VarsTab({ pid }: { pid: string }) {
19
+ const toast = useToast();
20
+ const isBase = String(pid) === "0";
21
+ const [filter, setFilter] = useState<"all" | "project" | "global">(
22
+ isBase ? "global" : "all",
23
+ );
24
+ const [revealAll, setRevealAll] = useState(false);
25
+ const list = useSWR<VarsList>(
26
+ `/projects/${pid}/vars?reveal=${revealAll ? 1 : 0}`,
27
+ () => Vars.list(pid, { reveal: revealAll }),
28
+ );
29
+ const [openCreate, setOpenCreate] = useState<{ name?: string; value?: string; scope?: VarScope } | null>(null);
30
+
31
+ const rows: Row[] = useMemo(() => {
32
+ if (!list.data) return [];
33
+ const out: Row[] = [];
34
+ const proj = list.data.project || {};
35
+ const glob = list.data.global || {};
36
+ for (const [name, masked] of Object.entries(proj)) {
37
+ out.push({ name, scope: "project", masked });
38
+ }
39
+ for (const [name, masked] of Object.entries(glob)) {
40
+ if (proj[name] !== undefined) continue;
41
+ out.push({ name, scope: "global", masked });
42
+ }
43
+ return out
44
+ .filter((r) => (filter === "all" ? true : r.scope === filter))
45
+ .sort((a, b) => a.name.localeCompare(b.name));
46
+ }, [list.data, filter]);
47
+
48
+ const remove = async (name: string, scope: VarScope) => {
49
+ if (!confirm(t("project.vars.delete_confirm", { name, scope }))) return;
50
+ try {
51
+ await Vars.remove(pid, name, scope);
52
+ toast.success(t("project.vars.removed"));
53
+ list.mutate();
54
+ } catch (e: any) {
55
+ toast.error(e?.message || t("common.error_generic"));
56
+ }
57
+ };
58
+
59
+ return (
60
+ <Section
61
+ title={t("project.vars.title")}
62
+ description={
63
+ isBase ? t("project.vars.subtitle_base") : t("project.vars.subtitle_project")
64
+ }
65
+ action={
66
+ <div className="flex items-center gap-2">
67
+ <Switch checked={revealAll} onChange={setRevealAll} label={t("project.vars.reveal_all")} />
68
+ <Button size="sm" variant="primary" onClick={() => setOpenCreate({})}>
69
+ <Plus size={14} /> {t("project.vars.new")}
70
+ </Button>
71
+ </div>
72
+ }
73
+ >
74
+ {!isBase && (
75
+ <div className="mb-3 flex items-center gap-2 text-xs">
76
+ <span className="text-muted-fg">{t("project.vars.filter_label")}</span>
77
+ <FilterPill active={filter === "all"} onClick={() => setFilter("all")}>
78
+ {t("project.vars.filter_all")}
79
+ </FilterPill>
80
+ <FilterPill active={filter === "project"} onClick={() => setFilter("project")}>
81
+ {t("project.vars.filter_project")}
82
+ </FilterPill>
83
+ <FilterPill active={filter === "global"} onClick={() => setFilter("global")}>
84
+ {t("project.vars.filter_global")}
85
+ </FilterPill>
86
+ </div>
87
+ )}
88
+
89
+ {list.isLoading && <Loading />}
90
+ {!list.isLoading && rows.length === 0 && <Empty>{t("project.vars.empty")}</Empty>}
91
+
92
+ {rows.length > 0 && (
93
+ <ul className="space-y-2 text-sm">
94
+ {rows.map((r) => (
95
+ <li
96
+ key={`${r.scope}-${r.name}`}
97
+ className="flex items-center gap-3 rounded-md border border-border bg-muted/30 px-3 py-2"
98
+ >
99
+ <span className="font-mono text-xs font-medium">{r.name}</span>
100
+ <Badge tone={r.scope === "project" ? "info" : "muted"}>
101
+ {r.scope === "project" ? t("project.vars.scope_project") : t("project.vars.scope_global")}
102
+ </Badge>
103
+ <span className="ml-2 font-mono text-xs text-muted-fg">{r.masked}</span>
104
+ <div className="ml-auto flex items-center gap-1">
105
+ {/* Edit: only project-scope rows can be edited from a non-base project.
106
+ Global rows can be edited from /p/0. We surface "edit globally" by
107
+ pre-filling the dialog with scope=global; the user can switch. */}
108
+ <Button
109
+ size="sm"
110
+ variant="ghost"
111
+ onClick={() => setOpenCreate({ name: r.name, scope: r.scope })}
112
+ aria-label={t("project.vars.edit_btn")}
113
+ >
114
+ <Pencil size={13} />
115
+ </Button>
116
+ {!(isBase && r.scope === "project") && (
117
+ <Button
118
+ size="sm"
119
+ variant="destructive"
120
+ onClick={() => remove(r.name, r.scope)}
121
+ aria-label={t("project.vars.delete_btn")}
122
+ >
123
+ <Trash2 size={13} />
124
+ </Button>
125
+ )}
126
+ </div>
127
+ </li>
128
+ ))}
129
+ </ul>
130
+ )}
131
+
132
+ <UpsertVarDialog
133
+ open={openCreate !== null}
134
+ initial={openCreate || undefined}
135
+ onClose={() => setOpenCreate(null)}
136
+ pid={pid}
137
+ isBase={isBase}
138
+ onSaved={() => {
139
+ setOpenCreate(null);
140
+ list.mutate();
141
+ }}
142
+ />
143
+ </Section>
144
+ );
145
+ }
146
+
147
+ function FilterPill({
148
+ active,
149
+ onClick,
150
+ children,
151
+ }: {
152
+ active: boolean;
153
+ onClick: () => void;
154
+ children: React.ReactNode;
155
+ }) {
156
+ return (
157
+ <button
158
+ type="button"
159
+ onClick={onClick}
160
+ className={
161
+ active
162
+ ? "rounded-full border border-primary/50 bg-primary/10 px-2 py-0.5 text-xs"
163
+ : "rounded-full border border-border bg-muted/30 px-2 py-0.5 text-xs hover:bg-muted/60"
164
+ }
165
+ >
166
+ {children}
167
+ </button>
168
+ );
169
+ }
170
+
171
+ function UpsertVarDialog({
172
+ open,
173
+ onClose,
174
+ pid,
175
+ isBase,
176
+ initial,
177
+ onSaved,
178
+ }: {
179
+ open: boolean;
180
+ onClose: () => void;
181
+ pid: string;
182
+ isBase: boolean;
183
+ initial?: { name?: string; value?: string; scope?: VarScope };
184
+ onSaved: () => void;
185
+ }) {
186
+ const toast = useToast();
187
+ const [busy, setBusy] = useState(false);
188
+ const [revealValue, setRevealValue] = useState(false);
189
+ const [name, setName] = useState(initial?.name || "");
190
+ const [value, setValue] = useState(initial?.value || "");
191
+ const [scope, setScope] = useState<VarScope>(
192
+ initial?.scope || (isBase ? "global" : "project"),
193
+ );
194
+ const isEdit = !!initial?.name;
195
+
196
+ // Reset state when the dialog opens with a different initial.
197
+ useEffect(() => {
198
+ if (open) {
199
+ setName(initial?.name || "");
200
+ setValue(initial?.value || "");
201
+ setScope(initial?.scope || (isBase ? "global" : "project"));
202
+ setRevealValue(false);
203
+ }
204
+ }, [open, initial?.name, initial?.scope, initial?.value, isBase]);
205
+
206
+ const submit = async () => {
207
+ if (!name.trim()) {
208
+ toast.error(t("project.vars.name_required"));
209
+ return;
210
+ }
211
+ if (!value) {
212
+ toast.error(t("project.vars.value_required"));
213
+ return;
214
+ }
215
+ setBusy(true);
216
+ try {
217
+ await Vars.upsert(pid, { name: name.trim(), value, scope });
218
+ toast.success(isEdit ? t("project.vars.updated") : t("project.vars.added"));
219
+ onSaved();
220
+ } catch (e: any) {
221
+ toast.error(e?.message || t("common.error_generic"));
222
+ } finally {
223
+ setBusy(false);
224
+ }
225
+ };
226
+
227
+ return (
228
+ <Dialog
229
+ open={open}
230
+ onClose={() => (busy ? null : onClose())}
231
+ title={isEdit ? t("project.vars.edit_title") : t("project.vars.new_title")}
232
+ description={t("project.vars.new_desc")}
233
+ size="sm"
234
+ footer={
235
+ <>
236
+ <Button variant="ghost" onClick={onClose} disabled={busy}>
237
+ {t("common.cancel")}
238
+ </Button>
239
+ <Button variant="primary" onClick={submit} loading={busy}>
240
+ {isEdit ? t("project.vars.save_btn") : t("project.vars.add_btn")}
241
+ </Button>
242
+ </>
243
+ }
244
+ >
245
+ <div className="space-y-3">
246
+ <Field label={t("project.vars.scope_label")}>
247
+ <UiSelect
248
+ value={scope}
249
+ onChange={(v) => setScope(v as VarScope)}
250
+ options={[
251
+ ...(isBase
252
+ ? []
253
+ : [
254
+ {
255
+ value: "project",
256
+ label: t("project.vars.scope_project"),
257
+ description: t("project.vars.scope_project_desc"),
258
+ },
259
+ ]),
260
+ {
261
+ value: "global",
262
+ label: t("project.vars.scope_global"),
263
+ description: t("project.vars.scope_global_desc"),
264
+ },
265
+ ]}
266
+ />
267
+ </Field>
268
+ <Field label={t("project.vars.name_label")} hint={t("project.vars.name_hint")}>
269
+ <Input
270
+ value={name}
271
+ onChange={(e) => setName(e.target.value.toUpperCase().replace(/[^A-Z0-9_]/g, "_"))}
272
+ placeholder="MY_API_KEY"
273
+ disabled={isEdit}
274
+ autoFocus={!isEdit}
275
+ />
276
+ </Field>
277
+ <Field label={t("project.vars.value_label")} hint={t("project.vars.value_hint")}>
278
+ <div className="relative">
279
+ <Input
280
+ type={revealValue ? "text" : "password"}
281
+ value={value}
282
+ onChange={(e) => setValue(e.target.value)}
283
+ placeholder={isEdit ? t("project.vars.value_edit_ph") : ""}
284
+ className="pr-9 font-mono text-xs"
285
+ autoFocus={isEdit}
286
+ />
287
+ <button
288
+ type="button"
289
+ onClick={() => setRevealValue((v) => !v)}
290
+ className="absolute right-2 top-1/2 -translate-y-1/2 text-muted-fg hover:text-fg"
291
+ aria-label={revealValue ? t("project.vars.hide") : t("project.vars.reveal")}
292
+ >
293
+ {revealValue ? <EyeOff size={14} /> : <Eye size={14} />}
294
+ </button>
295
+ </div>
296
+ </Field>
297
+ </div>
298
+ </Dialog>
299
+ );
300
+ }
@@ -70,6 +70,11 @@ export interface McpEntry {
70
70
  source: "apc" | "runtime" | "global" | string;
71
71
  transport: string;
72
72
  enabled: boolean;
73
+ command?: string | null;
74
+ args?: string[];
75
+ env?: Record<string, string>;
76
+ url?: string | null;
77
+ headers?: Record<string, string>;
73
78
  }
74
79
 
75
80
  export interface MessageEntry {
@@ -279,6 +284,16 @@ export interface ChatStreamEvent {
279
284
  streak?: number;
280
285
  // tool_start / tool_result / tool_deduped
281
286
  trace?: ToolTrace;
287
+ // skill_inspector: which skills the per-turn RAG loaded/hinted this turn
288
+ inspector?: {
289
+ enabled?: boolean;
290
+ reason?: string;
291
+ embedder?: string;
292
+ scored?: { slug: string; sim: number }[];
293
+ loaded?: string[];
294
+ hinted?: string[];
295
+ jit?: boolean;
296
+ };
282
297
  // final
283
298
  result?: {
284
299
  text?: string;
@@ -1,141 +0,0 @@
1
- ---
2
- name: apx-agency-agents
3
- description: "Manage the APX agent vault — reusable agent templates (Roby, Cody, Rocky, Tessa, Max, Arch, Sid, Vera, Finn + generic dev/marketing/ops/qa/support). Load to spawn a specialist, list templates, import one into a project, create a template, or hide/restore a bundled default. Triggers: 'spawn agent', 'use Cody/Rocky/Tessa', 'list agents', 'agent vault', 'import agent', 'new agent'."
4
- ---
5
-
6
- # apx-agency-agents — the APX agent vault
7
-
8
- The vault is the **global, project-agnostic library of agent templates** in APX. Two layers, deduped per-slug, with the user layer winning:
9
-
10
- | Layer | Where | Mutability |
11
- |---|---|---|
12
- | **Bundled** | `<repo>/assets/agent-vault-defaults/<slug>.md` | Read-only on disk. Always visible unless tombstoned. |
13
- | **User** | `~/.apx/agents/<slug>.md` | Read-write. Overrides the bundled with the same slug. |
14
- | **Tombstones** | `~/.apx/agents/.removed.json` | List of bundled slugs the user explicitly hid. |
15
-
16
- Listing returns `bundled ∪ user`, with `source: "bundled" | "user" | "user-override"` per entry. Editing a bundled entry is **copy-on-write** — it materializes into the user layer the moment you save. Deleting a bundled entry **tombstones** it (you can restore later); deleting a user-only entry physically removes the file.
17
-
18
- ## Bundled starter pack
19
-
20
- APX ships 14 templates out of the box, two families:
21
-
22
- ### Named team (from nicho-apps)
23
- A characterful crew already used in production by NichoApps:
24
-
25
- | Slug | Role | Strength |
26
- |---|---|---|
27
- | `roby-orchestrator` | Pipeline orchestrator | Autonomous task routing, multi-agent coordination |
28
- | `arch-architect` | Software architect | System design, tradeoffs, ADRs |
29
- | `cody-developer` | Senior Laravel dev | Code, refactors, technical leadership |
30
- | `tessa-qa` | QA / beta tester | Reality checks, test plans, real-user empathy |
31
- | `max-marketing` | Growth hacker | Content, campaigns, SEO, copy |
32
- | `sid-security` | Security specialist | Audits, threat models, hardening |
33
- | `rocky-pm` | Senior PM | Tasklists, roadmaps, stakeholder comms |
34
- | `vera-ui` | UI/UX reviewer | Visual audits, usability (uses browser-use) |
35
- | `finn-billing` | Billing / commercial ops | Stripe, invoicing, plan logic |
36
-
37
- ### Generic specialists (from PandaProject)
38
- Plain functional roles — useful when you want capabilities without a persona:
39
-
40
- | Slug | Role |
41
- |---|---|
42
- | `development` | Engineering & code |
43
- | `marketing` | Marketing & growth |
44
- | `ops` | Ops, deploys & incidents |
45
- | `qa` | Quality assurance & testing |
46
- | `support` | Customer support & escalations |
47
-
48
- Bundled templates ship with `language: es` and **no `model:` set** — they inherit the project/global default model. Set a model on import or by editing the vault file directly.
49
-
50
- ## Concrete commands
51
-
52
- ```bash
53
- # List the vault (bundled + your overrides, with [bundled] / [user] / [override] tags)
54
- apx agent vault list
55
-
56
- # Include tombstoned bundled defaults (the ones you hid)
57
- apx agent vault list --all
58
-
59
- # Create a new template (writes ~/.apx/agents/<slug>.md)
60
- apx agent vault add reviewer \
61
- --role "Code reviewer" \
62
- --model ollama:llama3.2:3b \
63
- --language es \
64
- --skills code-review,git \
65
- --description "Reviews PRs and pushes back on hand-wavy diffs."
66
-
67
- # Delete a template:
68
- # - user-only slug → file is physically deleted
69
- # - bundled slug → tombstoned, hidden from listings
70
- apx agent vault rm tessa-qa
71
-
72
- # Bring back a tombstoned bundled default
73
- apx agent vault restore tessa-qa
74
-
75
- # Import a vault template into the current project
76
- apx agent import cody-developer
77
- apx agent import tessa-qa --copy # copy into .apc/agents/ for local edits
78
- apx agent import roby-orchestrator --force # overwrite an existing local def
79
-
80
- # Inside the daemon's tool API, the same flow:
81
- list_vault_agents()
82
- import_agent({ slug: "cody-developer", project: "<name-or-path>" })
83
- ```
84
-
85
- ## The web equivalents
86
-
87
- The Agent defaults tab (`/p/0/agent-defaults`) has the same CRUD: a "New" button (POST `/agents/vault`), "Edit" per card (PATCH `/agents/vault/:slug`, copy-on-write for bundled), "Delete"/"Hide" (DELETE), and a "Show removed" toggle that surfaces tombstoned bundled defaults with a "Restore" button.
88
-
89
- ## When to use which agent
90
-
91
- - **User says "spawn/use Cody/Rocky/Tessa/Max/Arch/Sid/Vera/Roby/Finn"** → that exact slug exists in the named team. Import it.
92
- - **User wants a "developer" / "QA" / "marketing" agent without a persona** → use the generic specialists (`development`, `qa`, `marketing`, …).
93
- - **User wants something not in the vault** → either `apx agent vault add <slug>` to create a blank one, or `apx agent add <slug>` directly inside a project for a one-off.
94
- - **Fresh install** → bundled defaults are always present (no sync step); they appear in `apx agent vault list` immediately.
95
-
96
- ## Where the files live
97
-
98
- ```
99
- <APX repo>/assets/agent-vault-defaults/<slug>.md ← canonical bundle (committed)
100
- ~/.apx/agents/<slug>.md ← user vault (sync target)
101
- <project>/.apc/agents/<slug>.md ← project-local copy (after import --copy)
102
- ```
103
-
104
- The vault file format is identical to a project agent file:
105
-
106
- ```
107
- ---
108
- role: <human-readable role>
109
- model: <provider:model>
110
- description: <short description shown in UI grid>
111
- language: es
112
- skills: a, b, c
113
- tools: x, y
114
- is_master: false
115
- ---
116
-
117
- <markdown body — the agent's system prompt extension>
118
- ```
119
-
120
- ## Frontmatter fields the runtime reads
121
-
122
- | Field | Effect |
123
- |---|---|
124
- | `role` | Shown in CLI/web. Appears in the agent's prompt as "Role: …". |
125
- | `model` | Default model for engine routing. |
126
- | `description` | Shown in `/agents/vault` and the AgentDefaultsTab cards. |
127
- | `language` | Adds "Default language: <code>" to the system prompt. |
128
- | `skills` | Per-agent skill names; relevant skill bodies are loaded by skill resolution. |
129
- | `tools` | Declared tool hints; actual callable tools depend on the invocation surface. |
130
- | `is_master` | If true, marked as a master agent in the project (badge + ordering). |
131
-
132
- ## Related skills
133
-
134
- - **[apx-agent](../apx-agent/SKILL.md)** — per-project agent CRUD (add / edit / memory / list). The vault is the *library*; this skill is the *workshop*.
135
- - **[apx-runtime](../apx-runtime/SKILL.md)** — delegating to external coding CLIs (claude-code, codex, etc) from inside an agent.
136
-
137
- ## Gotchas
138
-
139
- - **Bundled defaults are always present** — there's no sync step. They appear in `apx agent vault list` and in the web UI the moment APX is installed. Removing one tombstones it; editing one copies it to your user layer.
140
- - The slug `roby-orchestrator` is intentionally **not** `roby` — the APX super-agent persona is already named "Roby" via `~/.apx/identity.json`. Importing a project agent called `roby` would shadow that and cause confusion. Use `roby-orchestrator` for a *project-level* orchestrator.
141
- - The `agency-agents` skill in `~/.claude/skills/` pulls from an external GitHub repo (`msitarzewski/agency-agents`). APX bundles a snapshot in `assets/agent-vault-defaults/` so installs are offline-first. To refresh from upstream, edit the bundle and re-commit; existing users' overrides are untouched.
@@ -1,100 +0,0 @@
1
- ---
2
- name: apx-agent
3
- description: How to create, configure, and use project agents in APX. Load when the user wants to "add an agent", import from the vault, set a per-agent model, or write agent memory.
4
- ---
5
-
6
- # apx-agent
7
-
8
- A project agent is a named persona inside an APC project. Canonical definition: `.apc/agents/<slug>.md` (flat file). `AGENTS.md` is auto-regenerated for discovery. Per-agent runtime data (memory, conversations, sessions) lives under `~/.apx/projects/<apx_id>/agents/<slug>/` and is never committed. APX still reads legacy `.apc/agents/<slug>/memory.md` as a migration fallback only.
9
-
10
- ## Concrete CLI calls
11
-
12
- ```bash
13
- # List agents in the current project (agent commands are cwd-scoped — run from the project root)
14
- apx agent list
15
-
16
- # Create a new agent (writes .apc/agents/<slug>.md, creates runtime dir, regenerates AGENTS.md)
17
- apx agent add reviewer \
18
- --role "Code reviewer" \
19
- --model ollama:llama3.2:3b \
20
- --language es \
21
- --description "Reviews PRs and pushes back on hand-wavy diffs." \
22
- --tools read,write,run \
23
- --skills code-review,git
24
-
25
- # Import an agent template from the global vault (~/.apx/agents/)
26
- apx agent vault list # see what's available
27
- apx agent import <slug> # register vault slug in this project
28
- apx agent import <slug> --copy # copy vault .md into .apc/agents/ for local edits
29
- apx agent import <slug> --force # overwrite existing local definition
30
-
31
- # Show details (config + memory)
32
- apx agent get <slug> # alias: apx agent show <slug>
33
-
34
- # Per-agent memory (drives system prompt for that agent; cwd-scoped — run from the project root)
35
- apx memory <slug> # read
36
- apx memory <slug> --append "fact" # append a line under "## Recent context"
37
- apx memory <slug> --replace < file.md # full replace from stdin
38
- ```
39
-
40
- ## What the agent's system prompt looks like
41
-
42
- `buildAgentSystem()` (`src/core/agent-system.js`) composes:
43
-
44
- 1. Identity block: `You are <slug>` + project name.
45
- 2. Description (from AGENTS.md).
46
- 3. Role + Language fields.
47
- 4. Invocation context: `engine | telegram | routine | runtime` — the channel calling the agent.
48
- 5. Memory: `~/.apx/projects/<apx_id>/agents/<slug>/memory.md` if it exists, with legacy `.apc/agents/<slug>/memory.md` as a migration fallback.
49
- 6. Skills declared in the agent's `Skills:` field, each loaded from `.apc/skills/<slug>.md` or the bundled set.
50
- 7. The `apx` meta-skill (so the agent knows how to operate APX).
51
- 8. ACTION_DISCIPLINE_RULES (fixed footer — anti-ghost, anti-disclaimer, action-first).
52
-
53
- That's the prompt the engine sees on every `apx exec <agent>` or `apx chat <agent>`. The super-agent (default APX mode) uses a *different* prompt — see `apx-routine` for when the super-agent runs vs. when an exec_agent runs.
54
-
55
- ## Models per agent
56
-
57
- Each agent can set `Model:` in its `.apc/agents/<slug>.md` definition to override the global super-agent model. Leave it empty when the agent should follow the project/global default.
58
-
59
- ```markdown
60
- # .apc/agents/reviewer.md
61
- ---
62
- Role: Code reviewer
63
- Model: ollama:llama3.2:3b ← this agent uses this model, independent of super_agent.model
64
- Language: es
65
- ---
66
- ```
67
-
68
- When a routine `kind: exec_agent` runs with `spec.agent: reviewer`, it uses that model.
69
-
70
- ## Anti-examples
71
-
72
- ```bash
73
- # DON'T hand-write .apc/agents/<slug>.md without matching AGENTS.md regeneration.
74
- echo "..." > /path/.apc/agents/reviewer.md
75
- # ↑ Prefer `apx agent add` or `apx agent import` so AGENTS.md stays consistent.
76
-
77
- # DON'T set Model: to a provider you don't have keys for.
78
- # An agent with Model: openai:gpt-4o on a machine with no openai.api_key fails on first call.
79
-
80
- # DON'T put long-running context in `Description`. Put it in memory.md.
81
- # Description is one line, Role is a noun phrase, memory is unlimited.
82
- ```
83
-
84
- ## How agents differ from the super-agent
85
-
86
- | Aspect | Super-agent (default APX) | Project agent |
87
- |---|---|---|
88
- | Has tools? | Yes (the full registry) | No (text-in/text-out via callEngine) |
89
- | Loop? | Multi-iteration tool loop | Single call |
90
- | System prompt | `super-agent-base.md` + channel template + identity | `buildAgentSystem()` per-agent |
91
- | Conversation persisted in | super-agent surfaces | `<storagePath>/agents/<slug>/conversations/*.md` |
92
- | Configured via | `super_agent.*` in config | `AGENTS.md` + per-agent files |
93
-
94
- When in doubt: the super-agent is APX itself; agents are personas inside a project.
95
-
96
- ## Don't
97
-
98
- - Don't expect a project agent to call tools. It can't. If you want tools, use the super-agent or call MCPs from a routine `kind: shell`.
99
- - Don't overwrite `AGENTS.md` manually — `apx agent add/remove` regenerates it. Hand edits get clobbered.
100
- - Don't use the same slug across projects expecting shared memory. Memory is per-project.