Echolot
Referencia

Archivos del espacio de trabajo

El formato del espacio de trabajo, archivo por archivo y clave por clave, para leer diffs, escribir archivos a mano y generarlos.

Un espacio de trabajo es una carpeta que termina en .echolot con archivos TOML sencillos dentro: uno por solicitud, entorno, servidor MCP, mock y flujo. El Finder lo muestra como un único documento; en Terminal, en Git y en tu editor es una carpeta normal. Echolot escribe todos los archivos siempre de la misma manera (las claves en un orden fijo, sin escribir nada que tenga su valor predeterminado), así que un cambio en la app es un cambio pequeño en el diff. Consulta Git y equipos.

Alpenglow.echolot/
  workspace.toml                     the workspace: ID, name, variables, auth, agents, proxy, certificates
  environments/
    staging.toml                     one environment
  requests/
    _folder.toml                     the order of the top level
    _folder.pre.js                   the workspace's pre-request script (and _folder.test.js)
    auth/
      _folder.toml                   a folder: name, order, docs, variables, auth
      sign-in.req.toml               an HTTP request
      sign-in.body.json              its body
      sign-in.pre.js                 its pre-request script
      sign-in.test.js                its test script
    catalog/
      search-products.gql.toml       a GraphQL request
      search-products.graphql        its query
  mcp-servers/
    alpenglow-mcp.toml               an MCP server
  specs/
    alpenglow.yaml                   an OpenAPI document
    shop.graphql                     a GraphQL schema
    inventory.proto                  a protobuf file
  mocks/
    shop.toml                        a mock server: settings and routes
    shop.js                          its routes in JavaScript
  flows/
    place-test-order.flow.toml       a flow
  assistant/
    checking-orders.md               a shared Assistant conversation, to read
    checking-orders.json             the same, to open in the app

Reglas de todos los archivos

  • Los archivos son TOML 1.0, UTF-8.
  • Cada uno empieza con echolot = 1, la versión del formato. Un archivo con un número más alto lo guardó una versión más reciente de Echolot, y Echolot lo dice en lugar de abrirlo.
  • Los nombres de archivo son slugs: letras minúsculas, dígitos y guiones, de 80 caracteres como máximo, creados a partir del nombre del elemento (Sign in es sign-in). El nombre en sí es la clave name.
  • Las rutas entre elementos son slugs unidos con /, relativas a requests/: auth/sign-in, orders.
  • Los campos de texto pueden contener {{variables}} y valores dinámicos.
  • Las listas de cosas son arrays de tablas de TOML ([[headers]]). Todo lo que tiene enabled = false se conserva pero está desactivado; sin la clave, está activado.

Lo que nunca va en los archivos

  • Valores secretos. Una variable secreta se escribe con su nombre y secret = true, sin valor; el valor vive en el llavero de tu Mac. Los campos que necesitan un secreto (una contraseña, la contraseña de un proxy, un secreto de cliente) deben contener una {{variable}} que sea secreta. Echolot ofrece trasladar al llavero una contraseña que escribes, y las importaciones lo hacen por sí solas. Consulta secretos.
  • Los tokens OAuth y los inicios de sesión de MCP: en el llavero.
  • Los valores que fijan los scripts con pm.environment.set y similares: duran lo que dure la ventana o el comando.
  • El historial y las respuestas: en Application Support de tu Mac, un historial por espacio de trabajo. Consulta historial.
  • Tu propia disposición: la disposición de los paneles y sus tamaños, las pestañas abiertas, el entorno que elegiste.

Así que un espacio de trabajo se puede confirmar y compartir sin riesgo. Un compañero fija sus propios valores secretos.

workspace.toml

# Echolot workspace. Requests live in requests/, one file each.
echolot = 1
id = "0b7d4c1e-2f6a-4e38-9c51-7a1e3d9b5f20"
name = "Alpenglow"

[[variables]]
name = "baseURL"
value = "https://demo.echolot.dev/v1"

