@agentprojectcontext/apx 1.31.2 → 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.
- package/package.json +6 -1
- package/skills/apc-context/SKILL.md +5 -2
- package/skills/apx/SKILL.md +3 -3
- package/skills/apx-agency-agents/SKILL.md +5 -5
- package/skills/apx-agent/SKILL.md +7 -7
- package/skills/apx-mcp/SKILL.md +6 -4
- package/skills/apx-mcp-builder/SKILL.md +4 -7
- package/skills/apx-project/SKILL.md +4 -5
- package/skills/apx-routine/SKILL.md +14 -12
- package/skills/apx-runtime/SKILL.md +5 -3
- package/skills/apx-sessions/SKILL.md +5 -5
- package/skills/apx-skill-builder/SKILL.md +10 -6
- package/skills/apx-task/SKILL.md +8 -8
- package/skills/apx-telegram/SKILL.md +23 -7
- package/skills/apx-voice/SKILL.md +8 -6
- package/src/core/{agent-system.js → agent/build-agent-system.js} +10 -12
- package/src/core/agent/constants.js +5 -0
- package/src/core/agent/index.js +0 -2
- package/src/core/{agent-memory.js → agent/memory.js} +2 -2
- package/src/core/agent/model-router.js +21 -43
- package/src/core/agent/prompt-builder.js +17 -63
- package/src/core/agent/prompts/action-discipline.md +17 -0
- package/src/core/agent/prompts/channels/code.md +8 -12
- package/src/core/agent/prompts/channels/desktop.md +6 -4
- package/src/core/agent/prompts/channels/routine.md +10 -1
- package/src/core/agent/prompts/channels/telegram.md +5 -0
- package/src/core/agent/prompts/channels/web_code.md +20 -0
- package/src/core/agent/prompts/modes/voice.md +2 -2
- package/src/core/agent/prompts/super-agent-base.md +2 -2
- package/src/core/agent/run-agent.js +66 -36
- package/src/core/agent/runtime-bridge.js +42 -0
- package/src/core/agent/self-memory.js +19 -9
- package/src/core/agent/skills/catalog.js +65 -0
- package/src/core/agent/skills/index.js +6 -0
- package/src/{host/daemon/skills-loader.js → core/agent/skills/loader.js} +3 -3
- package/src/core/agent/skills/rag.js +91 -0
- package/src/core/agent/skills/trigger.js +71 -0
- package/src/{host/daemon → core/agent}/super-agent.js +5 -5
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/add-project.js +3 -4
- package/src/core/agent/tools/handlers/ask-questions.js +115 -0
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/call-agent.js +2 -2
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/call-mcp.js +1 -2
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/call-runtime.js +10 -11
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/create-task.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/discover-tools.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/edit-file.js +1 -2
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/import-agent.js +4 -5
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-agents.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-skills.js +7 -2
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-tasks.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-vault-agents.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/load-skill.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/read-agent-memory.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/read-self-memory.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/remember.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/run-shell.js +1 -2
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/search-messages.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/search-sessions.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/send-telegram.js +0 -2
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/set-identity.js +1 -3
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/set-permission-mode.js +1 -3
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/tail-messages.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/transcribe-audio.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/write-file.js +1 -2
- package/src/core/agent/tools/helpers.js +74 -0
- package/src/{host/daemon/super-agent-tools → core/agent/tools}/registry-bridge.js +3 -3
- package/src/{host/daemon/super-agent-tools/index.js → core/agent/tools/registry.js} +31 -32
- package/src/core/apc/agents-vault.js +37 -0
- package/src/core/{scaffold.js → apc/scaffold.js} +4 -5
- package/src/core/{config.js → config/index.js} +21 -27
- package/src/core/config/paths.js +32 -0
- package/src/core/constants/actors.js +8 -0
- package/src/core/constants/channels.js +19 -0
- package/src/core/constants/index.js +5 -0
- package/src/core/constants/permissions.js +17 -0
- package/src/core/constants/roles.js +9 -0
- package/src/core/engines/_streaming.js +63 -0
- package/src/core/engines/anthropic.js +11 -22
- package/src/core/engines/ollama.js +7 -16
- package/src/core/identity/index.js +8 -0
- package/src/core/{identity.js → identity/self.js} +5 -5
- package/src/core/{telegram-identity.js → identity/telegram.js} +1 -1
- package/src/core/logging.js +1 -1
- package/src/core/mascot.js +1 -1
- package/src/core/memory/active-threads.js +10 -10
- package/src/core/memory/broker.js +9 -9
- package/src/core/memory/compactor.js +2 -2
- package/src/core/memory/index.js +2 -2
- package/src/core/memory/indexer.js +1 -1
- package/src/core/{code-sessions-store.js → stores/code-sessions.js} +3 -7
- package/src/core/{messages-store.js → stores/messages.js} +6 -4
- package/src/core/stores/routine-memory.js +71 -0
- package/src/core/{routines-store.js → stores/routines.js} +1 -3
- package/src/core/stores/runtime-sessions.js +99 -0
- package/src/core/{tasks-store.js → stores/tasks.js} +3 -8
- package/src/core/update-check.js +1 -1
- package/src/core/util/ids.js +14 -0
- package/src/core/util/index.js +2 -0
- package/src/core/util/text-similarity.js +52 -0
- package/src/core/util/time.js +9 -0
- package/src/core/voice/tts.js +1 -1
- package/src/host/daemon/api/admin-config.js +4 -3
- package/src/host/daemon/api/admin.js +1 -1
- package/src/host/daemon/api/agents.js +4 -25
- package/src/host/daemon/api/artifacts.js +118 -1
- package/src/host/daemon/api/code.js +60 -16
- package/src/host/daemon/api/confirm.js +1 -1
- package/src/host/daemon/api/connections.js +2 -2
- package/src/host/daemon/api/conversations.js +2 -2
- package/src/host/daemon/api/deck.js +1 -1
- package/src/host/daemon/api/desktop.js +1 -1
- package/src/host/daemon/api/embeddings.js +4 -4
- package/src/host/daemon/api/engines.js +2 -2
- package/src/host/daemon/api/exec.js +3 -3
- package/src/host/daemon/api/identity.js +1 -1
- package/src/host/daemon/api/mcps.js +1 -1
- package/src/host/daemon/api/messages.js +1 -1
- package/src/host/daemon/api/runtimes.js +9 -8
- package/src/host/daemon/api/sessions-search.js +1 -1
- package/src/host/daemon/api/sessions.js +2 -2
- package/src/host/daemon/api/shared.js +5 -4
- package/src/host/daemon/api/skills.js +30 -0
- package/src/host/daemon/api/super-agent.js +29 -9
- package/src/host/daemon/api/tasks.js +2 -2
- package/src/host/daemon/api/telegram.js +1 -1
- package/src/host/daemon/api/tools.js +6 -6
- package/src/host/daemon/api/tts.js +2 -2
- package/src/host/daemon/api/voice.js +14 -12
- package/src/host/daemon/api.js +2 -0
- package/src/host/daemon/compact.js +1 -1
- package/src/host/daemon/db.js +4 -4
- package/src/host/daemon/desktop-ws.js +1 -1
- package/src/host/daemon/index.js +4 -4
- package/src/host/daemon/plugins/{desktop.js → desktop/index.js} +45 -6
- package/src/host/daemon/plugins/index.js +2 -2
- package/src/host/daemon/plugins/telegram/ask.js +309 -0
- package/src/host/daemon/plugins/{telegram.js → telegram/index.js} +390 -191
- package/src/host/daemon/plugins/telegram/media.js +162 -0
- package/src/host/daemon/projects-helpers.js +54 -0
- package/src/host/daemon/routines.js +28 -12
- package/src/host/daemon/smoke.js +2 -2
- package/src/host/daemon/token-store.js +1 -1
- package/src/host/daemon/transcription.js +2 -2
- package/src/host/daemon/wakeup.js +2 -2
- package/src/interfaces/cli/commands/agent.js +3 -3
- package/src/interfaces/cli/commands/artifact.js +99 -0
- package/src/interfaces/cli/commands/command.js +1 -1
- package/src/interfaces/cli/commands/config.js +3 -2
- package/src/interfaces/cli/commands/desktop.js +1 -1
- package/src/interfaces/cli/commands/exec.js +2 -1
- package/src/interfaces/cli/commands/identity.js +2 -2
- package/src/interfaces/cli/commands/init.js +1 -1
- package/src/interfaces/cli/commands/mcp.js +1 -1
- package/src/interfaces/cli/commands/memory.js +2 -2
- package/src/interfaces/cli/commands/model.js +16 -6
- package/src/interfaces/cli/commands/project.js +1 -1
- package/src/interfaces/cli/commands/routine.js +58 -0
- package/src/interfaces/cli/commands/search.js +1 -1
- package/src/interfaces/cli/commands/session.js +4 -4
- package/src/interfaces/cli/commands/setup.js +4 -3
- package/src/interfaces/cli/commands/skills.js +25 -4
- package/src/interfaces/cli/commands/status.js +1 -1
- package/src/interfaces/cli/commands/sys.js +11 -4
- package/src/interfaces/cli/commands/update.js +1 -1
- package/src/interfaces/cli/index.js +8 -4
- package/src/interfaces/cli/postinstall.js +2 -2
- package/src/interfaces/cli/terminal-chat/renderer.js +22 -2
- package/src/interfaces/mcp-server/index.js +1 -1
- package/src/interfaces/tui/component/prompt/index.tsx +3 -1
- package/src/interfaces/tui/context/sdk-apx.tsx +47 -7
- package/src/interfaces/tui/context/sync-apx.tsx +20 -2
- package/src/interfaces/tui/context/sync.tsx +2 -1
- package/src/interfaces/tui/routes/session/index.tsx +151 -136
- package/src/interfaces/tui/routes/session/sidebar-apx.tsx +37 -15
- package/src/interfaces/tui/run.ts +2 -0
- package/src/interfaces/web/dist/assets/index-34U_Mp1M.css +1 -0
- package/src/interfaces/web/dist/assets/index-BkybwwRn.js +570 -0
- package/src/interfaces/web/dist/assets/index-BkybwwRn.js.map +1 -0
- package/src/interfaces/web/dist/index.html +2 -2
- package/src/interfaces/web/package-lock.json +9 -9
- package/src/interfaces/web/src/App.tsx +51 -32
- package/src/interfaces/web/src/components/RobyBubble.tsx +12 -6
- package/src/interfaces/web/src/components/UiSelect.tsx +1 -1
- package/src/interfaces/web/src/components/chat/AskQuestionsCard.tsx +72 -0
- package/src/interfaces/web/src/components/chat/InlineAskPanel.tsx +399 -0
- package/src/interfaces/web/src/components/chat/MessageBubble.tsx +16 -3
- package/src/interfaces/web/src/components/chat/MessageList.tsx +2 -1
- package/src/interfaces/web/src/components/chat/SkillPicker.tsx +77 -0
- package/src/interfaces/web/src/components/code/CodeArtifactsTab.tsx +230 -0
- package/src/interfaces/web/src/components/code/CodeProjectPicker.tsx +1 -1
- package/src/interfaces/web/src/components/code/CodeSidePanel.tsx +40 -17
- package/src/interfaces/web/src/components/common/TabLayout.tsx +9 -5
- package/src/interfaces/web/src/components/common/TabNav.tsx +3 -3
- package/src/interfaces/web/src/components/layout/ProjectSidebar.tsx +4 -2
- package/src/interfaces/web/src/hooks/useChat.ts +47 -2
- package/src/interfaces/web/src/hooks/useNavCollapseCtx.tsx +59 -0
- package/src/interfaces/web/src/hooks/usePersonaName.ts +11 -0
- package/src/interfaces/web/src/i18n/en.ts +27 -7
- package/src/interfaces/web/src/i18n/es.ts +27 -7
- package/src/interfaces/web/src/lib/api/artifacts.ts +47 -0
- package/src/interfaces/web/src/lib/api/skills.ts +25 -0
- package/src/interfaces/web/src/lib/api.ts +2 -0
- package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +41 -20
- package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +5 -18
- package/src/interfaces/web/src/screens/modules/DesktopScreen.tsx +1 -8
- package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +39 -40
- package/src/interfaces/web/src/screens/project/ChatTab.tsx +27 -9
- package/src/skills/apc-context/SKILL.md +159 -0
- package/src/core/agent/ghost-guard.js +0 -24
- package/src/core/agent/prompts/channels/terminal.md +0 -16
- package/src/host/daemon/apc-runtime-context.js +0 -124
- package/src/host/daemon/super-agent-tools/helpers.js +0 -124
- package/src/host/daemon/super-agent-tools/tools/ask-questions.js +0 -32
- package/src/host/daemon/tool-call-parser.js +0 -2
- package/src/interfaces/web/dist/assets/index-BDUsA6L6.css +0 -1
- package/src/interfaces/web/dist/assets/index-BV615I9p.js +0 -548
- package/src/interfaces/web/dist/assets/index-BV615I9p.js.map +0 -1
- /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-files.js +0 -0
- /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-mcps.js +0 -0
- /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-projects.js +0 -0
- /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/read-file.js +0 -0
- /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/search-files.js +0 -0
- /package/src/core/agent/{pseudo-tools.js → tools/pseudo-tools.js} +0 -0
- /package/src/core/agent/{tool-call-parser.js → tools/tool-call-parser.js} +0 -0
- /package/src/core/{parser.js → apc/parser.js} +0 -0
- /package/src/core/{apc-skill-sync.js → apc/skill-sync.js} +0 -0
- /package/src/core/{artifacts-store.js → stores/artifacts.js} +0 -0
- /package/src/{host/daemon → core/stores}/engine-sessions.js +0 -0
- /package/src/core/{session-store.js → stores/sessions.js} +0 -0
|
@@ -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
|
-
|
|
291
|
-
|
|
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
|
-
|
|
715
|
-
title: "
|
|
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
|
|
719
|
-
thinking: "
|
|
720
|
-
talk: "Hablar con
|
|
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
|
},
|
|
@@ -727,6 +727,18 @@ export const es = {
|
|
|
727
727
|
message: "Esa ruta no existe.",
|
|
728
728
|
},
|
|
729
729
|
|
|
730
|
+
ask_panel: {
|
|
731
|
+
answers_header: "Respuestas",
|
|
732
|
+
other: "Otro",
|
|
733
|
+
other_placeholder: "Escribí tu propia respuesta acá",
|
|
734
|
+
text_placeholder: "Escribí tu respuesta…",
|
|
735
|
+
back: "Atrás",
|
|
736
|
+
skip: "Omitir",
|
|
737
|
+
next: "Siguiente",
|
|
738
|
+
submit: "Enviar",
|
|
739
|
+
status_waiting: "Esperando respuesta…",
|
|
740
|
+
status_received: "Respuestas recibidas",
|
|
741
|
+
},
|
|
730
742
|
code_module: {
|
|
731
743
|
title: "Code",
|
|
732
744
|
badge: "super-agent",
|
|
@@ -748,6 +760,14 @@ export const es = {
|
|
|
748
760
|
mode_plan_hint: "Plan — solo lectura, propone cambios sin tocar archivos",
|
|
749
761
|
tab_context: "Contexto",
|
|
750
762
|
tab_changes: "Cambios",
|
|
763
|
+
tab_artifacts: "Artifacts",
|
|
764
|
+
artifacts_none: "Todavía no hay artifacts. Pedile al agente que cree un script en `artifacts/<nombre>`.",
|
|
765
|
+
artifacts_count: "{n} artifact(s)",
|
|
766
|
+
artifacts_copy_path: "Copiar path",
|
|
767
|
+
artifacts_run: "Run",
|
|
768
|
+
artifacts_run_hint: "Para ejecutarlo desde la terminal:",
|
|
769
|
+
artifacts_delete: "Eliminar",
|
|
770
|
+
artifacts_delete_confirm: "¿Eliminar este artifact? El archivo se borra del disco.",
|
|
751
771
|
ctx_model: "Modelo",
|
|
752
772
|
ctx_tokens: "Tokens",
|
|
753
773
|
ctx_input: "Entrada",
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { http } from "../http";
|
|
2
|
+
|
|
3
|
+
export interface ArtifactEntry {
|
|
4
|
+
name: string;
|
|
5
|
+
path: string;
|
|
6
|
+
size: number;
|
|
7
|
+
modified: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ArtifactContent {
|
|
11
|
+
name: string;
|
|
12
|
+
path: string;
|
|
13
|
+
content: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Shape of POST /projects/:pid/artifacts/:name/run. On success the daemon
|
|
17
|
+
// returns the captured stdout/stderr and exit metadata; on 4xx an error
|
|
18
|
+
// payload is thrown by the http client instead.
|
|
19
|
+
export interface ArtifactRunResult {
|
|
20
|
+
ok: boolean;
|
|
21
|
+
exitCode?: number | null;
|
|
22
|
+
signal?: string | null;
|
|
23
|
+
timedOut?: boolean;
|
|
24
|
+
truncated?: boolean;
|
|
25
|
+
stdout?: string;
|
|
26
|
+
stderr?: string;
|
|
27
|
+
durationMs?: number;
|
|
28
|
+
error?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const Artifacts = {
|
|
32
|
+
list: (pid: string) =>
|
|
33
|
+
http.get<ArtifactEntry[]>(`/projects/${encodeURIComponent(pid)}/artifacts`),
|
|
34
|
+
read: (pid: string, name: string) =>
|
|
35
|
+
http.get<ArtifactContent>(
|
|
36
|
+
`/projects/${encodeURIComponent(pid)}/artifacts/${encodeURIComponent(name)}`,
|
|
37
|
+
),
|
|
38
|
+
run: (pid: string, name: string, args: string[] = []) =>
|
|
39
|
+
http.post<ArtifactRunResult>(
|
|
40
|
+
`/projects/${encodeURIComponent(pid)}/artifacts/${encodeURIComponent(name)}/run`,
|
|
41
|
+
{ args },
|
|
42
|
+
),
|
|
43
|
+
remove: (pid: string, name: string) =>
|
|
44
|
+
http.del<void>(
|
|
45
|
+
`/projects/${encodeURIComponent(pid)}/artifacts/${encodeURIComponent(name)}`,
|
|
46
|
+
),
|
|
47
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -21,6 +21,8 @@ export * from "./api/filesystem";
|
|
|
21
21
|
export * from "./api/voice";
|
|
22
22
|
export * from "./api/deck";
|
|
23
23
|
export * from "./api/code";
|
|
24
|
+
export * from "./api/artifacts";
|
|
25
|
+
export * from "./api/skills";
|
|
24
26
|
|
|
25
27
|
// Re-export the daemon types so older imports of "../lib/api" still work.
|
|
26
28
|
export type {
|
|
@@ -1,13 +1,14 @@
|
|
|
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";
|
|
9
9
|
import { CodeComposer } from "../../components/code/CodeComposer";
|
|
10
10
|
import { CodeSidePanel } from "../../components/code/CodeSidePanel";
|
|
11
|
+
import { InlineAskPanel, pendingAskQuestions } from "../../components/chat/InlineAskPanel";
|
|
11
12
|
import { useToast } from "../../components/Toast";
|
|
12
13
|
import { t } from "../../i18n";
|
|
13
14
|
import { applyStreamEvent, textOf, type ChatMsg } from "../../hooks/useChat";
|
|
@@ -151,8 +152,8 @@ export function CodeScreen() {
|
|
|
151
152
|
return copy;
|
|
152
153
|
});
|
|
153
154
|
|
|
154
|
-
const send = async () => {
|
|
155
|
-
const prompt = draft.trim();
|
|
155
|
+
const send = async (overridePrompt?: string) => {
|
|
156
|
+
const prompt = (overridePrompt ?? draft).trim();
|
|
156
157
|
if (!prompt || busy || !pid || !sid) return;
|
|
157
158
|
const now = new Date().toISOString();
|
|
158
159
|
setMsgs((curr) => [
|
|
@@ -208,27 +209,34 @@ export function CodeScreen() {
|
|
|
208
209
|
|
|
209
210
|
const hasProjects = !projects.isLoading && projectList.length > 0;
|
|
210
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);
|
|
211
217
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
<Code2 size={22} /> {t("code_module.title")}
|
|
218
|
-
</h1>
|
|
219
|
-
<p className="text-sm text-muted-fg">{t("code_module.desc")}</p>
|
|
220
|
-
</div>
|
|
221
|
-
<Badge tone="success">{t("code_module.badge")}</Badge>
|
|
222
|
-
</header>
|
|
218
|
+
// Detect unanswered ask_questions in the last assistant turn. Local "dismissed"
|
|
219
|
+
// ref keys off the turn id so the panel re-appears for a fresh batch.
|
|
220
|
+
const [dismissedKey, setDismissedKey] = useState<string | null>(null);
|
|
221
|
+
const pending = !busy ? pendingAskQuestions(msgs) : null;
|
|
222
|
+
const askVisible = pending && pending.turnKey !== dismissedKey;
|
|
223
223
|
|
|
224
|
+
const submitAnswers = (compiled: string) => {
|
|
225
|
+
void send(compiled);
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
return (
|
|
229
|
+
<div className="flex h-full min-h-0" data-testid="screen-code">
|
|
224
230
|
{projects.isLoading ? (
|
|
225
231
|
<Loading />
|
|
226
232
|
) : !hasProjects ? (
|
|
227
|
-
<
|
|
233
|
+
<div className="grid flex-1 place-items-center">
|
|
234
|
+
<Empty>{t("code_module.no_projects")}</Empty>
|
|
235
|
+
</div>
|
|
228
236
|
) : (
|
|
229
|
-
|
|
230
|
-
{/* Left
|
|
231
|
-
<aside className="flex w-
|
|
237
|
+
<>
|
|
238
|
+
{/* Left: project picker + session list */}
|
|
239
|
+
<aside className="flex w-52 shrink-0 flex-col border-r border-border">
|
|
232
240
|
<div className="shrink-0 border-b border-border p-2">
|
|
233
241
|
<CodeProjectPicker
|
|
234
242
|
projects={projectList}
|
|
@@ -246,6 +254,9 @@ export function CodeScreen() {
|
|
|
246
254
|
onRename={onRenameSession}
|
|
247
255
|
onDelete={onDeleteSession}
|
|
248
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>
|
|
249
260
|
</aside>
|
|
250
261
|
|
|
251
262
|
{/* Center: transcript + composer */}
|
|
@@ -263,6 +274,15 @@ export function CodeScreen() {
|
|
|
263
274
|
</div>
|
|
264
275
|
)}
|
|
265
276
|
</div>
|
|
277
|
+
{askVisible && pending && (
|
|
278
|
+
<InlineAskPanel
|
|
279
|
+
turnKey={pending.turnKey}
|
|
280
|
+
questions={pending.questions}
|
|
281
|
+
onSubmit={submitAnswers}
|
|
282
|
+
onDismiss={() => setDismissedKey(pending.turnKey)}
|
|
283
|
+
disabled={busy}
|
|
284
|
+
/>
|
|
285
|
+
)}
|
|
266
286
|
<div className="border-t border-border bg-card/60 p-3" data-testid="code-input">
|
|
267
287
|
<CodeComposer
|
|
268
288
|
value={draft}
|
|
@@ -280,15 +300,16 @@ export function CodeScreen() {
|
|
|
280
300
|
</main>
|
|
281
301
|
|
|
282
302
|
{/* Right: context + changes */}
|
|
283
|
-
<aside className="hidden w-
|
|
303
|
+
<aside className="hidden w-72 shrink-0 flex-col border-l border-border lg:flex">
|
|
284
304
|
<CodeSidePanel
|
|
305
|
+
pid={pid}
|
|
285
306
|
turns={turns}
|
|
286
307
|
changes={changes.data}
|
|
287
308
|
changesLoading={changes.isLoading}
|
|
288
309
|
onRefreshChanges={() => void changes.mutate()}
|
|
289
310
|
/>
|
|
290
311
|
</aside>
|
|
291
|
-
|
|
312
|
+
</>
|
|
292
313
|
)}
|
|
293
314
|
</div>
|
|
294
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
|
|
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-
|
|
123
|
-
<
|
|
124
|
-
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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}
|
|
@@ -8,9 +8,11 @@ import { UiSelect } from "../../components/UiSelect";
|
|
|
8
8
|
import { Composer } from "../../components/chat/Composer";
|
|
9
9
|
import { MessageList } from "../../components/chat/MessageList";
|
|
10
10
|
import { ContextBar } from "../../components/chat/ContextBar";
|
|
11
|
+
import { InlineAskPanel, pendingAskQuestions } from "../../components/chat/InlineAskPanel";
|
|
11
12
|
import { useChat } from "../../hooks/useChat";
|
|
12
13
|
import { useToast } from "../../components/Toast";
|
|
13
14
|
import { t } from "../../i18n";
|
|
15
|
+
import { usePersonaName } from "../../hooks/usePersonaName";
|
|
14
16
|
import type { AgentEntry } from "../../types/daemon";
|
|
15
17
|
|
|
16
18
|
// Virtual entry slug used in the agent dropdown to address the daemon-level
|
|
@@ -25,19 +27,21 @@ export function ChatTab({ pid }: { pid: string }) {
|
|
|
25
27
|
const [activeSlug, setActiveSlug] = useState(params.get("agent") || "");
|
|
26
28
|
const [creating, setCreating] = useState(false);
|
|
27
29
|
const [model, setModel] = useState("");
|
|
30
|
+
const [dismissedAskKey, setDismissedAskKey] = useState<string | null>(null);
|
|
28
31
|
const { msgs, send: sendChat, stop, clear, streaming } = useChat(pid, (m) => toast.error(m));
|
|
32
|
+
const persona = usePersonaName();
|
|
29
33
|
|
|
30
34
|
const agentList = agents.data || [];
|
|
31
|
-
// Virtual options shown in the dropdown —
|
|
32
|
-
// real project agents.
|
|
33
|
-
// /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.
|
|
34
38
|
const isRoby = (slug: string | null | undefined) => slug === ROBY_SLUG;
|
|
35
39
|
const dropdownOptions = useMemo(
|
|
36
40
|
() => [
|
|
37
|
-
{ value: ROBY_SLUG, label:
|
|
41
|
+
{ value: ROBY_SLUG, label: `${persona} (super-agent)` },
|
|
38
42
|
...agentList.map((a) => ({ value: a.slug, label: a.slug })),
|
|
39
43
|
],
|
|
40
|
-
[agentList],
|
|
44
|
+
[agentList, persona],
|
|
41
45
|
);
|
|
42
46
|
const activeAgent = useMemo(
|
|
43
47
|
() => agentList.find((a) => a.slug === activeSlug) || agentList[0],
|
|
@@ -73,10 +77,11 @@ export function ChatTab({ pid }: { pid: string }) {
|
|
|
73
77
|
|
|
74
78
|
if (agents.isLoading) return <Loading />;
|
|
75
79
|
|
|
76
|
-
// Header subtitle differs: with
|
|
77
|
-
// super-agent (it CAN call tools); a project agent is a
|
|
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.
|
|
78
83
|
const headerSubtitle = activeIsRoby
|
|
79
|
-
? t("project.chat.
|
|
84
|
+
? t("project.chat.superagent_subtitle", { persona })
|
|
80
85
|
: t("project.chat.subtitle");
|
|
81
86
|
|
|
82
87
|
return (
|
|
@@ -84,7 +89,7 @@ export function ChatTab({ pid }: { pid: string }) {
|
|
|
84
89
|
<header className="flex shrink-0 items-center justify-between gap-3 border-b border-border px-4 py-3">
|
|
85
90
|
<div className="min-w-0">
|
|
86
91
|
<h2 className="text-sm font-semibold">
|
|
87
|
-
{activeIsRoby ? t("project.chat.
|
|
92
|
+
{activeIsRoby ? t("project.chat.superagent_title", { persona }) : t("project.chat.title")}
|
|
88
93
|
</h2>
|
|
89
94
|
<p className="truncate text-[11px] text-muted-fg">{headerSubtitle}</p>
|
|
90
95
|
</div>
|
|
@@ -117,6 +122,19 @@ export function ChatTab({ pid }: { pid: string }) {
|
|
|
117
122
|
)}
|
|
118
123
|
</div>
|
|
119
124
|
<ContextBar msgs={msgs} />
|
|
125
|
+
{(() => {
|
|
126
|
+
const pending = !streaming ? pendingAskQuestions(msgs) : null;
|
|
127
|
+
if (!pending || pending.turnKey === dismissedAskKey) return null;
|
|
128
|
+
return (
|
|
129
|
+
<InlineAskPanel
|
|
130
|
+
turnKey={pending.turnKey}
|
|
131
|
+
questions={pending.questions}
|
|
132
|
+
onSubmit={(compiled) => void send(compiled)}
|
|
133
|
+
onDismiss={() => setDismissedAskKey(pending.turnKey)}
|
|
134
|
+
disabled={streaming}
|
|
135
|
+
/>
|
|
136
|
+
);
|
|
137
|
+
})()}
|
|
120
138
|
<Composer
|
|
121
139
|
onSend={send}
|
|
122
140
|
onStop={stop}
|
|
@@ -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/`.
|