Skip to content

The host ​

A host is what a client connects to: one root resource, the sessions running under it, the automations it holds and the resources it serves. One ahpd process runs one host, reachable over a WebSocket, over stdin and stdout inside a container, or over an HTTP API.

The process, its verbs and its flags are REFERENCE.md. This page is the host itself: what it announces, what it serves, and every setting it reads.

Terms, one line each:

Term
the hostthe thing a connection is accepted by, and the name for everything below it
the root resourcethe channel ahp-root://, which every client subscribes to
root statethe snapshot that channel answers: agents, activeSessions, terminals and config
root configthe keys a client pushes to ahp-root:// with root/configChanged
a schemethe part of a resource URI before the colon - file, user, usage, or a plugin's
a grant<subject>:<operation>, one act on one kind of thing - USERS.md

The root resource ​

ahp-root:// is the channel a client subscribes to before it knows anything else. Its state says what this host is:

FieldWhat it says
agentsEvery backend, as providers - see below
activeSessionsA number: how many sessions are running a turn, not a list
terminalsEvery open terminal's TerminalInfo, absent when none is open
configThe schema and the values of root config - see Root config

_meta carries two things beside them: ahpd.resourceProviders, the schemes this host serves; and ahpd.grants, every subject a grant may name. ahpd.principal is there for a connection that has already signed in, saying who it is - the same statement the handshake makes, so a client that subscribes later reads what a client that connected earlier was told.

The state of the root, of every session and of every chat is what the protocol's reducers make of the actions this host sends on that channel, from a seed read once when the channel opens. A client that subscribes is served that state, so it holds what a client that watched every action holds.

ahpd.resourceProviders is advertised in the handshake as well as in every root state, because a client needs it before it can ask for anything.

The root channel is also where a client's own reads are served, whatever they are about: listSessions, the resource calls, authenticate, createResourceWatch and resolveSessionConfig all declare ahp-root:// as their channel. The four root actions and their origins are AHP.md.

What a host announces ​

Every entry of agents is one backend, as the protocol's AgentInfo:

FieldWhat it says
providerThe id a client names in createSession, and the scheme its session URIs use
displayName, descriptionWhat a person reads instead of the id
modelsWhat the backend's probe found, each row carrying its own provider because the wire type requires one. A backend that has not answered yet announces none, which is the honest form of "nobody has signed in"
protectedResourcesThe resources a client may send authenticate a token for. Absent when there are none, which means no credential can be handed to this backend at all
customizationsThe skills, subagents and MCP servers a session of this backend starts with, so a client can show what a harness offers before any session exists
capabilitiesmultipleChats, with fork and sideChat where the backend can resume at a turn; and multipleWorkingDirectories, with immutablePrimary and primaryReplacement where it takes more than one directory

A host can be told which agents are off, as HostOptions.disabledAgents: the ids whose record says mode: disabled, read each time the list is asked for. A disabled agent is left out of agents, and refused a new session, a new chat, a chat move and a new turn with <id> is turned off. Its sessions keep their history and stay listed, and take a message again once the agent is on.

HostOptions.pausedAgents is the same for an agent whose record says mode: paused: its backend is served and opened, so its sessions keep their history and its alerts show, and it is left out of agents and refused a new session, a new chat, a chat move and a new turn with <id> is paused. A wake of a stored session reads its history, because the record is opened; a message to it is refused.

ahpd.grants is the other half of what a client is told: one entry per subject a grant may name, each with its title, a one-line description, its operations and the two groups those fall into. Eleven subjects are the host's own - session, chat, file, automation, terminal, diagnostics, container, config, trust, proxy and account, plus the people and cost schemes - and every scheme a provider serves is beside them under its own name. A client draws a role editor from this one map, which is why it is advertised with or without a user directory: it says what a role could hold, not what anybody holds.

What a host serves ​

file: is the host's own scheme. Every other scheme in ahpd.resourceProviders is a provider's: user:, team:, project: and role: when a directory is configured, policy: and usage: always, and whatever a plugin registered. Each entry carries the provider's own describe(), the root URI - <scheme>:// - and the operations its methods implement, read off the provider rather than off a list somebody maintains.