[[variables]]
name = "token"
secret = true
ClaveSignificado
idEl ID del espacio de trabajo. Los secretos del llavero le pertenecen, así que las copias con el mismo ID los comparten. Una copia exportada recibe uno nuevo.
nameEl nombre del espacio de trabajo.
[[variables]]Las variables del espacio de trabajo. Consulta variables.
[auth]La autenticación de toda solicitud que la hereda. Consulta autenticación. Predeterminado: ninguna.
[agents]Las reglas para los agentes de IA. Consulta agentes.
[proxy]El proxy propio del espacio de trabajo, en lugar del de la app.
[[certificates]]Certificados de CA en los que confiar y certificados de cliente que enviar, por host.

Proxy

ClaveSignificado
modemanual (predeterminado), system, environment (la familia HTTPS_PROXY) o none.
urlEl proxy: http://host:port, https://… o socks5://host:port.
username, passwordLas credenciales del proxy. Escribe la contraseña como una {{variable}} secreta.
bypassLos hosts a los que acceder directamente, como un array.

Certificados

Cada tabla [[certificates]] es una regla para un host:

ClaveSignificado
hostEl host al que se aplica la regla.
trustArchivos PEM de certificados de CA en los que confiar, como un array.
certificateUn certificado de cliente: un archivo PEM, o un archivo .p12/.pfx.
keyLa clave PEM del certificado de cliente, cuando el archivo del certificado no la incluye.
passphraseLa contraseña de la clave o del archivo PKCS#12. Escríbela como una {{variable}} secreta.

Agentes

[agents] define lo que pueden hacer los agentes de IA en este espacio de trabajo, mediante el servidor MCP de Echolot y el Asistente. Consulta agentes.

[agents]
allowed-hosts = ["demo.echolot.dev"]
max-requests = 200
max-requests-per-minute = 30

[agents.rules]
unsafe-send = "ask"
destructive = "refuse"
ClaveSignificado
enabledfalse desactiva los agentes para el espacio de trabajo: no obtienen nada de él. Predeterminado: true.
allowed-hostsHosts que cuentan como propios del espacio de trabajo, además de los que usan sus solicitudes.
max-requestsSolicitudes que puede enviar en total una sesión de agente.
max-requests-per-minuteSolicitudes que puede enviar por minuto una sesión de agente.
[agents.rules]Una regla por tipo de acción: allow, ask o refuse.

Los tipos de acción son read, safe-send, unsafe-send, protected-send, new-host, workspace-write y destructive. Una regla más estricta siempre cuenta. Una más permisiva solo cuenta cuando confías en ella (la app pregunta; la línea de comandos necesita --trust-workspace-policy). protected-send y new-host nunca pueden ponerse en allow.

environments/

Un archivo por entorno; su nombre de archivo es su slug, que usa --env.

echolot = 1
name = "Production"
protected = true

[[variables]]
name = "baseURL"
value = "https://api.alpenglow.example/v1"

[[variables]]
name = "password"
secret = true
ClaveSignificado
nameEl nombre del entorno.
protectedtrue lo convierte en un entorno protegido: cada envío pregunta antes.
[[variables]]Sus variables.

Variables

Igual en workspace.toml, los entornos, las carpetas y las solicitudes:

ClaveSignificado
nameEl nombre de la variable, que se usa como {{name}}.
valueSu valor. Se omite en un secreto.
secrettrue para un secreto: el valor está en el llavero.
enabledfalse la desactiva.

requests/

La carpeta requests contiene el árbol que ves en la barra lateral. Cada carpeta que hay en ella es una carpeta del árbol, y cada archivo de solicitud, una solicitud. El tipo de solicitud viene del sufijo del archivo:

SufijoTipo
.req.tomlHTTP, incluidos los eventos enviados por el servidor (SSE)
.gql.tomlGraphQL
.grpc.tomlgRPC
.ws.tomlWebSocket
.sio.tomlSocket.IO
.mqtt.tomlMQTT
.mcp.tomlUna llamada a un servidor MCP

Junto a una solicitud, con el mismo slug:

ArchivoContiene
<slug>.body.<ext>El cuerpo de la solicitud en su propio formato: .json, .xml, .txt, .html, .graphql o .form.txt.
<slug>.graphqlLa consulta de una solicitud GraphQL.
<slug>.pre.jsEl script previo a la solicitud.
<slug>.test.jsEl script de prueba.

_folder.toml

Cada carpeta tiene uno, y también requests/ mismo, para el nivel superior.

echolot = 1
name = "Auth"
order = ["sign-in", "who-am-i", "client-credentials"]
docs = "Send \"Sign in\" first: it captures the access token into {{token}}."
ClaveSignificado
nameEl nombre de la carpeta. No está en requests/_folder.toml.
orderLos slugs de lo que hay en la carpeta, en el orden que usan la barra lateral y las ejecuciones. Lo que no aparece en la lista va después, ordenado por slug.
docsLa documentación de la carpeta, en Markdown.
specLa especificación que sigue la carpeta, como specs/alpenglow.yaml.
spec-urlDe dónde se obtiene esa especificación, cuando vino de una URL.
agent-toolstrue ofrece las solicitudes de la carpeta a los agentes como herramientas.
[[variables]]Las variables de la carpeta, para todo lo que contiene.
[auth]La autenticación de la carpeta, para todo lo que contiene y la hereda. Predeterminado: heredar.

Junto a él, _folder.pre.js y _folder.test.js son los scripts de la carpeta; en requests/ son los del espacio de trabajo. Se ejecutan para cada solicitud de dentro, del espacio de trabajo hacia abajo hasta la propia solicitud. Una carpeta que sigue una especificación también tiene _spec-lock.json, lo último que tomó de la especificación; deja que Echolot lo mantenga.

Claves de todas las solicitudes

echolot = 1
name = "Sign in"
method = "POST"
url = "{{baseURL}}/auth/token"

[body]
syntax = "json"
file = "sign-in.body.json"

[[headers]]
name = "Content-Type"
value = "application/json"

[[assertions]]
target = "status"
check = "equals"
expected = "200"

[[captures]]
variable = "token"
from = "json"
path = "$.access_token"
scope = "workspace"
secret = true
ClaveSignificado
nameEl nombre de la solicitud.
urlLa URL, con su cadena de consulta. Todos los tipos salvo las llamadas MCP tienen una.
docsLa documentación de la solicitud, en Markdown.
spec-operationLa operación de la especificación a partir de la cual se creó, como POST /auth/token.
[[headers]]name, value y enabled = false para una que está desactivada.
[[disabled-params]]Parámetros de consulta desactivados: name, value. Los que están activados están en la URL.
[[disabled-form-fields]]Campos de formulario desactivados: name, value.
[[variables]]Las variables propias de la solicitud.
[[assertions]]Sus comprobaciones.
[[captures]]Valores que guarda en variables después de cada respuesta.
[auth]Su autenticación. Predeterminado: heredar de su carpeta.
[settings]Ajustes que difieren de los de la app.

Solicitudes HTTP (.req.toml)

ClaveSignificado
methodEl método: GET, POST o cualquier token. Predeterminado: GET.
[body]El cuerpo; ninguno si se omite.

La tabla [body] admite una de tres formas:

FormaClaves
Textosyntax: json, xml, text, html, graphql o form (campos de formulario codificados como URL). file: el archivo del cuerpo junto a la solicitud.
Un archivo transmitido desde el discostream-from: la ruta del archivo.
Multipartsyntax = "multipart" y una tabla [[body.parts]] por parte: name, después value (texto) o file (una ruta), content-type, enabled.

Solicitudes GraphQL (.gql.toml)

