@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.
- package/package.json +1 -1
- package/skills/apx/SKILL.md +49 -61
- package/src/core/agent/a2a/reply.js +48 -0
- package/src/core/agent/build-agent-system.js +136 -59
- package/src/core/agent/channels/voice-context.js +98 -0
- package/src/core/agent/memory.js +2 -1
- package/src/core/agent/prompt-builder.js +178 -124
- package/src/core/agent/prompts/channels/code.md +12 -10
- package/src/core/agent/prompts/channels/desktop.md +5 -32
- package/src/core/agent/prompts/channels/telegram.md +4 -15
- package/src/core/agent/prompts/channels/web_code.md +11 -11
- package/src/core/agent/prompts/core/agent-base.md +24 -0
- package/src/core/agent/prompts/core/project-agent.md +11 -0
- package/src/core/agent/prompts/core/super-agent.md +21 -0
- package/src/core/agent/prompts/discipline/action.md +10 -0
- package/src/core/agent/prompts/discipline/single-segment.md +6 -0
- package/src/core/agent/prompts/discipline/two-segment.md +11 -0
- package/src/core/agent/prompts/modes/code-build.md +1 -0
- package/src/core/agent/prompts/modes/code-plan.md +1 -0
- package/src/core/agent/prompts/modes/index.js +28 -0
- package/src/core/agent/self-memory.js +43 -1
- package/src/core/agent/skills/index-store.js +307 -0
- package/src/core/agent/skills/index.js +15 -1
- package/src/core/agent/skills/inspector.js +317 -0
- package/src/core/agent/skills/loader.js +22 -18
- package/src/core/agent/stream/turn-accumulator.js +73 -0
- package/src/core/agent/suggestions.js +37 -0
- package/src/core/agent/super-agent.js +7 -1
- package/src/core/agent/tools/handlers/_git.js +50 -0
- package/src/core/agent/tools/handlers/add-project.js +5 -2
- package/src/core/agent/tools/handlers/call-runtime.js +3 -2
- package/src/core/agent/tools/handlers/git-diff.js +44 -0
- package/src/core/agent/tools/handlers/git-log.js +38 -0
- package/src/core/agent/tools/handlers/git-show.js +34 -0
- package/src/core/agent/tools/handlers/git-status.js +61 -0
- package/src/core/agent/tools/handlers/transcribe-audio.js +1 -1
- package/src/core/agent/tools/helpers.js +2 -2
- package/src/core/agent/tools/names.js +169 -0
- package/src/core/agent/tools/registry-bridge.js +6 -14
- package/src/core/agent/tools/registry.js +103 -69
- package/src/core/apc/context-copy.js +27 -0
- package/src/core/apc/notes.js +19 -0
- package/src/core/apc/parser.js +12 -5
- package/src/core/apc/paths.js +87 -0
- package/src/core/apc/scaffold.js +82 -76
- package/src/core/apc/skill-sync.js +10 -0
- package/src/{host/daemon/plugins → core/channels}/telegram/dispatch.js +38 -16
- package/src/core/config/index.js +24 -2
- package/src/core/config/redact.js +95 -0
- package/src/core/constants/channels.js +2 -0
- package/src/core/constants/code-modes.js +10 -0
- package/src/core/constants/index.js +1 -0
- package/src/core/deck/manifest.js +186 -0
- package/src/core/engines/catalog.js +83 -0
- package/src/core/{tools → http-tools}/browser.js +0 -1
- package/src/core/{tools → http-tools}/fetch.js +0 -1
- package/src/core/{tools → http-tools}/glob.js +0 -1
- package/src/core/{tools → http-tools}/grep.js +0 -1
- package/src/core/{tools → http-tools}/registry.js +0 -1
- package/src/core/{tools → http-tools}/search.js +0 -1
- package/src/core/i18n/en.js +9 -0
- package/src/core/i18n/es.js +12 -0
- package/src/core/i18n/index.js +54 -0
- package/src/core/i18n/pt.js +9 -0
- package/src/core/identity/telegram.js +2 -1
- package/src/core/mcp/runner.js +272 -14
- package/src/core/mcp/sources.js +3 -2
- package/src/core/routines/index.js +16 -0
- package/src/{host/daemon/routines.js → core/routines/runner.js} +36 -103
- package/src/core/runtime-skills/apc-context/SKILL.md +159 -0
- package/src/core/runtime-skills/apx/SKILL.md +83 -0
- package/src/core/runtime-skills/apx-agency-agents/SKILL.md +125 -0
- package/src/core/runtime-skills/apx-agent/SKILL.md +97 -0
- package/src/core/runtime-skills/apx-mcp/SKILL.md +111 -0
- package/src/core/runtime-skills/apx-mcp-builder/SKILL.md +169 -0
- package/{skills → src/core/runtime-skills}/apx-project/SKILL.md +20 -29
- package/src/core/runtime-skills/apx-routine/SKILL.md +127 -0
- package/src/core/runtime-skills/apx-runtime/SKILL.md +99 -0
- package/src/core/runtime-skills/apx-sessions/SKILL.md +232 -0
- package/src/core/runtime-skills/apx-skill-builder/SKILL.md +129 -0
- package/{skills → src/core/runtime-skills}/apx-task/SKILL.md +18 -21
- package/src/core/runtime-skills/apx-telegram/SKILL.md +120 -0
- package/src/core/runtime-skills/apx-voice/SKILL.md +117 -0
- package/src/core/runtime-skills/{claude-code.md → claude-code/SKILL.md} +1 -0
- package/src/core/runtime-skills/{codex-cli.md → codex-cli/SKILL.md} +1 -0
- package/src/core/runtime-skills/{opencode-cli.md → opencode-cli/SKILL.md} +1 -0
- package/src/core/runtime-skills/{openrouter.md → openrouter/SKILL.md} +1 -0
- package/src/{host/daemon/env-detect.js → core/runtimes/detect.js} +1 -1
- package/src/core/stores/code-sessions.js +50 -2
- package/src/core/stores/routine-memory.js +1 -1
- package/src/core/stores/sessions-search.js +121 -0
- package/src/core/stores/sessions.js +38 -0
- package/src/core/vars/index.js +14 -0
- package/src/core/vars/interpolate.js +86 -0
- package/src/core/vars/sources.js +151 -0
- package/src/core/voice/audio-decode.js +38 -0
- package/src/core/voice/transcription.js +225 -0
- package/src/host/daemon/api/admin-config.js +5 -82
- package/src/host/daemon/api/agents.js +5 -5
- package/src/host/daemon/api/code.js +17 -169
- package/src/host/daemon/api/config.js +3 -4
- package/src/host/daemon/api/conversations.js +8 -29
- package/src/host/daemon/api/deck.js +37 -404
- package/src/host/daemon/api/engines.js +1 -80
- package/src/host/daemon/api/exec.js +1 -1
- package/src/host/daemon/api/mcps.js +32 -0
- package/src/host/daemon/api/routines.js +1 -1
- package/src/host/daemon/api/runtimes.js +4 -3
- package/src/host/daemon/api/sessions-search.js +24 -140
- package/src/host/daemon/api/sessions.js +12 -30
- package/src/host/daemon/api/shared.js +2 -1
- package/src/host/daemon/api/skills.js +140 -6
- package/src/host/daemon/api/super-agent.js +56 -1
- package/src/host/daemon/api/telegram.js +1 -11
- package/src/host/daemon/api/tools.js +6 -6
- package/src/host/daemon/api/transcribe.js +2 -2
- package/src/host/daemon/api/vars.js +137 -0
- package/src/host/daemon/api/voice.js +13 -290
- package/src/host/daemon/api.js +2 -0
- package/src/host/daemon/db.js +6 -6
- package/src/host/daemon/deck-exec.js +148 -0
- package/src/host/daemon/index.js +20 -3
- package/src/host/daemon/plugins/telegram/index.js +9 -9
- package/src/host/daemon/routines-scheduler.js +64 -0
- package/src/host/daemon/smoke.js +3 -2
- package/src/host/daemon/whisper-server.js +225 -0
- package/src/interfaces/cli/branding.js +53 -0
- package/src/interfaces/cli/commands/agent.js +3 -2
- package/src/interfaces/cli/commands/command.js +2 -3
- package/src/interfaces/cli/commands/messages.js +6 -2
- package/src/interfaces/cli/commands/pair.js +5 -4
- package/src/interfaces/cli/commands/search.js +1 -1
- package/src/interfaces/cli/commands/sessions.js +3 -2
- package/src/interfaces/cli/commands/skills.js +290 -55
- package/src/interfaces/cli/index.js +84 -2
- package/src/interfaces/web/dist/assets/index-C0fm31dY.js +618 -0
- package/src/interfaces/web/dist/assets/index-C0fm31dY.js.map +1 -0
- package/src/interfaces/web/dist/assets/index-UcAqlBO6.css +1 -0
- package/src/interfaces/web/dist/index.html +2 -2
- package/src/interfaces/web/package-lock.json +182 -182
- package/src/interfaces/web/src/components/ModelCombobox.tsx +2 -1
- package/src/interfaces/web/src/components/TelegramChannelDialog.tsx +1 -1
- package/src/interfaces/web/src/components/chat/AskAnswersCard.tsx +76 -0
- package/src/interfaces/web/src/components/chat/MessageBubble.tsx +37 -4
- package/src/interfaces/web/src/components/chat/MessageList.tsx +23 -1
- package/src/interfaces/web/src/components/chat/ModelPicker.tsx +3 -1
- package/src/interfaces/web/src/components/code/CodeArtifactsTab.tsx +4 -4
- package/src/interfaces/web/src/components/code/CodeChangesTab.tsx +1 -1
- package/src/interfaces/web/src/components/code/CodeFileTree.tsx +3 -2
- package/src/interfaces/web/src/components/code/CodeFileViewer.tsx +3 -2
- package/src/interfaces/web/src/components/code/CodeTerminal.tsx +3 -2
- package/src/interfaces/web/src/components/config/GlobalConfigEditor.tsx +2 -1
- package/src/interfaces/web/src/components/deck/WidgetRow.tsx +2 -1
- package/src/interfaces/web/src/components/inputs/KeyValueList.tsx +93 -0
- package/src/interfaces/web/src/components/inputs/VarTokenInput.tsx +449 -0
- package/src/interfaces/web/src/components/settings/DefaultRouterCard.tsx +2 -1
- package/src/interfaces/web/src/components/settings/EnginesPanel.tsx +2 -2
- package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +73 -4
- package/src/interfaces/web/src/components/settings/SkillsInspectorPanel.tsx +222 -0
- package/src/interfaces/web/src/components/settings/providers/ProviderCard.tsx +3 -2
- package/src/interfaces/web/src/components/settings/providers/ProviderModal.tsx +3 -2
- package/src/interfaces/web/src/components/ui/chat-input.tsx +5 -4
- package/src/interfaces/web/src/components/ui/sidebar.tsx +3 -2
- package/src/interfaces/web/src/components/voice/VoiceProviderModal.tsx +2 -1
- package/src/interfaces/web/src/constants/index.ts +1 -1
- package/src/interfaces/web/src/hooks/useChat.ts +19 -0
- package/src/interfaces/web/src/i18n/en.ts +175 -7
- package/src/interfaces/web/src/i18n/es.ts +180 -15
- package/src/interfaces/web/src/lib/api/mcps.ts +25 -0
- package/src/interfaces/web/src/lib/api/skills.ts +70 -0
- package/src/interfaces/web/src/lib/api/vars.ts +38 -0
- package/src/interfaces/web/src/lib/api.ts +1 -0
- package/src/interfaces/web/src/screens/ProjectScreen.tsx +8 -31
- package/src/interfaces/web/src/screens/SettingsScreen.tsx +6 -2
- package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +1 -1
- package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +4 -3
- package/src/interfaces/web/src/screens/modules/DesktopScreen.tsx +7 -6
- package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +4 -3
- package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +1 -1
- package/src/interfaces/web/src/screens/project/ConfigTab.tsx +132 -1
- package/src/interfaces/web/src/screens/project/McpsTab.tsx +549 -104
- package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +1 -1
- package/src/interfaces/web/src/screens/project/VarsTab.tsx +300 -0
- package/src/interfaces/web/src/types/daemon.ts +15 -0
- package/skills/apx-agency-agents/SKILL.md +0 -141
- package/skills/apx-agent/SKILL.md +0 -100
- package/skills/apx-mcp-builder/SKILL.md +0 -183
- package/skills/apx-routine/SKILL.md +0 -140
- package/skills/apx-runtime/SKILL.md +0 -117
- package/skills/apx-sessions/SKILL.md +0 -281
- package/skills/apx-skill-builder/SKILL.md +0 -153
- package/skills/apx-telegram/SKILL.md +0 -131
- package/skills/apx-voice/SKILL.md +0 -137
- package/src/core/agent/prompts/action-discipline.md +0 -24
- package/src/core/agent/prompts/super-agent-base.md +0 -42
- package/src/host/daemon/transcription.js +0 -538
- package/src/host/daemon/whisper-transcribe.py +0 -73
- package/src/interfaces/web/dist/assets/index-Aaiw8BZN.css +0 -1
- package/src/interfaces/web/dist/assets/index-DPqtjDjh.js +0 -602
- package/src/interfaces/web/dist/assets/index-DPqtjDjh.js.map +0 -1
- /package/src/{host/daemon → core/apc}/projects-helpers.js +0 -0
- /package/src/{host/daemon/plugins → core/channels}/telegram/ask.js +0 -0
- /package/src/{host/daemon/plugins → core/channels}/telegram/helpers.js +0 -0
- /package/src/{host/daemon/plugins → core/channels}/telegram/media.js +0 -0
- /package/src/core/{tools → http-tools}/index.js +0 -0
- /package/src/{host/daemon/compact.js → core/stores/conversations-compactor.js} +0 -0
- /package/src/{host/daemon → core/stores}/conversations.js +0 -0
- /package/src/{host/daemon → core/util}/thinking.js +0 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: apx-mcp-builder
|
|
3
|
+
scope: internal
|
|
4
|
+
description: Author a new MCP (Model Context Protocol) server and register it in APX. Covers JSON-RPC stdio protocol, FastMCP (Python) / TypeScript SDK shapes, tool design, secrets, debugging. Load when building a new MCP / exposing a new tool surface. To add an existing MCP, load `apx-mcp` instead.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# apx-mcp-builder
|
|
8
|
+
|
|
9
|
+
An MCP server is a tiny stdio JSON-RPC process. APX spawns it (via `apx mcp add`), discovers tools (`tools/list`), and lets the super-agent call them by name.
|
|
10
|
+
|
|
11
|
+
## Minimum surface
|
|
12
|
+
|
|
13
|
+
| Method | Purpose | Returns |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| `initialize` | Handshake (protocol version + capabilities). | Server capabilities. |
|
|
16
|
+
| `tools/list` | Enumerate tools. | `{ tools: [{name, description, inputSchema}] }` |
|
|
17
|
+
| `tools/call` | Run one tool with `{ name, arguments }`. | `{ content: [...], isError? }` |
|
|
18
|
+
| `notifications/initialized` | One-way init-done from APX. | — |
|
|
19
|
+
|
|
20
|
+
JSON-RPC 2.0 over stdio, framed `Content-Length: N\r\n\r\n<JSON>`. The `@modelcontextprotocol/sdk` (TS) and `fastmcp` / `mcp` (Python) packages handle framing.
|
|
21
|
+
|
|
22
|
+
## Pick a stack
|
|
23
|
+
|
|
24
|
+
| Stack | When |
|
|
25
|
+
|---|---|
|
|
26
|
+
| **Python + FastMCP** | Fastest path; decorator-based; ideal for pip-wrapping tools. |
|
|
27
|
+
| **Node + @modelcontextprotocol/sdk** | Node-only libs, or zero install (`npx -y`). |
|
|
28
|
+
| Raw JSON-RPC | Only when exposing an existing daemon. Otherwise use the SDK. |
|
|
29
|
+
|
|
30
|
+
## Python (FastMCP) — minimum viable server
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
# my_server.py
|
|
34
|
+
from mcp.server.fastmcp import FastMCP
|
|
35
|
+
|
|
36
|
+
mcp = FastMCP("my-server")
|
|
37
|
+
|
|
38
|
+
@mcp.tool()
|
|
39
|
+
def search_inventory(query: str, limit: int = 10) -> list[dict]:
|
|
40
|
+
"""Search the inventory by free-text query. Returns matching SKUs."""
|
|
41
|
+
return [{"sku": "abc", "title": "..."}]
|
|
42
|
+
|
|
43
|
+
@mcp.tool()
|
|
44
|
+
def get_stock(sku: str) -> dict:
|
|
45
|
+
"""Return the current stock count for a SKU."""
|
|
46
|
+
return {"sku": sku, "stock": 42}
|
|
47
|
+
|
|
48
|
+
if __name__ == "__main__":
|
|
49
|
+
mcp.run() # stdio transport
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install fastmcp
|
|
54
|
+
# or: uv tool install fastmcp
|
|
55
|
+
|
|
56
|
+
apx mcp add my-server \
|
|
57
|
+
--command uv --project iacrmar \
|
|
58
|
+
-- run python /abs/path/my_server.py
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Node (TypeScript SDK) — minimum viable server
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// my-server.ts
|
|
65
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
66
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
67
|
+
import {
|
|
68
|
+
ListToolsRequestSchema,
|
|
69
|
+
CallToolRequestSchema,
|
|
70
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
71
|
+
|
|
72
|
+
const server = new Server(
|
|
73
|
+
{ name: "my-server", version: "0.1.0" },
|
|
74
|
+
{ capabilities: { tools: {} } }
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
78
|
+
tools: [
|
|
79
|
+
{
|
|
80
|
+
name: "search_inventory",
|
|
81
|
+
description: "Search the inventory by free-text query.",
|
|
82
|
+
inputSchema: {
|
|
83
|
+
type: "object",
|
|
84
|
+
properties: {
|
|
85
|
+
query: { type: "string" },
|
|
86
|
+
limit: { type: "number", default: 10 },
|
|
87
|
+
},
|
|
88
|
+
required: ["query"],
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
}));
|
|
93
|
+
|
|
94
|
+
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
95
|
+
if (req.params.name === "search_inventory") {
|
|
96
|
+
const { query, limit = 10 } = req.params.arguments as any;
|
|
97
|
+
return {
|
|
98
|
+
content: [{ type: "text", text: JSON.stringify([{ sku: "abc" }]) }],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
throw new Error(`unknown tool: ${req.params.name}`);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
await server.connect(new StdioServerTransport());
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
apx mcp add my-server \
|
|
109
|
+
--command npx --project iacrmar \
|
|
110
|
+
-- -y my-server-package
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Tool design rules
|
|
114
|
+
|
|
115
|
+
1. **Names are snake_case verbs**: `search_inventory`, not `inventorySearch`.
|
|
116
|
+
2. **inputSchema is JSON Schema draft-07**. `required` matters — vague schemas → bad calls.
|
|
117
|
+
3. **Descriptions read like a man-page**. Tool + param descriptions are surfaced to the model.
|
|
118
|
+
4. **Return structured data**, not prose. Convention: JSON inside a text content block. Images use the `image` type.
|
|
119
|
+
5. **Errors are errors**: `throw new Error(...)` propagates as `isError: true`. Empty result = "found nothing" — different signal.
|
|
120
|
+
|
|
121
|
+
## Env vars and secrets
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
apx mcp add github \
|
|
125
|
+
--scope runtime --project iacrmar \
|
|
126
|
+
--command npx \
|
|
127
|
+
--env GITHUB_TOKEN=ghp_xxx \
|
|
128
|
+
--env GITHUB_OWNER=manuel \
|
|
129
|
+
-- -y @modelcontextprotocol/server-github
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`--scope runtime` writes to `~/.apx/projects/<id>/mcps.json` (chmod 0600, never committed). NEVER `--scope shared` for tokens — that file lives in `.apc/` and gets committed.
|
|
133
|
+
|
|
134
|
+
## Anti-examples
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
# DON'T expose every internal function. A server with 40 tools eats context.
|
|
138
|
+
# Pick 5-10 high-value tools per server; split into multiple servers if more.
|
|
139
|
+
|
|
140
|
+
# DON'T return giant blobs in `content`. The agent re-reads every turn.
|
|
141
|
+
# Paginate (`offset`, `limit`) and let the agent ask for more.
|
|
142
|
+
|
|
143
|
+
# DON'T mix stdio + HTTP transports in one process. APX spawns stdio;
|
|
144
|
+
# for HTTP use `url:` in mcps.json instead of `command:`.
|
|
145
|
+
|
|
146
|
+
# DON'T print to stdout outside JSON-RPC frames. Stray print() corrupts
|
|
147
|
+
# the protocol — use stderr for logs. (SDKs handle this; bare `print("debug")`
|
|
148
|
+
# in a tool body breaks everything.)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Debugging
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Smoke test (apx mcp tools is a v0.2 stub — don't rely on it)
|
|
155
|
+
apx mcp run my-server search_inventory '{"query":"shoes"}'
|
|
156
|
+
|
|
157
|
+
# Spawn errors / stderr
|
|
158
|
+
apx log -f
|
|
159
|
+
|
|
160
|
+
# Scopes / files / env APX sees
|
|
161
|
+
apx mcp check --project iacrmar
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Don't
|
|
165
|
+
|
|
166
|
+
- Don't reinvent SDK framing — bypass only with reason.
|
|
167
|
+
- Don't make interactive tools. MCP is one-shot per call; split flows into multiple tools.
|
|
168
|
+
- Don't ship without a README — future-you forgets which env vars matter.
|
|
169
|
+
- Don't expect APX to retry MCP errors. The agent sees the error and decides.
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: apx-project
|
|
3
|
-
description:
|
|
3
|
+
description: Register, list, configure, manage APX projects. Load BEFORE asking "which project?" — registered projects are listable; per-project config set via dotted-key PATCH. Triggers: 'register project', 'apx project', 'project config', 'list projects', 'what projects are registered'.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# apx-project
|
|
7
7
|
|
|
8
|
-
A project in APX is an APC-compliant folder
|
|
8
|
+
A project in APX is an APC-compliant folder (`AGENTS.md` + `.apc/project.json`). Once registered, APX keeps runtime state (sessions, messages, routines, tasks, MCPs) under `~/.apx/projects/<apxId>/`.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Two kinds of projects
|
|
11
11
|
|
|
12
|
-
- **`default`** (id=0):
|
|
12
|
+
- **`default`** (id=0): super-agent's scratch workspace at `~/.apx/projects/default/`. Used when user has no project named, no project registered, or addresses "apx itself". Don't use for real work — shared.
|
|
13
13
|
- **registered** (id=1+): real projects, each rooted at a path the user owns.
|
|
14
14
|
|
|
15
15
|
## Concrete CLI calls
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
# Register
|
|
19
|
-
apx project add /path/to/repo #
|
|
19
|
+
apx project add /path/to/repo # reads AGENTS.md + .apc/project.json
|
|
20
20
|
apx project add . # current dir
|
|
21
21
|
|
|
22
22
|
# Inspect
|
|
23
23
|
apx project list # id, name, agents count, path
|
|
24
24
|
|
|
25
|
-
# Remove / rebuild (id or exact path only —
|
|
25
|
+
# Remove / rebuild (id or exact path only — no name resolution here)
|
|
26
26
|
apx project remove <id|path>
|
|
27
|
-
apx project rebuild <id|path> # force re-scan of .apc/
|
|
27
|
+
apx project rebuild <id|path> # force re-scan of .apc/
|
|
28
28
|
|
|
29
29
|
# Per-project config — dotted keys, lives in <repo>/.apc/config.json
|
|
30
30
|
apx project config show <project> # effective + project_only
|
|
@@ -36,17 +36,11 @@ apx project config unset <project> super_agent.model # back to glo
|
|
|
36
36
|
apx project config edit <project> # opens $EDITOR on project_only JSON
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
Every
|
|
39
|
+
Every `project config` write triggers `POST /admin/reload` so the daemon picks up changes without restart.
|
|
40
40
|
|
|
41
|
-
##
|
|
41
|
+
## `<project>` argument resolution
|
|
42
42
|
|
|
43
|
-
Accepted
|
|
44
|
-
- numeric id: `1`
|
|
45
|
-
- exact name from `.apc/project.json`: `iacrmar`
|
|
46
|
-
- absolute path: `/Volumes/SSDT7Shield/trabajos_proyectos/iacrmar`
|
|
47
|
-
- relative path (from cwd) — resolved before matching.
|
|
48
|
-
|
|
49
|
-
The CLI calls `resolveProjectId()` which does fuzzy id-or-name-or-path matching. If you got "project not found", `apx project list` first.
|
|
43
|
+
Accepted: numeric id (`1`), exact name from `.apc/project.json` (`iacrmar`), absolute path, relative path (resolved from cwd). The CLI's `resolveProjectId()` does fuzzy id/name/path matching. If "project not found", run `apx project list` first.
|
|
50
44
|
|
|
51
45
|
## What lives where
|
|
52
46
|
|
|
@@ -59,7 +53,7 @@ The CLI calls `resolveProjectId()` which does fuzzy id-or-name-or-path matching.
|
|
|
59
53
|
├── skills/<slug>.md or <slug>/SKILL.md
|
|
60
54
|
├── mcps.json ← shared MCPs (committed)
|
|
61
55
|
├── commands/ ← custom slash-commands
|
|
62
|
-
└── config.json ← project-only overrides (
|
|
56
|
+
└── config.json ← project-only overrides (edited by `project config`)
|
|
63
57
|
|
|
64
58
|
~/.apx/projects/<apxId>/ ← runtime state (never committed)
|
|
65
59
|
├── messages/YYYY-MM-DD.jsonl
|
|
@@ -70,29 +64,26 @@ The CLI calls `resolveProjectId()` which does fuzzy id-or-name-or-path matching.
|
|
|
70
64
|
└── mcps.json ← per-project runtime MCPs (local, may hold tokens)
|
|
71
65
|
```
|
|
72
66
|
|
|
73
|
-
## Anti-
|
|
67
|
+
## Anti-examples
|
|
74
68
|
|
|
75
69
|
```bash
|
|
76
70
|
# DON'T hand-write AGENTS.md + .apc/project.json with shell tools.
|
|
77
71
|
echo "Hello" > /path/repo/AGENTS.md
|
|
78
|
-
mkdir -p /path/repo/.apc
|
|
79
|
-
|
|
80
|
-
|
|
72
|
+
mkdir -p /path/repo/.apc && echo "{...}" > /path/repo/.apc/project.json
|
|
73
|
+
# ↑ No scaffold validation; project appears registered but breaks on `apx project rebuild`.
|
|
74
|
+
# Use `apx init <path>` then `apx project add <path>`.
|
|
81
75
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
# DON'T set super_agent.model to a model that's not in the engine you have keys for.
|
|
76
|
+
# DON'T set super_agent.model to a model lacking an engine key.
|
|
86
77
|
apx project config set iacrmar super_agent.model gemini:gemini-1.5-pro
|
|
87
|
-
# ↑
|
|
78
|
+
# ↑ Fails at first call unless engines.gemini.api_key is set.
|
|
88
79
|
```
|
|
89
80
|
|
|
90
81
|
## When asked "what projects are there?"
|
|
91
82
|
|
|
92
|
-
Don't ask
|
|
83
|
+
Don't ask — call `list_projects` tool or `apx project list`. Same for "which agents does X have?" → `list_agents` / `apx agent list --project X`.
|
|
93
84
|
|
|
94
85
|
## Don't
|
|
95
86
|
|
|
96
|
-
- Don't operate on the default project (id=0) as if it were the user's main work.
|
|
87
|
+
- Don't operate on the default project (id=0) as if it were the user's main work. Scratch space for super-agent state.
|
|
97
88
|
- Don't put secrets in `.apc/config.json` — it's committed. Put them in `~/.apx/config.json` (machine-local) under `engines.*` or `voice.tts.*`.
|
|
98
|
-
- Don't move a project's `.apc/` folder without re-running `apx project rebuild`
|
|
89
|
+
- Don't move a project's `.apc/` folder without re-running `apx project rebuild` — `apxId` will be stale.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: apx-routine
|
|
3
|
+
description: Create, edit, run, debug APX routines (scheduled tasks). Load BEFORE `apx routine add` — schedule grammar, kind selection, pre/post hooks, double-reply gotcha.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# apx-routine
|
|
7
|
+
|
|
8
|
+
A scheduled APX task. Scheduler ticks every 5s. Each routine has a `kind`, `schedule`, optional `spec`, and optional `pre_commands` / `post_commands` shell hooks.
|
|
9
|
+
|
|
10
|
+
## Picking `kind`
|
|
11
|
+
|
|
12
|
+
| Kind | Tools? | Description |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| `heartbeat` | no | "Still alive" marker. No LLM. |
|
|
15
|
+
| `shell` | no | Pure shell. Stdout captured. |
|
|
16
|
+
| `exec_agent` | **no** | Loads agent prompt, sends `spec.prompt`, returns text. Single LLM call. |
|
|
17
|
+
| `super_agent` | **all** | Default agent with full tool registry. Multi-iteration loop. |
|
|
18
|
+
| `telegram` | n/a | Sends hardcoded text via Telegram plugin. |
|
|
19
|
+
|
|
20
|
+
Rule: text from model → `exec_agent`; orchestration (MCPs, files, multi-agent) → `super_agent`; pure shell → `shell`; fixed Telegram poke → `telegram`.
|
|
21
|
+
|
|
22
|
+
## Schedule grammar
|
|
23
|
+
|
|
24
|
+
- `every:<N><unit>` — `every:30s`, `every:5m`, `every:24h`, `every:7d`. **Most common.**
|
|
25
|
+
- `once:<iso-8601>` — `once:2026-12-01T08:00:00Z`. Fires once, then disabled.
|
|
26
|
+
- Cron — `*/5 * * * *`, `0 8 * * *`. Standard 5-field.
|
|
27
|
+
|
|
28
|
+
## Anatomy
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"name": "weather-bariloche",
|
|
33
|
+
"kind": "exec_agent",
|
|
34
|
+
"schedule": "every:24h",
|
|
35
|
+
"spec": { "agent": "default", "prompt": "Write a short greeting..." },
|
|
36
|
+
"pre_commands": ["curl -s 'https://wttr.in/Bariloche?format=...'"],
|
|
37
|
+
"post_commands": ["apx telegram send \"$APX_LLM_OUTPUT\""],
|
|
38
|
+
"enabled": true,
|
|
39
|
+
"skip_prompt_on": "signal"
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Pipeline: `pre_commands` run sequentially → combined stdout becomes `{{pre_output}}` in `spec.prompt` and `$APX_PRE_OUTPUT` (plus `$APX_PRE_OUTPUT_FILE` for big payloads) → handler runs, result becomes `$APX_LLM_OUTPUT` → `post_commands` run.
|
|
44
|
+
|
|
45
|
+
## Anti-example: double-reply
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"kind": "super_agent", ← DON'T
|
|
50
|
+
"spec": { "prompt": "The weather is {{pre_output}}. Send it via Telegram." },
|
|
51
|
+
"post_commands": ["apx telegram send \"$APX_LLM_OUTPUT\""]
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Sends **two** messages: one from agent's `send_telegram` tool, one from `post_commands`. The runner auto-suppresses `send_telegram` when post contains `apx telegram send`, but the clean fix is `exec_agent`:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"kind": "exec_agent",
|
|
60
|
+
"spec": { "agent": "default", "prompt": "The weather is {{pre_output}}. One friendly sentence." },
|
|
61
|
+
"post_commands": ["apx telegram send \"$APX_LLM_OUTPUT\""]
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Concrete CLI calls
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Always pin --project; never use default for real ones
|
|
69
|
+
apx routine list --project iacrmar
|
|
70
|
+
apx routine get weather-bariloche --project iacrmar
|
|
71
|
+
|
|
72
|
+
# Create — exec_agent + shell delivery
|
|
73
|
+
apx routine add weather-bariloche \
|
|
74
|
+
--project iacrmar \
|
|
75
|
+
--kind exec_agent \
|
|
76
|
+
--schedule "every:24h" \
|
|
77
|
+
--spec '{"agent":"default","prompt":"The weather is {{pre_output}}. One friendly sentence."}' \
|
|
78
|
+
--pre-commands "curl -s 'https://wttr.in/Bariloche?format=%t+%C+viento+%w'" \
|
|
79
|
+
--post-commands 'apx telegram send "$APX_LLM_OUTPUT"'
|
|
80
|
+
|
|
81
|
+
# Create — super-agent with tools
|
|
82
|
+
apx routine add daily-status \
|
|
83
|
+
--project iacrmar \
|
|
84
|
+
--kind super_agent \
|
|
85
|
+
--schedule "0 9 * * *" \
|
|
86
|
+
--spec '{"prompt":"List projects with pending tasks and send me a short summary via Telegram."}' \
|
|
87
|
+
--permission-mode automatico
|
|
88
|
+
|
|
89
|
+
# Toggle / run / remove
|
|
90
|
+
apx routine enable weather-bariloche --project iacrmar
|
|
91
|
+
apx routine disable weather-bariloche --project iacrmar
|
|
92
|
+
apx routine run weather-bariloche --project iacrmar # force-trigger now
|
|
93
|
+
apx routine remove weather-bariloche --project iacrmar
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## `--project` is non-negotiable
|
|
97
|
+
|
|
98
|
+
Routines live in `~/.apx/projects/<apxId>/routines.json`. Without `--project`, they go to default (id=0, super-agent scratch) — **not** a user project. Always pass `--project <name|id|path>`.
|
|
99
|
+
|
|
100
|
+
## `skip_prompt_on`
|
|
101
|
+
|
|
102
|
+
Gates the LLM call based on `pre_commands` (`shouldSkipPrompt` in `host/daemon/routines.js`). Post-commands always run.
|
|
103
|
+
|
|
104
|
+
| Value | Skips LLM when… |
|
|
105
|
+
|---|---|
|
|
106
|
+
| `signal` (default) | pre_command prints literal `APX_SKIP`. Non-zero exit alone does NOT skip. |
|
|
107
|
+
| `pre_failure` | any pre_command exits non-zero. |
|
|
108
|
+
| `pre_success` | pre_commands exit 0 (LLM only on pre failure). |
|
|
109
|
+
| `always` | unconditionally — pure pre→post, no LLM. |
|
|
110
|
+
| `never` | LLM always runs, even if pre crashes. |
|
|
111
|
+
|
|
112
|
+
## Debugging
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
apx routine history weather-bariloche --project iacrmar # last runs
|
|
116
|
+
apx log -f # tail unified log
|
|
117
|
+
apx messages tail --channel routine -n 20 # routine-channel messages
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
"Sends nothing" usually means: `enabled: false`, `next_run_at` in the future, or empty LLM text (check `apx messages` or `result.text`).
|
|
121
|
+
|
|
122
|
+
## Don't
|
|
123
|
+
|
|
124
|
+
- Use `super_agent` when `exec_agent` would do — it loops, calls tools, costs more.
|
|
125
|
+
- Write `apx telegram send` inside a `super_agent` prompt — agent calls `send_telegram` AND post_commands fire. Pick one.
|
|
126
|
+
- Hardcode model names in `spec` without reason — routines inherit `super_agent.model` (with router fallback).
|
|
127
|
+
- Put credentials in `spec`. Use `~/.apx/config.json` engines and reference by provider.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: apx-runtime
|
|
3
|
+
description: Delegate a task to an external coding CLI (claude-code, codex, opencode, aider, cursor-agent, gemini-cli, qwen-code) via `apx run`. APX builds the system prompt, spawns the CLI, captures the result. Load when delegating to another AI tool.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# apx-runtime
|
|
7
|
+
|
|
8
|
+
A "runtime" is an external AI coding CLI that APX invokes headlessly. APX builds the agent's system prompt, spawns the CLI with the right flags, captures stdout (and the external session id when available), and stores run metadata as a session file under `~/.apx/projects/<apxId>/agents/<slug>/sessions/` (never committed). Some flows link to the engine's own transcript path.
|
|
9
|
+
|
|
10
|
+
## Supported runtimes
|
|
11
|
+
|
|
12
|
+
| id | binary | Headless flag |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| `claude-code` | `claude` | `-p "<prompt>" --append-system-prompt "<sys>" --output-format json` |
|
|
15
|
+
| `codex` | `codex` | `exec "<prompt>"` (works outside git repos) |
|
|
16
|
+
| `opencode` | `opencode` | non-interactive mode |
|
|
17
|
+
| `aider` | `aider` | `--message "<prompt>" --no-stream` |
|
|
18
|
+
| `cursor-agent` | `cursor-agent` | headless print mode |
|
|
19
|
+
| `gemini-cli` | `gemini` | headless prompt mode |
|
|
20
|
+
| `qwen-code` | `qwen-code` | system prompt passed separately |
|
|
21
|
+
|
|
22
|
+
`apx env detect` reports which are installed and reachable.
|
|
23
|
+
|
|
24
|
+
## Concrete CLI calls
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
apx env detect # which runtimes are installed
|
|
28
|
+
apx env list # alias
|
|
29
|
+
|
|
30
|
+
apx run reviewer --runtime claude-code "Review the diff in src/host/daemon/api/ for memory leaks"
|
|
31
|
+
apx run scratch --runtime codex "Refactor parseAgentsMd to use a state machine"
|
|
32
|
+
apx run scratch --runtime opencode "<prompt>"
|
|
33
|
+
apx run scratch --runtime codex --timeout 300 "<prompt>" # cap (seconds)
|
|
34
|
+
apx run scratch --runtime codex - # prompt from stdin (large prompts)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Behavior:
|
|
38
|
+
1. APX picks project from `--project` or cwd.
|
|
39
|
+
2. Reads agent's `AGENT.md` + memory + skills; builds system prompt with `buildAgentSystem({ invocation: "runtime", runtime: "<id>" })`.
|
|
40
|
+
3. Spawns CLI with the right flags; cwd = project path.
|
|
41
|
+
4. Captures stdout. If runtime printed `APC_RESULT: <value>`, that's the structured result; else first 200 chars of stdout.
|
|
42
|
+
5. Writes `~/.apx/projects/<apxId>/agents/<slug>/sessions/<YYYY-MM-DD>-<id>.md` with frontmatter linking back to the external transcript when available.
|
|
43
|
+
|
|
44
|
+
## Resuming an external session
|
|
45
|
+
|
|
46
|
+
The session file references the external transcript:
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
# ~/.apx/projects/<apxId>/agents/reviewer/sessions/2026-05-27-claude-code-abc123.md
|
|
50
|
+
---
|
|
51
|
+
external_session_path: /Users/.../.claude/projects/<...>/abc123.jsonl
|
|
52
|
+
runtime: claude-code
|
|
53
|
+
session_id: abc123
|
|
54
|
+
---
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Full resume/get/continue/summarise lives in the **`apx-sessions`** skill. Quick paths:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
apx sessions list --engine claude --project iacrmar
|
|
61
|
+
apx session resume <id> # auto-detects engine
|
|
62
|
+
apx session resume <id> --continue # spawn native CLI to keep going
|
|
63
|
+
apx session resume <id> --summary # super-agent summary
|
|
64
|
+
apx session resume <id> --into apx:<slug> # seed new APX session
|
|
65
|
+
apx session get <id> --any --full # or --engine claude --tail 16k
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
See `apx-sessions` for full flag reference, collision handling, and daemon-vs-no-daemon matrix.
|
|
69
|
+
|
|
70
|
+
## APC_RESULT contract
|
|
71
|
+
|
|
72
|
+
To capture a structured value from the external runtime, instruct it via the prompt to print on its last line:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
APC_RESULT: <one-line value>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`extractApfResult()` parses that into the session's `result` field. Useful for automation return values.
|
|
79
|
+
|
|
80
|
+
## Anti-examples
|
|
81
|
+
|
|
82
|
+
- DON'T expect `apx run` to be interactive — it's headless. For interactive, invoke the CLI directly (e.g. `claude`).
|
|
83
|
+
- DON'T pass huge prompts via command line (shell arg limits). For >~10KB, use stdin (`-`) or a temp file.
|
|
84
|
+
- DON'T expect APX to impose a model on the external CLI. APX passes system + user prompt only; the external CLI's own config wins.
|
|
85
|
+
|
|
86
|
+
## When to use which
|
|
87
|
+
|
|
88
|
+
| You want | Pick |
|
|
89
|
+
|---|---|
|
|
90
|
+
| Pair-program with file edits + shell | `claude-code` if installed, else `codex` |
|
|
91
|
+
| Lightweight LLM run, no tools | `apx exec <agent> "<prompt>"` (no runtime needed) |
|
|
92
|
+
| Super-agent to call other agents | `call_agent` tool (in-process, no spawn) |
|
|
93
|
+
| Persisted state across days | `apx run` with `claude-code` or `codex` (their sessions persist) |
|
|
94
|
+
|
|
95
|
+
## Don't
|
|
96
|
+
|
|
97
|
+
- Run untrusted prompts in a `--runtime` CLI with broad tool permissions — the CLI may take file/shell actions.
|
|
98
|
+
- Expect APX to track tool calls inside the external transcript. APX captures stdout + external session path only; inspect the external transcript for tool-level audit.
|
|
99
|
+
- Pick a runtime the user doesn't have installed; `apx env detect` first.
|