@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
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: apx-mcp-builder
|
|
3
|
-
scope: internal
|
|
4
|
-
description: How to build a Model Context Protocol (MCP) server from scratch and register it in APX. Load when authoring a new MCP / exposing a new tool surface to agents. Covers the JSON-RPC stdio protocol, FastMCP (Python) / TypeScript SDK shapes, and APX registration.
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# apx-mcp-builder
|
|
8
|
-
|
|
9
|
-
A **Model Context Protocol** server is a tiny process the agent talks to over stdio JSON-RPC. APX spawns it (via `apx mcp add`), discovers its tools (`tools/list`), and lets the super-agent call them by name. This skill is for **authoring a new MCP server**. To **add an existing one** to APX, load `apx-mcp` instead.
|
|
10
|
-
|
|
11
|
-
## The minimum surface
|
|
12
|
-
|
|
13
|
-
An MCP server must implement four RPC methods:
|
|
14
|
-
|
|
15
|
-
| Method | Purpose | Returns |
|
|
16
|
-
|---|---|---|
|
|
17
|
-
| `initialize` | Handshake. APX sends protocol version + capabilities. | Server's capabilities. |
|
|
18
|
-
| `tools/list` | Enumerate available tools. | `{ tools: [{name, description, inputSchema}] }` |
|
|
19
|
-
| `tools/call` | Run one tool. APX sends `{ name, arguments }`. | `{ content: [...], isError? }` |
|
|
20
|
-
| `notifications/initialized` | One-way; APX signals it's done initializing. | — |
|
|
21
|
-
|
|
22
|
-
JSON-RPC 2.0 framing over stdio. Each message: `Content-Length: N\r\n\r\n<JSON>`. The `@modelcontextprotocol/sdk` (TS) and `fastmcp` / `mcp` (Python) packages handle framing for you.
|
|
23
|
-
|
|
24
|
-
## Pick a stack
|
|
25
|
-
|
|
26
|
-
| Stack | When |
|
|
27
|
-
|---|---|
|
|
28
|
-
| **Python + FastMCP** | Fastest path. Decorator-based. Great if your tools wrap pip libs. |
|
|
29
|
-
| **Node + @modelcontextprotocol/sdk** | When the tool calls Node-only libs, or you want zero install (`npx -y`). |
|
|
30
|
-
| Raw JSON-RPC | Only if you have an existing daemon you want to expose. Otherwise SDK. |
|
|
31
|
-
|
|
32
|
-
## Python (FastMCP) — minimum viable server
|
|
33
|
-
|
|
34
|
-
```python
|
|
35
|
-
# my_server.py
|
|
36
|
-
from mcp.server.fastmcp import FastMCP
|
|
37
|
-
|
|
38
|
-
mcp = FastMCP("my-server")
|
|
39
|
-
|
|
40
|
-
@mcp.tool()
|
|
41
|
-
def search_inventory(query: str, limit: int = 10) -> list[dict]:
|
|
42
|
-
"""Search the inventory by free-text query. Returns matching SKUs."""
|
|
43
|
-
# ... your logic ...
|
|
44
|
-
return [{"sku": "abc", "title": "..."}]
|
|
45
|
-
|
|
46
|
-
@mcp.tool()
|
|
47
|
-
def get_stock(sku: str) -> dict:
|
|
48
|
-
"""Return the current stock count for a SKU."""
|
|
49
|
-
return {"sku": sku, "stock": 42}
|
|
50
|
-
|
|
51
|
-
if __name__ == "__main__":
|
|
52
|
-
mcp.run() # stdio transport by default
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
Install:
|
|
56
|
-
```bash
|
|
57
|
-
pip install fastmcp
|
|
58
|
-
# or via uv (recommended):
|
|
59
|
-
uv tool install fastmcp
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Register in APX:
|
|
63
|
-
```bash
|
|
64
|
-
apx mcp add my-server \
|
|
65
|
-
--command uv --project iacrmar \
|
|
66
|
-
-- run python /abs/path/my_server.py
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Node (TypeScript SDK) — minimum viable server
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
// my-server.ts
|
|
73
|
-
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
74
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
75
|
-
import {
|
|
76
|
-
ListToolsRequestSchema,
|
|
77
|
-
CallToolRequestSchema,
|
|
78
|
-
} from "@modelcontextprotocol/sdk/types.js";
|
|
79
|
-
|
|
80
|
-
const server = new Server(
|
|
81
|
-
{ name: "my-server", version: "0.1.0" },
|
|
82
|
-
{ capabilities: { tools: {} } }
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
86
|
-
tools: [
|
|
87
|
-
{
|
|
88
|
-
name: "search_inventory",
|
|
89
|
-
description: "Search the inventory by free-text query.",
|
|
90
|
-
inputSchema: {
|
|
91
|
-
type: "object",
|
|
92
|
-
properties: {
|
|
93
|
-
query: { type: "string" },
|
|
94
|
-
limit: { type: "number", default: 10 },
|
|
95
|
-
},
|
|
96
|
-
required: ["query"],
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
}));
|
|
101
|
-
|
|
102
|
-
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
103
|
-
if (req.params.name === "search_inventory") {
|
|
104
|
-
const { query, limit = 10 } = req.params.arguments as any;
|
|
105
|
-
// ... your logic ...
|
|
106
|
-
return {
|
|
107
|
-
content: [{ type: "text", text: JSON.stringify([{ sku: "abc" }]) }],
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
throw new Error(`unknown tool: ${req.params.name}`);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
await server.connect(new StdioServerTransport());
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
Register:
|
|
117
|
-
```bash
|
|
118
|
-
apx mcp add my-server \
|
|
119
|
-
--command npx --project iacrmar \
|
|
120
|
-
-- -y my-server-package
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## Tool design rules
|
|
124
|
-
|
|
125
|
-
1. **Names are snake_case**, verbs preferred: `search_inventory`, not `inventorySearch`.
|
|
126
|
-
2. **inputSchema is JSON Schema draft-07**. Be strict: `required` matters. The agent reads the schema; vague schemas → bad calls.
|
|
127
|
-
3. **Descriptions read like a CLI man-page**. Each tool's description and each param's description gets surfaced to the model. Make them count.
|
|
128
|
-
4. **Return structured data**, not prose. MCP `content` can be text but the convention is to put JSON inside a text block so the agent can parse it back. For images, use the `image` content type.
|
|
129
|
-
5. **Errors are errors, not silent empty**. `throw new Error(...)` propagates as `isError: true` and the agent will see it. Empty results = "found nothing"; that's a different signal.
|
|
130
|
-
|
|
131
|
-
## Env vars and secrets
|
|
132
|
-
|
|
133
|
-
Pass them at registration time via `--env`:
|
|
134
|
-
|
|
135
|
-
```bash
|
|
136
|
-
apx mcp add github \
|
|
137
|
-
--scope runtime --project iacrmar \
|
|
138
|
-
--command npx \
|
|
139
|
-
--env GITHUB_TOKEN=ghp_xxx \
|
|
140
|
-
--env GITHUB_OWNER=manuel \
|
|
141
|
-
-- -y @modelcontextprotocol/server-github
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
`--scope runtime` writes to `~/.apx/projects/<id>/mcps.json` (chmod 0600, never committed). NEVER use `--scope shared` for tokens — that file lives in `.apc/` and gets committed.
|
|
145
|
-
|
|
146
|
-
## Anti-examples
|
|
147
|
-
|
|
148
|
-
```python
|
|
149
|
-
# DON'T expose every internal function as a tool.
|
|
150
|
-
# A server with 40 tools is a context budget killer. Pick 5-10 high-value
|
|
151
|
-
# tools per server; split into multiple servers if you have more.
|
|
152
|
-
|
|
153
|
-
# DON'T return giant blobs in `content`. The agent has to read all of it
|
|
154
|
-
# every turn. Paginate (`offset`, `limit`) and let the agent ask for more.
|
|
155
|
-
|
|
156
|
-
# DON'T mix stdio + HTTP transports in the same process. Pick one. APX
|
|
157
|
-
# spawns stdio servers; if you want HTTP, use `url:` in mcps.json instead
|
|
158
|
-
# of `command:`.
|
|
159
|
-
|
|
160
|
-
# DON'T print to stdout other than JSON-RPC frames. Any stray print()
|
|
161
|
-
# corrupts the protocol — use stderr for logs. (FastMCP / the SDK handle
|
|
162
|
-
# this for you, but `print("debug")` in a tool body breaks everything.)
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## Common debugging path
|
|
166
|
-
|
|
167
|
-
```bash
|
|
168
|
-
# 1. Does the server start + does a tool work? (apx mcp tools is a v0.2 stub — don't rely on it)
|
|
169
|
-
apx mcp run my-server search_inventory '{"query":"shoes"}'
|
|
170
|
-
|
|
171
|
-
# 2. Are there spawn errors?
|
|
172
|
-
apx log -f # tail the daemon log — stderr lands here
|
|
173
|
-
|
|
174
|
-
# 3. What scopes/files + env does APX see?
|
|
175
|
-
apx mcp check --project iacrmar
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
## Don't
|
|
179
|
-
|
|
180
|
-
- Don't reinvent the SDK framing. FastMCP / @modelcontextprotocol/sdk handle the stdio JSON-RPC dance — bypass only if you really need to.
|
|
181
|
-
- Don't make tools that require interactive input. MCP is one-shot per call. If you need a flow, design separate tools for each step.
|
|
182
|
-
- Don't ship a server without a README in the repo. Future-you will not remember which env vars matter.
|
|
183
|
-
- Don't expect APX to retry MCP errors automatically. The agent sees the error and decides.
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: apx-routine
|
|
3
|
-
description: How to create, edit, run, and debug APX routines. Use BEFORE writing any `apx routine add` command — schedule grammar, kind selection, pre/post commands, and the gotchas that produce double-replies.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# apx-routine
|
|
7
|
-
|
|
8
|
-
A routine is a scheduled APX task. APX runs the scheduler tick every 5s and fires routines that are due. Each routine has a `kind`, a `schedule`, an optional `spec`, and optional `pre_commands` / `post_commands` shell hooks.
|
|
9
|
-
|
|
10
|
-
## When to use which `kind`
|
|
11
|
-
|
|
12
|
-
| Kind | Tools? | Description |
|
|
13
|
-
|---|---|---|
|
|
14
|
-
| `heartbeat` | no | Logs a marker message. Useful as a "still alive" ping. No LLM call. |
|
|
15
|
-
| `shell` | no | Pure shell command. No LLM. Stdout captured. |
|
|
16
|
-
| `exec_agent` | **no tools** | Loads a project agent's system prompt, sends `spec.prompt` to the engine, returns plain text. Single LLM call. |
|
|
17
|
-
| `super_agent` | **all tools** | Runs the APX default agent (super-agent mode) with the full tool registry. Multi-iteration tool loop. |
|
|
18
|
-
| `telegram` | n/a | Sends a hardcoded text via the Telegram plugin. |
|
|
19
|
-
|
|
20
|
-
**Picking rule of thumb**:
|
|
21
|
-
- Just need text from a model? → `exec_agent`.
|
|
22
|
-
- Need orchestration (call MCPs, write files, call other agents, send messages with logic)? → `super_agent`.
|
|
23
|
-
- Pure shell (curl + jq + write somewhere)? → `shell`.
|
|
24
|
-
- Periodic Telegram poke with fixed text? → `telegram`.
|
|
25
|
-
|
|
26
|
-
## Schedule grammar
|
|
27
|
-
|
|
28
|
-
- `every:<N><unit>` — `every:30s`, `every:5m`, `every:24h`, `every:7d`. **Most common.**
|
|
29
|
-
- `once:<iso-8601>` — `once:2026-12-01T08:00:00Z`. Fires once at that instant, then disabled.
|
|
30
|
-
- Cron — `*/5 * * * *`, `0 8 * * *`. Standard 5-field. Use only if you really need cron expressions.
|
|
31
|
-
|
|
32
|
-
## Anatomy of a routine
|
|
33
|
-
|
|
34
|
-
```json
|
|
35
|
-
{
|
|
36
|
-
"name": "weather-bariloche",
|
|
37
|
-
"kind": "exec_agent",
|
|
38
|
-
"schedule": "every:24h",
|
|
39
|
-
"spec": { "agent": "default", "prompt": "Write a short greeting..." },
|
|
40
|
-
"pre_commands": ["curl -s 'https://wttr.in/Bariloche?format=...'"],
|
|
41
|
-
"post_commands": ["apx telegram send \"$APX_LLM_OUTPUT\""],
|
|
42
|
-
"enabled": true,
|
|
43
|
-
"skip_prompt_on": "signal"
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
**The pipeline**:
|
|
48
|
-
1. `pre_commands` run sequentially. Their combined stdout becomes `{{pre_output}}` substitutable in `spec.prompt`, and `$APX_PRE_OUTPUT` env var available to `post_commands`. Also written to `$APX_PRE_OUTPUT_FILE` for big payloads.
|
|
49
|
-
2. The handler for `kind` runs. Its text result is exposed to post hooks as `$APX_LLM_OUTPUT`.
|
|
50
|
-
3. `post_commands` run sequentially with that env.
|
|
51
|
-
|
|
52
|
-
## Anti-example: the double-reply
|
|
53
|
-
|
|
54
|
-
```json
|
|
55
|
-
{
|
|
56
|
-
"kind": "super_agent", ← DON'T
|
|
57
|
-
"spec": { "prompt": "The weather is {{pre_output}}. Send it via Telegram." },
|
|
58
|
-
"post_commands": ["apx telegram send \"$APX_LLM_OUTPUT\""]
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
This sends **two** Telegram messages: one from the super-agent's `send_telegram` tool call, one from `post_commands`. The runner now auto-suppresses `send_telegram` when `post_commands` contains `apx telegram send` (see spec/done/01), but the cleaner fix is to use `exec_agent`:
|
|
63
|
-
|
|
64
|
-
```json
|
|
65
|
-
{
|
|
66
|
-
"kind": "exec_agent",
|
|
67
|
-
"spec": { "agent": "default", "prompt": "The weather is {{pre_output}}. One friendly sentence, no greeting." },
|
|
68
|
-
"post_commands": ["apx telegram send \"$APX_LLM_OUTPUT\""]
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
One message, the model writes prose, the shell pipes it to Telegram.
|
|
73
|
-
|
|
74
|
-
## Concrete CLI calls
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
# List routines per project (always pin --project; never use default for real ones)
|
|
78
|
-
apx routine list --project iacrmar
|
|
79
|
-
|
|
80
|
-
# Inspect one
|
|
81
|
-
apx routine get weather-bariloche --project iacrmar
|
|
82
|
-
|
|
83
|
-
# Create — text-only exec_agent + shell delivery
|
|
84
|
-
apx routine add weather-bariloche \
|
|
85
|
-
--project iacrmar \
|
|
86
|
-
--kind exec_agent \
|
|
87
|
-
--schedule "every:24h" \
|
|
88
|
-
--spec '{"agent":"default","prompt":"The weather is {{pre_output}}. One friendly sentence."}' \
|
|
89
|
-
--pre-commands "curl -s 'https://wttr.in/Bariloche?format=%t+%C+viento+%w'" \
|
|
90
|
-
--post-commands 'apx telegram send "$APX_LLM_OUTPUT"'
|
|
91
|
-
|
|
92
|
-
# Create — super-agent with tools
|
|
93
|
-
apx routine add daily-status \
|
|
94
|
-
--project iacrmar \
|
|
95
|
-
--kind super_agent \
|
|
96
|
-
--schedule "0 9 * * *" \
|
|
97
|
-
--spec '{"prompt":"List projects with pending tasks and send me a short summary via Telegram."}' \
|
|
98
|
-
--permission-mode automatico
|
|
99
|
-
|
|
100
|
-
# Toggle, run, remove
|
|
101
|
-
apx routine enable weather-bariloche --project iacrmar
|
|
102
|
-
apx routine disable weather-bariloche --project iacrmar
|
|
103
|
-
apx routine run weather-bariloche --project iacrmar # force-trigger now
|
|
104
|
-
apx routine remove weather-bariloche --project iacrmar
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## `--project` is non-negotiable
|
|
108
|
-
|
|
109
|
-
Routines live in `~/.apx/projects/<apxId>/routines.json`. Without `--project`, the default project (id=0, the super-agent's scratch workspace) gets the routine — that is **not** a user project. Always pass `--project <name|id|path>`.
|
|
110
|
-
|
|
111
|
-
## `skip_prompt_on`
|
|
112
|
-
|
|
113
|
-
Controls whether the LLM call is skipped based on the `pre_commands` result (`shouldSkipPrompt` in `host/daemon/routines.js`):
|
|
114
|
-
|
|
115
|
-
| Value | Skips the LLM when… |
|
|
116
|
-
|---|---|
|
|
117
|
-
| `signal` (default) | a pre_command prints the literal marker `APX_SKIP` to stdout. A non-zero exit alone does **not** skip. |
|
|
118
|
-
| `pre_failure` | any pre_command exits non-zero. |
|
|
119
|
-
| `pre_success` | the pre_commands exit 0 (i.e. run the LLM only on pre failure). |
|
|
120
|
-
| `always` | unconditionally — pure pre→post pipeline, no LLM. |
|
|
121
|
-
| `never` | never — the LLM always runs, even if pre crashes. |
|
|
122
|
-
|
|
123
|
-
Post-commands run regardless of the skip decision. The skip only gates the `kind` handler (the LLM call).
|
|
124
|
-
|
|
125
|
-
## Debugging a routine
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
apx routine history weather-bariloche --project iacrmar # last runs
|
|
129
|
-
apx log -f # tail unified log
|
|
130
|
-
apx messages tail --channel routine -n 20 # routine-channel messages
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
A routine that "sends nothing" most often means: (a) `enabled: false`, (b) `next_run_at` is in the future, (c) the LLM returned empty text — visible in `apx messages` or in the `result.text` of `apx routine run`.
|
|
134
|
-
|
|
135
|
-
## Don't
|
|
136
|
-
|
|
137
|
-
- Don't use `super_agent` when `exec_agent` would do. The super-agent loops, calls tools, costs more.
|
|
138
|
-
- Don't write `apx telegram send` inside a `super_agent` routine prompt — the agent will call `send_telegram` AND `post_commands` will fire. Pick one.
|
|
139
|
-
- Don't hardcode model names in `spec` unless you have a reason — the routine inherits `super_agent.model` (with router fallback) by default.
|
|
140
|
-
- Don't put credentials in routine `spec`. Put them in `~/.apx/config.json` engines and reference them by provider.
|
|
@@ -1,117 +0,0 @@
|
|
|
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, and captures the result. Load when delegating work to another AI tool.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# apx-runtime
|
|
7
|
-
|
|
8
|
-
A "runtime" in APX is an external AI coding CLI that APX can invoke headlessly. APX builds the agent's system prompt, spawns the CLI with the right flags, captures the stdout (and the external tool's session id when available), and stores the run metadata as a session file under `~/.apx/projects/<apxId>/agents/<slug>/sessions/` (runtime state — never committed). Some flows also link to the external 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` | passes system prompt separately |
|
|
21
|
-
|
|
22
|
-
`apx env detect` reports which are installed and reachable.
|
|
23
|
-
|
|
24
|
-
## Concrete CLI calls
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
# What's available on this machine
|
|
28
|
-
apx env detect # which runtimes are installed and reachable
|
|
29
|
-
apx env list # alias of `apx env detect`
|
|
30
|
-
|
|
31
|
-
# Run an agent through an external CLI
|
|
32
|
-
apx run reviewer --runtime claude-code "Review the diff in src/host/daemon/api/ for memory leaks"
|
|
33
|
-
apx run scratch --runtime codex "Refactor parseAgentsMd to use a state machine"
|
|
34
|
-
apx run scratch --runtime opencode "<prompt>"
|
|
35
|
-
apx run scratch --runtime codex --timeout 300 "<prompt>" # cap the run (seconds)
|
|
36
|
-
apx run scratch --runtime codex - # read the prompt from stdin (large prompts)
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Behavior:
|
|
40
|
-
1. APX picks the project from `--project` or cwd.
|
|
41
|
-
2. Reads the agent's `AGENT.md` + memory + skills, builds the system prompt with `buildAgentSystem({ invocation: "runtime", runtime: "<id>" })`.
|
|
42
|
-
3. Spawns the CLI with the right flags. cwd = project path.
|
|
43
|
-
4. Captures stdout. If the runtime printed `APC_RESULT: <value>`, that's the structured result; else the first 200 chars of stdout.
|
|
44
|
-
5. Writes `~/.apx/projects/<apxId>/agents/<slug>/sessions/<YYYY-MM-DD>-<id>.md` with frontmatter linking back to the external tool's own session file (when available).
|
|
45
|
-
|
|
46
|
-
## Resuming an external session
|
|
47
|
-
|
|
48
|
-
After a `apx run`, the resulting APC session file references the external transcript:
|
|
49
|
-
|
|
50
|
-
```yaml
|
|
51
|
-
# ~/.apx/projects/<apxId>/agents/reviewer/sessions/2026-05-27-claude-code-abc123.md
|
|
52
|
-
---
|
|
53
|
-
external_session_path: /Users/.../.claude/projects/<...>/abc123.jsonl
|
|
54
|
-
runtime: claude-code
|
|
55
|
-
session_id: abc123
|
|
56
|
-
---
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
All session resume / get / continue / summarise operations live in the
|
|
60
|
-
**`apx-sessions`** skill. From here, the most common quick paths:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
# Discover the id (or use the one printed by `apx run`)
|
|
64
|
-
apx sessions list --engine claude --project iacrmar
|
|
65
|
-
|
|
66
|
-
# Resume — apx auto-detects which engine owns the id
|
|
67
|
-
apx session resume <id>
|
|
68
|
-
apx session resume <id> --continue # spawn the native CLI to keep going
|
|
69
|
-
apx session resume <id> --summary # super-agent summary of the transcript
|
|
70
|
-
apx session resume <id> --into apx:<slug> # seed a new APX session with the summary
|
|
71
|
-
|
|
72
|
-
# Just read the transcript
|
|
73
|
-
apx session get <id> --any --full # or --engine claude --tail 16k
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
See the `apx-sessions` skill for the full flag reference, collision handling,
|
|
77
|
-
and daemon-vs-no-daemon matrix.
|
|
78
|
-
|
|
79
|
-
## APC_RESULT contract
|
|
80
|
-
|
|
81
|
-
When you want APX to capture a structured value from the external runtime, instruct the runtime via the prompt to print on its last line:
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
APC_RESULT: <one-line value>
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
APX `extractApfResult()` parses that and stores it as the session's `result` field. Useful for return values from automation.
|
|
88
|
-
|
|
89
|
-
## Anti-examples
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
# DON'T expect `apx run` to be interactive. It's headless.
|
|
93
|
-
# For interactive, just invoke the CLI directly (e.g. `claude` for Claude Code).
|
|
94
|
-
|
|
95
|
-
# DON'T pass huge prompts via the command line (shell args have limits).
|
|
96
|
-
# For prompts > ~10KB, use a stdin-friendly route or write a temp file and reference it.
|
|
97
|
-
|
|
98
|
-
# DON'T forget that each runtime has its own model selection.
|
|
99
|
-
# APX passes the system prompt and the user prompt; it does NOT impose a model on
|
|
100
|
-
# the external CLI. The user's external CLI config (e.g. Claude Code's CLAUDE.md
|
|
101
|
-
# defaults) wins.
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## When to use which
|
|
105
|
-
|
|
106
|
-
| You want | Pick |
|
|
107
|
-
|---|---|
|
|
108
|
-
| Pair-program with file edits and shell | `claude-code` if the user has Claude Code, else `codex` |
|
|
109
|
-
| Lightweight LLM run with no tools | `apx exec <agent> "<prompt>"` (no runtime needed) |
|
|
110
|
-
| The super-agent to call other agents | `call_agent` tool (in-process, no spawn) |
|
|
111
|
-
| Run something that needs persisted state across days | `apx run` with `claude-code` or `codex` (their sessions persist) |
|
|
112
|
-
|
|
113
|
-
## Don't
|
|
114
|
-
|
|
115
|
-
- Don't run untrusted prompts in `--runtime` of a CLI with broad tool permissions on the user's machine. The CLI may take file write or shell actions.
|
|
116
|
-
- Don't expect APX to track tool calls inside the external CLI's transcript. APX captures stdout and the external session path — that's it. Inspect the external transcript directly for tool-level audit.
|
|
117
|
-
- Don't pick a runtime the user doesn't have installed; `apx env detect` first if unsure.
|