echolot = 1
name = "Search products"
url = "{{baseURL}}/graphql"
operation = "SearchProducts"
schema = "specs/shop.graphql"
query-file = "search-products.graphql"
graphql-variables = """
{
  "text": "ultralight"
}"""
ClaveSignificado
query-fileEl archivo junto a la solicitud con la consulta, <slug>.graphql.
operationLa operación que se ejecuta, cuando la consulta tiene varias.
graphql-variablesLas variables de GraphQL, como texto JSON. Los archivos más antiguos las llaman variables.
schemaEl esquema con el que se comprueba y se completa: un archivo de specs/.
transportpost (predeterminado), get, o websocket para las suscripciones.
persisted-queriestrue envía primero solo el SHA-256 de la consulta, y la consulta cuando el servidor no la conoce (automatic persisted queries).
batchtrue envía un documento con varias operaciones como un array, una entrada por operación.
[[uploads]]Subidas de archivos: variable (la variable a la que va el archivo) y path.

Solicitudes gRPC (.grpc.toml)

ClaveSignificado
protoEl archivo .proto que describe el servicio, como specs/inventory.proto.
reflectiontrue usa en su lugar la reflexión del servidor.
serviceEl servicio, como alpenglow.inventory.v1.Inventory.
rpcEl método, como Reserve.
messageEl mensaje como texto JSON; un array de mensajes para un método con streaming del cliente.
deadline-msEl plazo en milisegundos.
compressiongzip o deflate para los mensajes enviados.

Solicitudes WebSocket (.ws.toml)

ClaveSignificado
subprotocolsSubprotocolos que ofrecer, como un array.
[[messages]]Mensajes guardados: name, text, enabled.

Solicitudes Socket.IO (.sio.toml)

ClaveSignificado
versionLa versión de Socket.IO del servidor: 4 (predeterminada), 3 o 2.
pathDónde escucha el servidor. Predeterminado: /socket.io/.
namespaceEl namespace al que unirse, como /support.
socket-authEl payload de autenticación, como texto JSON.
[[emits]]Eventos guardados: name, event, arguments (texto JSON), ack = true para pedir una confirmación, enabled.

Solicitudes MQTT (.mqtt.toml)

ClaveSignificado
version5 (predeterminada) o 3.1.1.
client-idEl ID de cliente; uno aleatorio si está vacío.
clean-startfalse pide al broker que conserve la sesión. Predeterminado: true.
keep-aliveSegundos entre pings. Predeterminado: 60.
[will]El último mensaje (will): topic, payload, qos, retain.
[[subscriptions]]filter, qos (predeterminado: 0), no-local, enabled.
[[messages]]Mensajes guardados para publicar: name, topic, payload, qos, retain, content-type, enabled.

El nombre de usuario y la contraseña son la autenticación Basic de la solicitud.

Llamadas MCP (.mcp.toml)

echolot = 1
name = "search_catalog"
server = "alpenglow-mcp"
tool = "search_catalog"
arguments = """
{
  "query": "ultralight tent",
  "limit": 3
}"""
ClaveSignificado
serverEl slug del servidor en mcp-servers/.
tool, resource, prompt o methodLo que se llama: una herramienta por su nombre, un recurso por su URI, un prompt por su nombre, o un método JSON-RPC sin procesar. Solo uno de ellos.
argumentsLos argumentos como texto JSON.

Aserciones

ClaveSignificado
targetLo que se comprueba: status, header, json, body, time (milisegundos), size (bytes), schema (JSON Schema), graphql-errors, mcp-error, mcp-output-schema, openapi, grpc-status.
namePara header: el nombre de la cabecera.
pathPara json: un JSONPath, como $.items.length.
checkequals, not-equals, contains, not-contains, less-than, at-most, greater-than, at-least, exists, not-exists, matches (una expresión regular), is-type, is-one-of, matches-schema.
expectedEl valor con el que comparar; no se escribe para las comprobaciones que no lo necesitan.
enabledfalse la desactiva.

Consulta scripts y pruebas para saber qué comprobaciones ofrece cada destino.

Capturas

