Devman Docs

Setup guide & technical reference
← Back to Devman

Setting up Devman

Devman never writes code itself. You talk to Devman; Devman hands every coding task to your dev environment — an automated coding model and agent that does the actual work on your project. Setup is two things:

  1. A data2l.ink API key — powers Devman's conversation and sifts agent output into spoken reports.
  2. A dev environment hostname (and its API key, if it requires one) — download and run the service before creating the account, since signup asks for its hostname. Running locally? http://localhost:8790 is a valid hostname.
  3. An ElevenLabs API key — so Devman can listen and speak.

All configuration lives behind your account: launch Devman, create an account, and enter all three there. The home page has no settings of its own — its task bar uses whatever the signed-in voice app has configured. You can change any of these later in the voice app's Settings.

1. The data2l.ink key

Powers Devman's brain. Requests go through Devman's own /d2l proxy (a Netlify edge function), so no CORS setup is needed. Your workspace is derived from your email at signup.

2. The dev environment hostname and dev key

The dev environment is its own automated coding model and coding agent — Claude Code, a custom agent, whatever you run — wrapped in the three-verb session protocol below. Account creation asks for its hostname, plus its Dev Key if it requires one, which Devman sends on every request as Authorization: Bearer <dev key>. Treat the dev key like an SSH key: it gates an agent that can modify and run code in your project. Once configured, every task Devman takes goes straight to it.

A task result's summary must be one plain, spoken-friendly sentence or paragraph — Devman reads it aloud verbatim.

3. Voice (ElevenLabs)