A scheme is advertised so a client can put its operations in a role and have the gate ask for what it will actually call. What each scheme is and who may read it is RESOURCES.md.

Configuration keys ​

Every flag can be a key in the configuration file instead, spelled without the dashes. How the files are found, merged and checked is CONFIGURE.md; this is what the keys are.

KeyValuesDefaultWhat changes
portinteger9187; 0 picks a free oneThe port the host listens on
hostaddress127.0.0.1The address it binds. 0.0.0.0 accepts from other machines, and then a token is required
originslist of origins, such as http://203.0.113.5:9187noneExtra origins a browser may reach this host by. A host bound to 0.0.0.0 answers only to its loopback names, so a page served on its public address needs that address here
pathslist of directoriesthe directory the daemon was started inThe directories this host serves
worktreesRootdirectory<repo>.worktrees beside each repositoryWhere session worktrees are kept
clientToolTimeoutMsinteger, milliseconds600000 (ten minutes)How long a tool call a client runs may wait for that client. 0 waits for ever
clientToolCallDisconnectTimeoutMsinteger, milliseconds30000 (thirty seconds)How long a client whose connections all closed keeps its place in a session and the tool calls it owes there, VS Code's CLIENT_TOOL_CALL_DISCONNECT_TIMEOUT; when it runs out, each call it owes fails in VS Code's words. 0 releases it at once
shellEnvan object of variable name to text or nullnoneThe environment every shell this host starts is given. A client that needs a variable in one session sets shellInitScripts instead
terminalAutoApproveDefaultsvscode or nonevscodeThe rules a session's shell commands are matched against when no window pushed any. vscode is VS Code's table, none approves no command - AHP.md
managedSettingsPermissionsVS Code's managed permissions: deny and ask rule lists, disableBypassPermissionsMode: 'disable', limitTononeThe operator's managed rules: under managedRules: 'checked' the host checks each on the tool questions of its kind; the lock takes Allow All away, and every backend is handed them on Start.managedSettings, under either value - PLUGINS.md
managedSettingsSandboxVS Code's floor shape, SessionSandboxPolicynoneThe floor under every session's sandbox: a chat's sandbox is resolved within it, it is published on each session as vscode.resolvedSandboxPolicy, and one with failClosed keeps the sandbox on with no way out - COMPUTERS.md
eligibleForAutoApprovalVS Code's map of tool name to booleannoneThe operator's per-tool eligibility: under managedRules: 'checked' a tool set to false asks on every call with Allow Once and Skip alone, read on every tool question; it is handed to every backend on Start.managedSettings beside the managed rules under either value - PLUGINS.md
managedRuleschecked or handedcheckedWho checks the two above on a tool question: checked is this host's own check of each managed family on every question of its kind from every backend; handed is VS Code's, the host checking no managed rule and marking nothing, handing the rules to the backends and putting a question a backend marked managedApprovalRequired with Allow Once and Skip. The start's check of the managed document and the Allow All lock hold under both
commandParserfile pathunsetA .js or .ts module whose default export splits a shell command before the terminal rules match it. A path is relative to the configuration file - PLUGINS.md
deltaWindowMsinteger, 0 to 100075How long a turn's streamed text is gathered before it is sent. 0 sends every delta as it arrives
sleepAfterMinutesinteger, minutes30; 0 neverHow long a session with nothing in hand stays loaded before its agent is let go. It wakes when something needs it - SESSIONS.md
sessionResidencyLimitinteger10; 0 sets no limitHow many sessions are resident at most, running or with their state held. Over it, the least recently used one that nothing holds is let go first, with its state - SESSIONS.md
attachmentFetchLimitBytesinteger, bytes33554432 (32 MiB); 0 sets no limitThe largest file a client is asked for when a message attaches one this host has no copy of; one whose size hint is over it is left as it was sent - CHATS.md
toolResultResourceLimitBytesinteger, bytes8388608 (8 MiB, VS Code's MAX_TOOL_RESULT_RESOURCE_BYTES); 0 sets no limitThe most bytes kept of one content a backend hands Start.storeToolResultResource; larger content is kept nowhere and the backend leaves it out - RESOURCES.md
advancedToolsbooleanfalseOffer the tools that declare advancedPermission to every session's model
sessionToolsbooleantrueWhether the session tools - the nine that read and move the sessions beside this one - are offered at all. false offers them to no session. The artifact tools and schedule_wakeup are not session tools and are offered either way
sessionToolsProviderslist of provider idsnoneOffer the session tools to the sessions of these providers alone. Empty, the default, offers them to every provider. It narrows sessionTools rather than replacing it, so with sessionTools false no session is offered them whatever this list holds
closedChatshidden or deletehiddenWhat closing one chat of a session does to that chat's conversation in the backend: hidden keeps it, delete removes it
unofferedModelfail or keepfailWhat a turn naming a model its chat's agent does not offer does: fail ends it in a modelSelectionFailed error, keep is VS Code's, a chat whose agent is not its session's keeping its model and any other chat's agent handed the model as it is
workspacelessFolderfirst or scratchfirstWhere a session that names no folder works: first names it none, so it works in the first folder this host serves; scratch is VS Code's, a folder of its own at <home>/.copilot/chats/<session id>, made when the session is, made again when a start finds it gone and removed with the session. A session id that names no folder under the chats folder is refused under scratch. A session working in its scratch folder is VS Code's workspace-less session: its row and state carry _meta.workspaceless: true, its agent is told last, in VS Code's words, that it works in a scratch folder, set_workspace is offered to it up front, a chat of it is refused a move, its folders are refused a change, and the mark goes when set_workspace gives it a workspace
turnSenderssaid or keptsaidWhether a turn's sender is said on what clients read: said puts who sent each turn under _meta['ahpd.sender'] on its start and its message, live and in every turn read back; kept is VS Code's, the host keeping each turn's sender for its store, its events and its usage and saying it in no action
backendBackgroundWorkdrop or saydropWhat a backend's own chat/backgroundWorkSet and chat/backgroundWorkRemoved come to: drop drops them with a line in the log, the host drawing every background row from backgroundTasks; say is VS Code's, the backend's action said as the host's own
agentOrchestrationLimitsScopesessionTree or sessionsessionTreeWhat the session tools' counts of sessions and chats made and messages sent are kept per, over their sliding hour: sessionTree keeps one count for a session somebody started and every session the tools grew from it, its refusal naming the tree; session is VS Code's, each session's own count, refused in VS Code's words
archiveDirtyWorktreekeep or commitkeepWhat archiving a session does with a working tree that has uncommitted changes: keep leaves the tree, commit commits the changes on the session's branch with the message "Saving uncommitted changes before archiving session", then removes the tree and keeps the branch
pullRequestLookupurl or branchurlHow the pass that archives and deletes merged sessions learns the state of a pull request: url asks GitHub for each related pull request by its page, a related one GitHub answers nothing for keeping the session as it is, as VS Code's lifecycle reads one; branch asks for the pull requests of the session's branch
updateCheckbooleantrueAsk npm, in the background, whether a newer version exists
wirefile pathunsetAppend every frame, both directions, to that file as JSON lines
sessionsfile or memoryfileWhere what this host keeps about a session is written - SESSIONS.md
automationsfile or memoryfileWhether automations survive a restart, and whether their schedules fire - AUTOMATIONS.md
unownedAutomationsevery or noneeveryWhat an automation that names no owner wakes on - AUTOMATIONS.md
usage{ "per": "turn" | "report", "timezone": "<zone>" }per: turn, the system's own zoneHow a turn is written down, and where a day, a week and the store's days are cut - USAGE.md
policies{ "check": true | false, "payOrder": "ending" | "regular" | "extra", "ownLimits": true | false }check: false, payOrder: ending, ownLimits: trueWhether the rows saying who may use which agent, model and computer are enforced, which row pays first, and whether a person reads the limits that apply to them - POLICY.md
httpApitrue, or { "port": <n>, "host": "<addr>" }offServe the commands over HTTP under /api
routes{ "port": <n>, "host": "<addr>" }the daemon's portServe the plugins' routes on a listener of their own - PLUGINS.md
mcpServersan object of server entriesnoneThe MCP servers every session is offered
pluginsa list of specsnoneThe plugins loaded at startup - PLUGINS.md
modelProxysee PROXY.mdnoneThe providers this host's model proxy calls, and the model names that point at them

Eight keys are about who may connect rather than about how the host behaves. They are connectionToken, connectionTokenFile, withoutConnectionToken, users, resource, issuer, requireIssuer and tokensPerPerson, in AUTHENTICATION.md. stdio, configFile, noPlugins, noCwd and pluginOptions mean something only when typed, so a file that sets one is warned about and ignored.

Each key that needs more than a line:

paths is the list of directories this host serves, and the first is where a session goes when a client names none, under the default workspacelessFolder. A relative one is taken from the directory of the file that set it. --no-cwd serves what is named and asks about no other folder; it is refused when the list would be empty. worktreesRoot keeps every session worktree under <dir>/<repo>/<name>, a layout of this host's own (the reference host keeps them in <repo>.worktrees beside each repository), and is made absolute against the working directory because it is a base other paths are joined to.

shellEnv is the environment every shell this host starts is given, as a map of variable name to value. A daemon that runs as a service unit has an environment of its own, and this is how the operator says which of it an agent's shells get: {"shellEnv": {"XDG_CONFIG_HOME": "/home/me/.config"}} opens every terminal and runs every Bash command with that directory. A name set to null is removed from what the daemon itself runs with, which is the other half - a shell that inherits a variable the operator does not want it to have. It reaches the host terminals and the Claude backend's Bash commands, and the other backends come later. A wrong value is ...: shellEnv.PORT must be text or null, and a name a shell cannot export is ...: shellEnv.2FA is not a shell variable name. A client that needs a variable in one session sends shellInitScripts, which is that session's own.

deltaWindowMs is how long the host gathers the streamed text of one part before sending it, in milliseconds: within that window a turn's deltas are merged into one action, so a client draws the same text from fewer envelopes. A wrong value is ...: deltaWindowMs must be an integer between 0 and 1000.

wire appends every frame, both directions, to that file as JSON lines, one message per line with an _ahpLog beside it - the shape VS Code's agent host writes its traffic log in. A line is written through the redactions VS Code's log makes: the token of an authenticate, an authorization string, the certificates of a result, and the source URL of a canvas are written as <redacted> (<redacted canvas source> for the canvas), and the data of a channel/frame or a tcp/data as <redacted channel payload>. A line over 1 MiB is written again with its strings cut and _ahpLog.truncated set; a file over 75 MiB rolls to <file>.1 and five files are kept. The capture holds every root config write a client sent, with the credentials such a write carries, so each of its files is 0600. pnpm wire -- <file> checks one against the schema.

usage says how a turn is written down and where the periods and the store's days are cut. per is turn, the default, which holds what a turn has used and writes one record when the turn ends, or report, which writes one record for every usage report so a turn still running is already billed for what it has spent. Both bill the same work, and a wrong value is ...: usage.per must be one of turn, report. timezone names, as Intl names one, the zone a day starts at and a week starts on - a week is Monday 00:00 there, not the system's own - and the zone the store keeps its days in, so a period summed there holds no record from the period before. The system's own zone is used when the key is absent or names a zone this host cannot read, which is said once at start.

The same store is served as the usage: scheme, so a client reads it through the resource calls it already has: usage:// lists the charged pools that reader may read, usage://<pool> reads that pool as { pool, kind, name, day, week, month }, usage://<pool>/range?from=&until= reads one total between two days, usage://<pool>/records?from=&until= lists the records charged to it, newest first, at most 200, usage://groups?by=&from=&until= sums the records by user, team and project, and usage://limits reads the limits that apply to the reader (USAGE.md). A pool name holds colons, so it is one encoded path segment - usage://project%3Abackend%3Asearch is project:backend:search, not an authority. ahpd usage with no pool lists what that caller may see, and with one prints that pool's three totals, cut in usage.timezone.

policies.check says whether the rows saying who may use which agent, model and computer are enforced. Off by default. The rows are kept and the policy: scheme is served either way, so a store can be filled in before anything is switched on; a wrong value is ...: policies.check must be true or false. policies.payOrder says which row of one scope pays first: ending, the default, uses the row that ends soonest first, regular the rows with no until, and extra the rows with one, the newest from first. policies.ownLimits, true by default, lets a person read the limits whose scope holds them, with only their own figure for an each limit; off, usage://limits is refused and an operator holding policy:read still reads every row through policy://<id>/limits.

httpApi serves the same commands the terminal renders, under /api. true puts it on the host's own listener; an object with a port gives it a listener of its own, and its host binds that listener - decision The HTTP API is off by default, and on the daemon's own port under /api unless httpApi.port is set, and httpApi.host binds the API's own listener. A host with neither a connection token nor a user directory refuses to start with it on, because there would be nothing to hold a request against.

mcpServers is the host's own MCP servers, by the name a person gave each, and every session is offered them whatever agent it runs. An entry is one of the two shapes VS Code uses: a stdio server needs a command, and an http one a url:

json
"mcpServers": {
  "files": { "type": "stdio", "command": "mcp-server-filesystem", "args": ["/srv"], "cwd": "/srv", "env": { "TOKEN": "..." } },
  "issues": { "type": "http", "url": "http://127.0.0.1:9310/mcp", "headers": { "Authorization": "Bearer ..." } }
}

An entry that is neither shape, or that is missing the one its own type needs, is one warning in the log and is left out: one server nobody can reach is a gap in one agent's reach, where a wrong port is a daemon that would not run at all. A value in env or in headers is a credential, so each answers <set> here and over the API alike.

plugins names what is loaded at startup: a package, a path, or a package installed in the configuration directory. Naming one runs its code in this process with this process's permissions, which is why installing a plugin is the trust decision. A plugin is loaded once and its options make its variants, so an entry may be an object naming one with its options and enabled - PLUGINS.md.

Root config ​

Root config is the record a client pushes to ahp-root:// with root/configChanged, kept per host and between starts, and read back on every root state. Three kinds of key live in it. The host's own are the ones this host acts on. The settings VS Code's agent host declares are declared here in full and read back, though only six change what this host does: globalAutoApproveEnabled, terminalAutoApproveEnabled, terminalAutoApproveRules, editAutoApprovePatterns, canvasesEnabled and agentOrchestrationLimits. The daemon's are the keys of config.json a client may edit.

The host's own schema is what a client draws its controls from. A key in the schema is a promise that pushing it changes something, except a readOnly one, which a client reads and the host says.

KeyValuesDefaultWhat it changes
defaultShellabsolute paththe system shellThe shell a host-managed terminal opens
workspaceTrust{ "enabled": bool, "trustedUris": [uri] }noneWhich folders the host's sessions may load their projects from. readOnly: a window pushes it, it is not a control
ahpd.restartNeededtrueabsentNothing: the host sets it with its own root/configChanged when a change it took waits for a restart, and a new daemon starts without it. readOnly, so a client draws no control for it. A client's push of it goes out as sent, and every reader's root holds the value pushed, as VS Code's host takes a root push as given

Beside them the schema declares every key VS Code's agent host declares at 7516b04bc94. They come from packages/sdk/src/vscoderootconfig.ts, each with the property VS Code gives it: telemetryLevel, globalAutoApproveEnabled, showExternalSessions, agentMerge.* and the rest. Six of those are read here: globalAutoApproveEnabled, which trust.ts asks before a tool call runs; terminalAutoApproveEnabled, terminalAutoApproveRules and editAutoApprovePatterns, which host/spawn.ts answers a session's commands from; canvasesEnabled, which host/canvases.ts asks at each plugin canvas call; and agentOrchestrationLimits, which host/tooling.ts asks before the session tools check a spawn's depth or count what a tree made - TOOLS.md. canvasesEnabled is off by default, and while it is off openCanvas, updateCanvas and closeCanvas are refused - PLUGINS.md. The rest are declared and nothing more. A client draws its settings pane from the schema, so a key it cannot find is a control it cannot draw.

Three keys VS Code declared before 1.140 are not declared: artifactToolsCompactPrompts, deferredTitleGeneration and activeAgentTitleGeneration. The artifact tools carry one wording, and every session runs under the deferred title strategy.

A provider's settings are declared beside them, as VS Code registers a provider's configuration: each registration in HostOptions.providerConfigurations, which a plugin's registerProviderConfiguration fills, adds its properties to the schema at the top of the root config, its default held where nothing set the key, and the rest of it, { provider, title, description, settings, configurationFile? }, is one entry of the root's _meta['vscode.agentCustomizationSettings'], the page a client draws the provider's settings on. A key the host's own schema declares stays the host's - agentConfigurationService.ts.

Every key is one value for the whole host, which the last push from any window sets and every connection reads back, as VS Code's host keeps one root config for every window: defaultShell, workspaceTrust, terminalAutoApproveEnabled, terminalAutoApproveRules and editAutoApprovePatterns among them. The terminal rules, the edit patterns and the trust answer every session's turns whoever sent them, and a start nobody sent, as VS Code's host reads each of them for every question and every session. The declaration is decision The root config declares every key VS Code pushes, as the reference declares it, and keeps every key a client pushes: every key a push carries is applied and kept, declared or not, as VS Code's host applies a root patch, and a push that moves a backend's account is refused as a read-only property's is.

The host writes what it holds to HostOptions.rootConfigStore after each push and after an Always Allow, whole and a backend's account aside, as VS Code's host writes its own; the daemon's store is root-config.json beside config.json. A start brings back the keys the schema declares, a provider's among them, each with a value its property's type and enum accept, as VS Code's host restores its values schema by schema. Of those, globalAutoApproveEnabled, autoApprovePolicyRestricted, terminalAutoApproveEnabled, editAutoApprovePatterns, autoReplyEnabled and workspaceTrust wait for each window's next push: they are VS Code's client-owned approval and policy keys, and a value one window left could grant again what was tightened while the host was stopped. A host given no store holds its root config for as long as the process runs.

One value is in config.values and in no schema at all: the account each agent's harness is signed in as, under vscode.codexAccount for Codex - the key VS Code's window reads the account of its own host's Codex agent from - and ahpd.<provider>Account for every other backend. Nobody declares it, and only the host moves it: the host writes it when a probe answers with an account or a running session reports one, and a client's push that moves it is refused in the words VS Code's host refuses a remote client's change to a read-only property, Host configuration property is read-only: <key>. The email in it is the operator's own, so under a people directory a connection that is not root and does not hold account:read is shown no account value at all, in the state it subscribes to and in every change after it; a host with no directory shows it to every connection.

The daemon's half is added to the same schema, and config:read is what a connection needs to be shown it. It is paths, port, host, httpApi, routes, modelProxy, updateCheck, advancedTools, sessionTools, sessionToolsProviders, closedChats, unofferedModel, workspacelessFolder, turnSenders, backendBackgroundWork, agentOrchestrationLimitsScope, archiveDirtyWorktree, pullRequestLookup, wire and mcpServers, and each configured plugin is one more key, plugins.<id> by its id, whose value is { enabled, options } - so one plugin is one key and its variants are its own options. Nothing else the file holds is there: stdio, configFile, noCwd, worktreesRoot, clientToolTimeoutMs, the connection token keys, requireIssuer, issuer, resource, users, automations and sessions are still edited the way they always were.

Pushing a key acts in one of two ways, and the answer says which.

  • advancedTools, sessionTools, sessionToolsProviders, closedChats, unofferedModel, workspacelessFolder, turnSenders, backendBackgroundWork, agentOrchestrationLimitsScope, archiveDirtyWorktree, pullRequestLookup, wire and mcpServers apply to this daemon as written. advancedTools changes the tools every running session's model is offered at once; the two session tool keys are rebuilt per session, since a provider list is not the same answer for all of them, and each running session is told its own set; the wire capture starts, moves or stops; mcpServers is read again for the next session opened, while a running session keeps the servers it started with. closedChats is read when the next chat is closed, so no session is rebuilt and none is told. unofferedModel is read as the next turn is sent. workspacelessFolder is read as the next session is made. archiveDirtyWorktree is read when the next archived session gives its tree back. pullRequestLookup is read by the next pass over merged sessions.
  • Every other key is written to config.json and the answer marks a restart as needed: the root's config carries ahpd.restartNeeded: true, set by the host's own root/configChanged, which every reader of root is shown whether or not it may see the keys the notice is about. A connection watching the root is also sent x-ahpd/restartNeeded with { channel: "ahp-root://" } once, when the mark is set: it is an x-ahpd extension, which a client that does not know it ignores. ahpd restart applies it.

A write to the daemon's file that no client pushed, a plugin switched, installed or removed through x-ahpd-plugins or ahpd plugin, or a folder added or removed through ahpd paths, is said on the root too: the host sends the root/configChanged that carries every daemon key the file now answers differently, and null for a key it no longer holds, so a client that watched and one that subscribes afterwards read the same values. The schema is the one the root opened with, since no protocol action carries a schema, so a plugin installed while the daemon runs has its value in config.values and its property in the schema from the next start.

That split, and the reason it is per key rather than all-or-nothing, is decision A configuration change applies live where the key can, and otherwise on ahpd restart.

A key shows what the file holds rather than what this run is using, and when a start flag overrode it the key's description says so. A credential is never sent back: every value a schema marks writeOnly, or secret, however deep in its options the mark sits, is answered as <set>, here and over the API alike, and a client that sends that back has said the credential is left as it is. A client drawing a record's form reads the same two keywords off the record's schema: a field marked secret is one a read answers as { "$secret": "<name>" }, so the field is drawn as set and the value is never asked for again.

Commands ​

The verbs that read or change this host's own settings, one line each. The rest are REFERENCE.md.

CommandWhat it does
ahpd configPrint every file it read, then each key and its value, each naming the file that set it
ahpd configureAsk at the terminal for each setting a first install needs, and write them
ahpd statusSay whether a daemon is running, and where
ahpd restartStop it and start it again with the same line, which is what applies a change that is not live

Grants ​

WhatGrantWhere it is asked
Read the daemon's own settings in root stateconfig:readseesConfig, and the status command
List the plugins the configuration namesplugin:listThe plugin list command, and x-ahpd-plugins
List the adapters the host servesconnector:listx-ahpd-adapters
List the engines the host servesagent:listx-ahpd-engines
Subscribe to the connectors channelconnector:listx-ahpd-connectors
List the caller's own, their teams' and the host's connectorsconnector:listx-ahpd-connectors, and no other person's connector with it
List every connectorconnector:allx-ahpd-connectors, and it is admitted without connector:list
List the connector choices of a form fieldconnector:list, or connector:allx-ahpd/completions, and the host's and the caller's own connectors only
Make or change a connectorconnector:put, and connector:host for a host connectorx-ahpd/connectors/put
Remove a connectorconnector:remove, and connector:host for a host connectorx-ahpd/connectors/remove
Check a connectorconnector:put, and connector:host for a host connectorx-ahpd/connectors/check
Change a root config keyconfig:changeroot/configChanged, and a replace - config:write covers it
Push workspaceTrusttrust:pushThe same action, when workspaceTrust is the one key it carries - trust:write covers it
Read the account an agent bills toaccount:readseesAccount, on the root state a connection subscribes to and on every root/configChanged after it
Stop the daemonconfig:changeThe shutdown command
Edit the configuration over HTTPconfig:writeGET /api/config; the plugin verbs that write take plugin: grants, and install, update and remove are the deployment token's

See also ​

REFERENCE.mdThe process: its verbs and its flags
CONFIGURE.mdHow the daemon reads its configuration
AHP.mdThe root channel's actions and their origins
AUTHENTICATION.mdThe door, the tokens and the seven keys about who may connect
RESOURCES.mdThe schemes this host serves and who may read them
PLUGINS.mdWhat a plugin contributes to a host