ClaveSignificado
variableLa variable en la que guardar el valor.
fromjson, form, msgpack, xml, header, cookie, status o body.
pathDónde está el valor: un JSONPath, un XPath, el nombre de una cabecera o de una cookie. No se usa con status ni body.
scopeenvironment (predeterminado: el entorno activo) o workspace.
secrettrue guarda el valor como un secreto, en el llavero.
enabledfalse la desactiva.

Una respuesta de 400 o más, o un valor que no está, deja la variable como estaba. Consulta capturas.

Ajustes

ClaveSignificado
timeoutSegundos para todo el intercambio.
rawtrue no envía cabeceras automáticas.
verify-tlsfalse omite la verificación del certificado.
follow-redirectsfalse se detiene ante una redirección.
max-redirectsCuántas redirecciones seguir.
decompressfalse conserva el cuerpo tal como lo codificó el servidor.
cookiesfalse ni envía ni guarda cookies.
http-versionautomatic, http1, http2 o http3.
stream-limitSegundos de escucha de un stream de eventos o de una sesión.

Consulta ajustes de la solicitud.

Autenticación

[auth] tiene un type y las claves de ese tipo. Una solicitud o una carpeta sin [auth] hereda; la predeterminada del espacio de trabajo es ninguna autenticación.

typeClaves
inheritNinguna: toma la de la carpeta.
noneNinguna: sin autenticación, aunque la carpeta tenga alguna.
basic, digestusername, password
bearertoken; prefix cuando no es Bearer
api-keyname, value, in (header o query)
oauth2grant (authorization-code, client-credentials, device-code), authorization-url, token-url, device-authorization-url, client-id, client-secret, scope, audience, redirect-uri; pkce = false para desactivar PKCE; client-authentication = "body" para enviar las credenciales del cliente en el cuerpo en lugar de con Basic; header-prefix cuando no es Bearer
aws-signatureaccess-key-id, secret-access-key, session-token, region, service
jwtalgorithm (HS256, HS384, HS512, RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384), secret, secret-base64, payload, header, issued-at = false para omitir iat, expires-in (segundos, 300 por omisión), in (header o query), prefix, query-name (token por omisión)
hawkid, key, algorithm (sha256 o sha1), ext, payload-hash
edgegridclient-token, client-secret, access-token, max-body (131072 por omisión), headers-to-sign
ntlmusername, password, domain, workstation

Escribe cada contraseña, token y clave como una {{variable}} secreta. Consulta autenticación.

mcp-servers/

Un archivo por servidor MCP; el nombre del archivo es el slug que nombran las llamadas MCP.

echolot = 1
name = "Alpenglow MCP"
transport = "http"
url = "https://demo.echolot.dev/mcp"
ClaveSignificado
nameEl nombre del servidor.
transporthttp (Streamable HTTP) o stdio (un programa que inicia Echolot).
urlPara http: el endpoint.
[[headers]]Para http: name, value, enabled.
commandPara stdio: el programa que se inicia.
argumentsPara stdio: sus argumentos, como un array.
working-directoryPara stdio: la carpeta en la que se inicia.
[[environment]]Para stdio: variables de entorno, name, value, enabled.
[oauth]Ajustes de cliente para un servidor que inicia sesión con OAuth: client-id, client-secret, scope, redirect-uri.

Consulta añadir servidores.

specs/

Archivos de especificación tal cual: documentos OpenAPI (.yaml, .yml, .json), esquemas GraphQL (SDL .graphql, o el resultado de una introspección como JSON) y archivos protobuf (.proto). Echolot los edita en el sitio y conserva tu formato. Las solicitudes y los mocks los nombran por su ruta, como specs/alpenglow.yaml. Consulta especificaciones.

mocks/

Un archivo por servidor mock, y sus rutas en JavaScript junto a él.

echolot = 1
name = "Shop"
spec = "specs/alpenglow.yaml"
port = 4010
delay = 200

[[scenarios]]
operation = "GET /products/{sku}"
status = "404"

[[routes]]
id = "e5f6a7b8"
method = "GET"
path = "/users/{id}"
summary = "One user"