Devman uses ElevenLabs for both speech-to-text (wake word, dictation) and text-to-speech (Devman's spoken replies). Your API key is collected at account creation (an optional Voice ID picks the voice; it defaults to EXAVITQu4vr4xnSDxMaL). The key is sent directly to ElevenLabs as the xi-api-key header and is stored with your other credentials.

Devman keys (portable login)

A Devman key (devman_...) is a portable credential bundle — your data2l.ink key, workspace, ElevenLabs key, voice, and preferences encoded into one token. Devman generates it locally in your browser: sign in to the voice app, then use Copy Key in the debug console (or call getDevmanKey() from the browser console). Paste it into the Devman-key field at /dev, or open any deploy with #devman_... in the URL, to sign in instantly — handy for moving between deploys and devices. Don't confuse it with the Dev Key above, which authenticates your dev environment service.

The Dev Environment API (session protocol)

Deliberately minimal: initialize a session, exec, kill the session. exec delivers instructions to the dev environment's coding agent — there are no file endpoints because exec covers reading, writing, and exploring too, and the session's info conveys what kind of instructions the environment understands (a shell, a REPL, or a natural-language coding agent). All endpoints speak JSON, must allow CORS from Devman's origin, and authenticate via Authorization: Bearer <dev key>.

EndpointRequestResponse
POST /session{ project_id? } { sessionId, info: { name, language?, shell?, root?, listCommand?, description? } }
POST /session/{id}/exec{ command, stdin?, timeoutMs? } { exitCode, stdout, stderr }
DELETE /session/{id} { success } (or 204)

How Devman drives it

When you give Devman a task, it opens a session, delivers the task to the environment's coding agent via exec, and kills the session when the task ends — including on cancellation. With no dev environment configured, D2L's AI stands in and answers the task directly instead.

The dev environment service (download)

Download devenv-service.js — a zero-dependency Node implementation of the protocol. Run it locally next to your project, or deploy it to a server; either way, its URL is the hostname you enter at account creation:

DEVMAN_DEV_KEY=your-secret node devenv-service.js
# options: PORT (default 8790), DEVMAN_ROOT (project dir), DEVMAN_AGENT, DEVMAN_ORIGIN

Run it locally and your hostname is simply http://localhost:8790 — localhost is a perfectly valid dev environment, and the signup form suggests it by default. (The service sends the Access-Control-Allow-Private-Network header so browsers that enforce Private Network Access can reach localhost from the deployed app.)

Out of the box the service includes no specific coding agents — it is a dummy: the built-in shell agent just runs instructions as shell commands. Real coding agents plug in via template files (below); bundled, selectable-at-install agents are planned.

Adding a coding agent

Agents are added with a template file — copy agents/example-agent.json.template to agents/<your-agent>.json next to the service, fill it in, and start the service with DEVMAN_AGENT=<name>. The file describes how to forward each instruction to your coding agent; wherever {{instruction}} appears, the request coming in from Devman (or any front-end speaking the protocol) is substituted. {{stdin}} and {{root}} are also available.

For an agent reachable over HTTP, you provide the JSON request to its API:

{
  "name": "my-coding-agent",
  "kind": "http",
  "request": {
    "method": "POST",
    "url": "http://localhost:11434/api/task",
    "headers": { "Content-Type": "application/json",
                 "Authorization": "Bearer YOUR_AGENT_API_KEY" },
    "body": { "prompt": "{{instruction}}", "project": "{{root}}" }
  },
  "responsePath": "result.text"
}

The API's response becomes the exec output (responsePath optionally dot-paths into a JSON response). For a CLI agent, use "kind": "command" with an argv array instead:

{ "name": "my-cli-agent", "kind": "command",
  "command": ["my-agent-cli", "--project", "{{root}}", "--task", "{{instruction}}"] }

A minimal implementation, sketched

If you'd rather build your own, the protocol is small enough to sketch — a real dev environment puts its coding agent behind the same three endpoints.

// ~40 lines of Express: a real shell session per id
app.post('/session', auth, (req, res) => {
  const id = crypto.randomUUID()
  sessions[id] = { cwd: process.cwd() }
  res.json({ sessionId: id, info: { name: 'my-project', shell: 'bash', root: process.cwd() } })
})
app.post('/session/:id/exec', auth, (req, res) => {
  const { command, stdin, timeoutMs } = req.body
  const p = spawn('bash', ['-c', command], { cwd: sessions[req.params.id].cwd, timeout: timeoutMs })
  if (stdin) p.stdin.end(stdin)
  // collect stdout/stderr, then:
  // res.json({ exitCode, stdout, stderr })
})
app.delete('/session/:id', auth, (req, res) => {
  delete sessions[req.params.id]
  res.json({ success: true })
})

Using Devman

The voice app is the primary interface; the home page's task bar is the typed equivalent for quick tests with your account's configuration: type a task and press Enter, or use Status / Last result / Cancel. Everything flows through one entry point, handleAction(action, params), with five actions:

ActionParamsReturns
codetask (required), context { taskId, status, coder, summary } — hands the task to the dev environment (or the D2L stand-in); rejects if one is already running
getStatus Running task, or the last finished one, plus whether a dev environment or the stand-in is answering
getLastResult { taskId, task, status, summary } of the most recent completed task
listTasks { tasks: [{ taskId, task, status }] }
cancelTask { cancelled, taskId } — aborts the running task and kills its dev environment session

The raw JSON shown under the task bar is exactly what any external caller would receive.

Appendix: WWWAND compatibility

Devman is a full voice assistant with a dev environment endpoint built in — and WWWAND compatibility comes with that architecture rather than being bolted on. The wwwand-compatible API sits at Devman's core: if an external WWWAND orchestrator integrates, it isn't really using Devman at all — it bypasses Devman's voice and brain and drives that API straight into the dev environment protocol. This is documented last not because it isn't true, but because out of the box it isn't relevant: Devman needs none of it to do its job.

orchestrator tab ⇄ BroadcastChannel ⇄ bridge iframe ⇄ postMessage ⇄ Devman tab

Devman's own app protocol

Devman is not only a WWWAND client — it is also an orchestrator in its own right, mirroring the WWWAND protocol with Devman in the driver's seat. Apps that want Devman's voice brain to drive them: