Agents.md(this file) is the root index for all coding agents.CLAUDE.mdis the Cloud/Claude agent entrypoint and should reference the same component docs.- Component-specific guidance lives next to code in nested files:
Agmente/AGENTS.mdACPClient/AGENTS.mdAppServerClient/AGENTS.mdAgmenteTests/AGENTS.mdAgmenteUITests/AGENTS.md
- Root files should stay concise and link to nested docs instead of duplicating implementation detail.
- Update
Agents.mdandCLAUDE.mdin the same PR when adding:- a new top-level component/folder,
- a new protocol integration (or protocol mode switch logic),
- major architecture changes that affect more than one component.
- Update the closest nested
AGENTS.mdin the same PR when changing:- RPC method mappings,
- protocol parsing/serialization behavior,
- persistence/session/thread lifecycle behavior,
- test contracts or required test env variables.
- If a code change does not require doc updates, note
Docs: N/Ain the PR description.
- Create
<component>/AGENTS.mdwhen introducing a new component that has runtime logic or tests. - Add the new component doc to both root files (
Agents.mdandCLAUDE.md). - Document:
- ownership boundaries,
- key files and extension points,
- required tests,
- compatibility constraints with ACP/Codex and any migration behavior.
- Create
.agmente.pathsfrom.agmente.paths.exampleonly if it does not already exist; otherwise keep your existing file and update keys as needed. .agmente.pathsis local-only and gitignored.- Use
.agmente.pathsas the single local path registry for ACP/Codex upstream checkouts. - Required variables:
AGMENTE_ACP_REPO: localagent-client-protocolcheckout.AGMENTE_CODEX_REPO: localcodexcheckout (must containcodex-rs).
- Connect to an Agent Client Protocol (ACP) server over WebSocket.
- Connect to an OpenAI Codex app-server over WebSocket.
- Detect protocol after
initializeand route requests to the matching client/runtime. - Keep ACP session flow and Codex thread/turn flow separate in app state and UI.
- ACP mode uses ACP RPC methods (
session/new,session/prompt,session/cancel, optionalsession/listandsession/load). - Codex mode uses app-server v2 methods (
thread/start,thread/resume,thread/list,turn/start,turn/interrupt,model/list,skills/list). - Detection: if
initializereturns a CodexuserAgent(for examplecodex/…), Agmente switches to Codex mode for that server.
- Tap Add Server, then choose ACP or Codex in
ServerTypePicker. - Enter your WebSocket endpoint and optional bearer token.
- Set the working directory if your agent expects one.
- Save, then Connect and Initialize (if not done automatically).
- Create a new session to begin chatting.
- Sessions/threads are kept in memory per server during the app lifecycle.
- ACP sessions
- For servers without
session/listsupport (like Gemini), sessions are persisted to local storage (Core Data) so they remain visible after app restart. - If
session/loadis available, opening a persisted session restores full conversation history from the server. - If
session/listis available, the app refreshes server-side session summaries.
- For servers without
- Codex threads
- The app uses
thread/listfor summaries andthread/resumefor full history. cwd/timestamp metadata comes fromthread/listwhen provided; if missing on older servers, cached values are preserved.- New prompts are sent with
turn/start, and streaming updates are rendered from turn/item notifications.
- The app uses
- Persistence with
@rebornix/stdio-to-ws: when using--persist, the server keeps the child process alive during disconnections and buffers messages. Agmente sends a persistentX-Client-Idheader on every connection so reconnecting clients can replay buffered messages. - Each session/thread opens a chat transcript view; tool calls are surfaced as system messages.
# If codex is installed in PATH
codex app-server --listen ws://127.0.0.1:8788
# Or from Codex source checkout (read `AGMENTE_CODEX_REPO` from `.agmente.paths`)
cd <AGMENTE_CODEX_REPO>/codex-rs
cargo run -p codex-cli -- app-server --listen ws://127.0.0.1:8788Stop Codex app-server:
pkill -9 -f "codex.*app-server.*8788"Add a server with:
Server Type:Codex- Endpoint:
ws://127.0.0.1:8788
Note: per Codex upstream docs, WebSocket transport is currently marked experimental.
Important: Always run stop and start as separate commands (never chained with
&∨). This ensures consistent command strings for VS Code auto-approve.
Start agent server:
npx -y @rebornix/stdio-to-ws --persist --grace-period 604800 "npx @google/gemini-cli --experimental-acp" --port 8765Stop agent server:
pkill -9 -f "stdio-to-ws.*8765"# Vibe agent (Mistral)
npx -y @rebornix/stdio-to-ws --persist --grace-period 604800 "vibe-acp" --port 8765
# Claude Code
npx -y @rebornix/stdio-to-ws --persist --grace-period 604800 "npx @zed-industries/claude-code-acp" --port 8765
# Qwen agent (supports session/list)
npx -y @rebornix/stdio-to-ws --persist --grace-period 604800 "qwen --experimental-acp" --port 8765Add a server with endpoint: ws://localhost:8765
Tip: Always use
--persistflag withstdio-to-ws. This keeps the child process alive during brief disconnections (e.g., iOS app backgrounding) and buffers messages for replay on reconnect. Agmente automatically sends a persistentX-Client-Idheader to enable this feature. Use--grace-periodto keep the process alive for a set time (seconds) after disconnect.
swift test --package-path /path/to/Agmente-oss/ACPClientList destinations and pick a simulator UDID:
xcodebuild -project /path/to/Agmente-oss/Agmente.xcodeproj -scheme Agmente -showdestinationsRun tests:
xcodebuild -project /path/to/Agmente-oss/Agmente.xcodeproj \
-scheme Agmente \
-destination "platform=iOS Simulator,id=<SIMULATOR_UDID>" \
testThe app can be tested in the iOS Simulator using the Xcode Build MCP tools. This section serves as a testing specification for verifying new changes and features.
- Xcode installed with iOS Simulator
- Xcode Build MCP server running (provides
mcp_xcodebuildmcp_*tools)
- Start the local agent - Run one of the agent commands above in a terminal
- Build & run - Discover project, list simulators, build and run on simulator
- Verify UI - Use
describe_ui+screenshotto check UI state - Interact - Tap, type, gesture to test features (always use
describe_uifor coordinates) - Validate - Screenshot + describe_ui to confirm results
- Iterate - Stop app, rebuild if code changes needed
- 🧹 Cleanup (REQUIRED) - Kill the agent server and uninstall the app from simulator
⚠️ IMPORTANT: Always complete the cleanup step! Failing to stop the agent server leaves a process running on port 8765, and failing to uninstall the app leaves stale state in the simulator.
Use these rules for every simulator automation run to avoid wrong taps and wrong mode selection:
- Never tap from screenshots alone. Always run
describe_uiimmediately before any tap/long-press/swipe that depends on coordinates. - Prefer semantic targeting first. Use
tap(id: ...)ortap(label: ...)before rawx,ycoordinates. - Treat coordinates as single-use. After any navigation, modal, keyboard show/hide, or form validation state change, run
describe_uiagain before the next coordinate tap. - Verify segmented control state explicitly. For
ServerTypePickerandProtocolPicker, do not assume selection from a prior run; verify selected mode from nearby text or resulting UI state after tapping. - Use post-action assertions. After critical actions (for example ACP vs Codex selection), confirm expected text is visible:
- ACP mode should show ACP guidance text.
- Codex mode should show
OpenAI Codex app-server protocol.
- Do not continue after ambiguous state. If UI elements overlap (e.g. warning sheet over form) or expected controls are duplicated, stop and re-read hierarchy before proceeding.
- Record key checkpoints in logs. For E2E runs, capture and verify event progression (initialize, thread start/resume, turn start, turn completed) before declaring success.
| Test | Steps | Expected Result |
|---|---|---|
| Add ACP server | Add Server → select ACP → Enter ws://localhost:8765/message → Save |
Server saved, can connect |
| Add Codex server | Add Server → select Codex → Enter ws://127.0.0.1:8788 → Save |
Server saved, can connect |
| Connect to server | Tap Connect on server | Status shows "Connected" |
| Initialize client | Connect → Initialize | Status shows "Initialized" |
| Handle connection error | Enter invalid endpoint | Error message displayed |
| Test | Steps | Expected Result |
|---|---|---|
| Create new session | Tap "+" or "New Session" | New session appears in sidebar |
| Select session | Tap on session | Chat view opens |
| Send message | Type message → Send | Message appears, response received |
| Cancel request | Send message → Tap cancel | Request cancelled, UI responsive |
| Test | Steps | Expected Result |
|---|---|---|
| Keyboard dismiss | Tap outside text field | Keyboard dismisses |
| Scroll chat | Swipe up/down in chat | Smooth scrolling |
| Tool calls display | Send message triggering tools | Tool calls shown as system messages |
- Start/stop the agent: Always start a local agent before testing, and kill it when done.
- Use
describe_uifor coordinates: Don't guess tap coordinates from screenshots. - Wait for responses: Agent processing takes time; use
postDelay/preDelayparameters on tap commands instead of running separatesleepcommands (which can kill the agent server). - Rebuild after changes: Stop the app, then rebuild to ensure fresh code is deployed.
- Never run
sleepin the same terminal as the agent: Runningsleepor other commands in the agent server's terminal will kill the server. Always use a different terminal or use tap delay parameters.
The Add Server form should have no placeholder values for scheme or host - users must enter these explicitly. Defaults:
- Protocol:
ws(most common for local testing) - Host: empty
- Working Directory: empty
The working directory is sent when creating new sessions. If the path doesn't exist on the agent's host, session creation will fail with:
ENOENT: no such file or directory, realpath '/path/that/does/not/exist'
- Fix: Leave working directory empty, or set a valid path on the agent's host.
- For local testing on macOS, the default is
/path/to/your/workspace.
If you previously saved a server with incorrect settings (wrong scheme, bad working directory), you may need to delete and re-add it after fixing the defaults in code. To delete: tap the "..." menu → Delete.
After testing, always stop the local agent server:
pkill -9 -f "stdio-to-ws.*8765"Always remove the app from the simulator when done testing:
xcrun simctl uninstall <SIMULATOR_UUID> com.example.AgmenteYou can get the simulator UUID from xcrun simctl list devices or from the list_sims tool.
Both steps are required after every test session:
| Step | Command | Why |
|---|---|---|
| 1. Stop agent server | pkill -9 -f "stdio-to-ws.*8765" |
Frees port 8765 for future tests |
| 2. Uninstall app | xcrun simctl uninstall <UUID> com.example.Agmente |
Removes stale app state |
💡 Tip: Run these as the final step of every test, even if the test failed partway through.
- The iOS app uses the local
ACPClientSwift package (Agmente/ACPClient) to speak ACP over WebSocket. - ACP protocol/spec upstream reference checkout:
AGMENTE_ACP_REPO/docs(especiallyAGMENTE_ACP_REPO/docs/protocolandAGMENTE_ACP_REPO/docs/schema). - Key types:
ACPClientConfiguration(endpoint, auth token provider, ping),ACPClient(connect/send), and delegate callbacks for state and messages. - RPC entry points used in the app:
initialize,session/new,session/prompt,session/cancel, and optionalsession/list. - If you extend the client, keep new RPC methods consistent with ACP JSON-RPC envelopes and add handlers to
ACPViewModel.
- Filesystem read/write toggles (default on).
- Terminal support toggle (default on).
- Client info defaults: name
Agmente iOS, version0.1.0.
- App-server implementation:
AGMENTE_CODEX_REPO/codex-rs/app-server- README for protocol flow and examples:
AGMENTE_CODEX_REPO/codex-rs/app-server/README.md
- README for protocol flow and examples:
- Protocol types/schema:
AGMENTE_CODEX_REPO/codex-rs/app-server-protocol- v2 protocol definitions (Thread/Turn/Item):
AGMENTE_CODEX_REPO/codex-rs/app-server-protocol/src/protocol/v2.rs
- v2 protocol definitions (Thread/Turn/Item):
- Schema generation (from installed Codex CLI):
codex app-server generate-ts --out DIRcodex app-server generate-json-schema --out DIR