[[routes.responses]]
name = "OK"
status = 200
content-type = "application/json"
headers = [{ name = "X-Request-Id", value = "{{$randomUUID}}" }]
body = """
{
  "id": "{{request.params.id}}",
  "name": "{{$randomFullName}}"
}"""

[[routes.responses]]
name = "Not found"
status = 404
content-type = "application/json"
rules = [{ source = "path", name = "id", value = "0" }]
body = """{ "error": "no user {{request.params.id}}" }"""
ClaveSignificado
nameEl nombre del mock.
specLa especificación que sirve. Sin ella, solo responden las rutas del mock.
portEl puerto. Predeterminado: 4010.
share-on-networktrue responde en todas las interfaces de red, no solo en este Mac.
delayMilisegundos antes de cada respuesta.
failure-ratePorcentaje de solicitudes que reciben un 500 inyectado, de 0 a 100.
validate-requestsfalse responde a las solicitudes que incumplen la especificación. Predeterminado: true.
[[scenarios]]La respuesta elegida para una operación de la especificación: operation (como GET /pets), status, example (el nombre del ejemplo).
[[routes]]Una ruta creada a mano: id (se mantiene mientras la ruta cambia), method (o ANY), path ({id} para un parámetro), summary, enabled = false para una ruta desactivada, response (el nombre de la respuesta predeterminada; la primera si se omite), request-content-type y request-body (lo que envían las solicitudes creadas a partir de ella).
[[routes.responses]]Una respuesta de la ruta anterior: name, status, content-type, headers (name y value), rules (source es path, query, header o body; name; value, con * para cualquiera y vacío para ninguno) y body.

mocks/<slug>.js contiene las rutas del mock en JavaScript, que responden antes que las rutas creadas a mano y la especificación. Para las operaciones de la especificación, las respuestas nunca viven en el mock: los ejemplos van a la especificación. Consulta mocks, rutas y datos falsos y rutas con script.

flows/

Un archivo por flujo, <slug>.flow.toml. Echolot escribe los bloques, las conexiones y las notas en un orden fijo, así que mover un bloque cambia dos líneas.

echolot = 1
name = "Place a test order"
description = "Places an order, then asks a person whether to keep it."

[mcp]
tool = "place_test_order"
description = "Places a test order on the demo shop, asking a person before keeping it."

[[blocks]]
id = "signin"
kind = "request"
title = "Sign in"
position = [330, 250]

[blocks.settings]
request = "auth/sign-in"

[[wires]]
from = "start.run"
to = "signin.run"
ClaveSignificado
name, descriptionEl nombre del flujo y lo que hace.
[mcp]Ofrece el flujo a los agentes como una herramienta: tool (su nombre) y description.
[schedule]Lo ejecuta según una programación: every-minutes, o cron (como "0 6 * * *").
[webhook]Lo ejecuta cuando llega una solicitud: method (POST por omisión) y path.
[[inputs]]Sus entradas: name, type (any, text, number, bool, object, list, secret), description, default, required.
[[blocks]]Sus bloques: id, kind, title, position ([x, y] en el lienzo), paused, color y [blocks.settings] con los ajustes del tipo.
[[wires]]Enlaces: from y to, cada uno block.port.
[[groups]]Grupos de bloques: title, blocks (sus ID), color.
[[notes]]Notas en el lienzo: text, frame ([x, y, width, height]).

Los tipos de bloque y sus ajustes están en bloques.

assistant/

Conversaciones con el Asistente que compartes en el espacio de trabajo: <slug>.md para leer en cualquier editor, y <slug>.json para que Echolot lo vuelva a abrir.

Otros archivos

Los archivos que Echolot no conoce se dejan en paz, así que un README, un .gitignore o archivos de datos pueden vivir en el espacio de trabajo. Los datos que guarda un agente o un flujo (como exports/products.csv) van donde se haya pedido, dentro del espacio de trabajo.

En esta página