Agentic AI Atlasby a5c.ai
OverviewWikiGraphFor AgentsEdgesSearchWorkspace
/
GitHubDocsDiscord
iiRecord
Agentic AI Atlas · `adapters launch` — Unified Harness Launcher
page:docs-adapters-archive-design-launchera5c.ai
Search record views/
Record · tabs

Available views

II.Record viewspp. 1 - 1
overviewarticlejsongraph
II.
Page JSON

page:docs-adapters-archive-design-launcher

Structured · live

`adapters launch` — Unified Harness Launcher json

Inspect the normalized record payload exactly as the atlas UI reads it.

File · wiki/docs/adapters/archive/design/launcher.mdCluster · wiki
Record JSON
{
  "id": "page:docs-adapters-archive-design-launcher",
  "_kind": "Page",
  "_file": "wiki/docs/adapters/archive/design/launcher.md",
  "_cluster": "wiki",
  "attributes": {
    "nodeKind": "Page",
    "sourcePath": "docs/adapters/archive/design/launcher.md",
    "sourceKind": "repo-docs",
    "title": "`adapters launch` — Unified Harness Launcher",
    "displayName": "`adapters launch` — Unified Harness Launcher",
    "slug": "docs/adapters/archive/design/launcher",
    "articlePath": "wiki/docs/adapters/archive/design/launcher.md",
    "article": "\n# `adapters launch` — Unified Harness Launcher\n\n> Archived design document. Preserved for historical context; not part of the current normative `reference/` contract.\n\n**Specification v1.0** | `@a5c-ai/adapters-cli`\n\n---\n\n## 1. Overview\n\n`adapters launch` is a CLI command that launches (or resumes) an interactive or non-interactive coding agent session with full stdin/stdout passthrough. Unlike `adapters run`, which parses and normalizes agent output into the `AgentEvent` stream, `adapters launch` acts as a **transparent proxy** — the user interacts directly with the harness as if they invoked it natively.\n\nThe key differentiation:\n\n| Concern | `adapters run` | `adapters launch` |\n|---|---|---|\n| Output format | Normalized `AgentEvent` stream | Raw harness output (bypass) |\n| Input format | `RunOptions` / SDK API | Raw stdin passthrough |\n| Provider config | N/A (each harness's own) | Unified provider/model resolution |\n| Proxy orchestration | No | Yes (`--with-proxy-if-needed`) |\n| Use case | Programmatic orchestration, multi-agent | Direct harness usage with provider flexibility |\n\n### 1.1 Cross-References\n\n| Concept | Spec |\n|---|---|\n| Provider/model configuration | `docs/adapters-provider-config.md` |\n| `adapters-proxy` bridge package | `docs/provider-adapter.md` |\n| Adapter system | `05-adapter-system.md` |\n| Built-in adapters | `12-built-in-adapters.md` |\n| CLI reference | `10-cli-reference.md` |\n| Process lifecycle | `11-process-lifecycle-and-platform.md` |\n\n---\n\n## 2. Command Syntax\n\n```\nadapters launch <harness> [provider] [flags...]\n```\n\n### 2.1 Positional Arguments\n\n| Argument | Required | Description |\n|---|---|---|\n| `<harness>` | Yes | Target harness name. Must be a registered `SubprocessAdapter.agent` value: `claude`, `codex`, `gemini`, `opencode`, `copilot`, `cursor`, `pi`, `omp`, `openclaw`, `hermes`, `droid`, `amp`, `qwen` |\n| `[provider]` | No | Provider/backend identifier. If omitted, uses the harness's default native provider. See §3 for the full taxonomy. |\n\n### 2.2 Flags\n\n#### Provider Configuration\n\n| Flag | Short | Type | Description |\n|---|---|---|---|\n| `--model` | `-m` | `string` | Model identifier (provider-specific format). Required for non-default providers. |\n| `--api-key` | | `string` | API key for the target provider. Can also be set via provider-specific env vars. |\n| `--api-base` | | `string` | Custom API base URL. Overrides provider defaults. |\n| `--region` | | `string` | Cloud region (for Bedrock, Vertex). |\n| `--project` | | `string` | Cloud project ID (for Vertex, Foundry). |\n| `--resource-group` | | `string` | Resource group (for Azure/Foundry). |\n| `--endpoint-name` | | `string` | Named deployment/endpoint (Azure, Foundry, Bedrock). |\n| `--transport` | `-t` | `string` | Wire protocol the harness should speak. One of: `anthropic`, `openai-chat`, `openai-responses`, `google`. Default: auto-detected from harness+provider. |\n| `--profile` | | `string` | Named provider profile from `~/.adapters/providers.json`. |\n| `--auth-command` | | `string` | External command that emits a bearer token on stdout. |\n\n#### Proxy Control\n\n| Flag | Type | Default | Description |\n|---|---|---|---|\n| `--with-proxy-if-needed` | `boolean` | `false` | Launch `adapters-proxy` automatically if the harness cannot speak the provider's native transport directly. |\n| `--with-proxy` | `boolean` | `false` | Force proxy launch even if the harness supports the provider natively. Useful for observability/logging. |\n| `--no-proxy` | `boolean` | `false` | Explicitly disable proxy. Error if the harness cannot reach the provider without one. |\n| `--proxy-port` | `number` | `0` (auto) | Port for the proxy server. `0` = ephemeral port. |\n| `--proxy-log-level` | `string` | `warn` | Log level for the proxy process: `debug`, `info`, `warn`, `error`. |\n\n#### Session Control\n\n| Flag | Short | Type | Description |\n|---|---|---|---|\n| `--resume` | `-r` | `string` | Resume an existing session by ID or name. Passes the appropriate resume flag to the harness. |\n| `--session-id` | `-s` | `string` | Explicit session ID for a new session. |\n\n#### Execution Mode\n\n| Flag | Short | Type | Description |\n|---|---|---|---|\n| `--prompt` | `-p` | `string` | Initial prompt. If set, runs in **non-interactive** mode: sends the prompt, streams output, and exits when the harness exits. If omitted, runs in **interactive** mode with full stdin/stdout passthrough. |\n| `--max-turns` | | `number` | Turn limit (non-interactive mode). |\n| `--max-budget-usd` | | `number` | Cost limit (where harness supports it). |\n\n#### Harness Passthrough\n\n| Flag | Type | Description |\n|---|---|---|\n| `--harness-args` | `string[]` | Raw arguments forwarded verbatim to the harness CLI after all adapters-managed args. Use `--` separator: `adapters launch claude api -- --bare --verbose` |\n\n#### General\n\n| Flag | Short | Type | Default | Description |\n|---|---|---|---|---|\n| `--json` | | `boolean` | `false` | Output machine-readable JSON for launch status and proxy lifecycle events (does not affect harness output). |\n| `--debug` | `-d` | `boolean` | `false` | Debug mode. Logs proxy and harness process details. |\n| `--dry-run` | | `boolean` | `false` | Print the resolved command, env vars, and proxy config without executing. |\n\n---\n\n## 3. Provider Taxonomy\n\nProviders are organized into categories. Each provider implies a specific wire transport protocol and authentication mechanism.\n\n### 3.1 Provider Categories\n\n| Category | Provider IDs | Wire Protocol | Auth Mechanism |\n|---|---|---|---|\n| **Direct API** | `api` | Provider-native | API key |\n| **Cloud (AWS)** | `bedrock` | Bedrock Converse / Anthropic Messages | AWS IAM / STS / Profile |\n| **Cloud (GCP)** | `vertex` | Vertex AI / Google GenAI | ADC / Service Account / OAuth |\n| **Cloud (Azure)** | `azure`, `foundry` | Azure OpenAI / Foundry | API key / AD token / SPN |\n| **OAuth** | `oauth` | Provider-native | OAuth2 browser flow |\n| **Local** | `local`, `ollama` | OpenAI Chat / Responses | None (localhost) |\n| **Custom** | `custom` | Any (requires `--transport`) | Any (via flags) |\n\n### 3.2 Provider ↔ Harness Native Support Matrix\n\nThis matrix defines which harness/provider combinations work **without** a proxy:\n\n| | `api` | `bedrock` | `vertex` | `azure` | `foundry` | `oauth` | `local` | `ollama` |\n|---|---|---|---|---|---|---|---|---|\n| **claude** | ✅ Anthropic | ✅ Built-in | ✅ Built-in | ❌ | ✅ Built-in | ✅ Browser | ❌ | ⚠️ via `ANTHROPIC_BASE_URL` |\n| **codex** | ✅ OpenAI | ❌ | ❌ | ❌ | ❌ | ✅ `codex login` | ❌ | ✅ `--oss` / config.toml |\n| **gemini** | ✅ Google | ❌ | ✅ ADC | ❌ | ❌ | ✅ Browser | ❌ | ❌ |\n| **opencode** | ✅ Multi | ✅ SDK | ✅ SDK | ✅ SDK | ❌ | ❌ | ❌ | ⚠️ OpenAI-compat |\n| **copilot** | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ GitHub | ❌ | ❌ |\n| **cursor** | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |\n\nLegend: ✅ = native support, ⚠️ = works with env var hack, ❌ = not supported (proxy required)\n\n### 3.3 Transport Protocol Registry\n\n| Transport ID | Description | Endpoint Format | Used By |\n|---|---|---|---|\n| `anthropic` | Anthropic Messages API | `POST /v1/messages` (SSE streaming) | Claude Code |\n| `openai-chat` | OpenAI Chat Completions | `POST /v1/chat/completions` | Codex (wire_api=chat), OpenCode |\n| `openai-responses` | OpenAI Responses API | `POST /v1/responses` | Codex (wire_api=responses) |\n| `google` | Google GenerateContent | `POST /v1beta/models/:model:generateContent` | Gemini CLI |\n\n---\n\n## 4. Launch Resolution Algorithm\n\nWhen `adapters launch <harness> [provider] [flags]` is invoked, the following resolution steps execute in order:\n\n### Step 1: Validate Harness\n\n```\n1. Look up <harness> in AdapterRegistry\n2. If not found → error: \"Unknown harness '<harness>'. Available: <list>\"\n3. Verify adapter is SubprocessAdapter type\n4. If not subprocess → error: \"Harness '<harness>' is a <type> adapter and cannot be launched via CLI\"\n```\n\n### Step 2: Resolve Provider\n\n```\n1. If <provider> is given, resolve from provider taxonomy (§3.1)\n2. If --profile is given, load profile from ~/.adapters/providers.json, merge with flags\n3. If neither, use harness default:\n   - claude → api (Anthropic)\n   - codex → api (OpenAI)\n   - gemini → api (Google)\n   - opencode → infer from env vars\n4. Validate required auth for provider (--api-key, env vars, or --auth-command)\n```\n\n### Step 3: Resolve Transport\n\n```\n1. If --transport is explicit, use it\n2. Otherwise, infer from harness native protocol:\n   - claude → anthropic\n   - codex → openai-responses (or openai-chat if configured)\n   - gemini → google\n   - opencode → openai-chat\n3. Record resolved transport as T_harness\n4. Record provider's native transport as T_provider\n```\n\n### Step 4: Determine Proxy Necessity\n\n```\n1. Check native support matrix (§3.2) for (harness, provider) pair\n2. If natively supported:\n   a. If --with-proxy → proxy = FORCE (user wants it anyway)\n   b. If --no-proxy → proxy = SKIP\n   c. Otherwise → proxy = SKIP (redundant, skip for performance)\n   d. Log: \"Proxy not needed: <harness> speaks <provider> natively\"\n3. If NOT natively supported:\n   a. If --no-proxy → error: \"<harness> does not support <provider> natively.\n      Use --with-proxy-if-needed or configure the harness manually.\"\n   b. If --with-proxy-if-needed or --with-proxy → proxy = REQUIRED\n   c. Otherwise → error: \"<harness> requires a proxy for <provider>.\n      Use --with-proxy-if-needed to auto-launch the proxy.\"\n```\n\n### Step 5: Launch Proxy (if needed)\n\n```\n1. Resolve proxy port (--proxy-port or ephemeral)\n2. Build proxy configuration:\n   - target_provider: provider config (model, api_key, region, project, etc.)\n   - exposed_transport: T_harness (what the harness expects to speak)\n   - port: resolved port\n3. Spawn adapters-proxy process (see docs/provider-adapter.md §5)\n4. Wait for proxy health check (GET /health → 200)\n5. Record proxy URL as PROXY_BASE_URL = http://127.0.0.1:<port>\n6. If proxy fails to start within 15s → error + cleanup\n```\n\n### Step 6: Build Harness Environment\n\nBased on harness identity and whether proxy is active, construct the environment variables and CLI args.\n\n#### Claude Code\n\n```bash\n# Direct (no proxy, api provider)\nANTHROPIC_API_KEY=<key>\nANTHROPIC_MODEL=<model>  # if --model given\nclaude [session-flags] [harness-args]\n\n# Via proxy\nANTHROPIC_BASE_URL=http://127.0.0.1:<port>\nANTHROPIC_API_KEY=\"adapters-proxy\"\nANTHROPIC_AUTH_TOKEN=\"adapters-proxy\"\nclaude [session-flags] [harness-args]\n\n# Bedrock (native)\nCLAUDE_CODE_USE_BEDROCK=1\nAWS_REGION=<region>\nAWS_ACCESS_KEY_ID=<key>  # or use profile\nclaude [session-flags] [harness-args]\n\n# Vertex (native)\nCLAUDE_CODE_USE_VERTEX=1\nGOOGLE_CLOUD_PROJECT=<project>\nGOOGLE_CLOUD_LOCATION=<region>\nclaude [session-flags] [harness-args]\n```\n\n#### Codex\n\n```bash\n# Direct (no proxy, api provider)\nOPENAI_API_KEY=<key>\ncodex [exec] [session-flags] [harness-args]\n\n# Via proxy (proxy exposes OpenAI Responses API)\nOPENAI_BASE_URL=http://127.0.0.1:<port>\nOPENAI_API_KEY=\"adapters-proxy\"\ncodex [exec] [session-flags] [harness-args]\n\n# Ollama (native)\ncodex --oss [session-flags] [harness-args]\n```\n\n#### Gemini CLI\n\n```bash\n# Direct (no proxy, api provider)\nGEMINI_API_KEY=<key>\ngemini [--prompt <prompt>] [harness-args]\n\n# Vertex (native)\nGOOGLE_GENAI_USE_VERTEXAI=true\nGOOGLE_CLOUD_PROJECT=<project>\nGOOGLE_CLOUD_LOCATION=<region>\ngemini [--prompt <prompt>] [harness-args]\n\n# Via proxy (proxy exposes Google GenerateContent)\nCODE_ASSIST_ENDPOINT=http://127.0.0.1:<port>\nGEMINI_API_KEY=\"adapters-proxy\"\ngemini [--prompt <prompt>] [harness-args]\n```\n\n#### OpenCode\n\n```bash\n# Direct (any supported provider)\nOPENCODE_CONFIG_CONTENT='{\"$schema\":\"https://opencode.ai/config.json\",\"provider\":{\"resolved\":{\"npm\":\"@ai-sdk/anthropic\",\"options\":{}}},\"model\":{\"default\":\"resolved/<model>\"}}'\nopencode [session-flags] [harness-args]\n\n# Via proxy (proxy exposes OpenAI Chat Completions)\nOPENCODE_CONFIG_CONTENT='{\"$schema\":\"https://opencode.ai/config.json\",\"provider\":{\"adapters-proxy\":{\"npm\":\"@ai-sdk/openai-compatible\",\"options\":{\"baseURL\":\"http://127.0.0.1:<port>/v1\"}}},\"model\":{\"default\":\"adapters-proxy/<model>\"}}'\nopencode [session-flags] [harness-args]\n```\n\n### Step 7: Spawn Harness Process\n\n```\n1. Resolve full command + args for the harness\n2. If --prompt is set:\n   a. Inject prompt via harness-specific mechanism:\n      - claude: --print <prompt> (or stdin stream-json message)\n      - codex: codex exec <prompt>\n      - gemini: --prompt <prompt>\n      - opencode: (stdin after launch)\n   b. Set nonInteractive = true\n3. If --resume is set:\n   a. Pass harness-specific resume flag:\n      - claude: --resume <id>\n      - codex: codex resume <id>\n      - gemini: (not supported → error)\n      - opencode: --session <id>\n4. Spawn child process with:\n   - stdin: process.stdin (passthrough)\n   - stdout: process.stdout (passthrough)\n   - stderr: process.stderr (passthrough)\n   - env: merged (process.env + harness env + proxy env)\n   - cwd: process.cwd()\n5. Wire SIGINT, SIGTERM, SIGHUP to child process\n6. Register cleanup handler for proxy (if running)\n```\n\n### Step 8: Cleanup on Exit\n\n```\n1. On child process exit:\n   a. If proxy is running:\n      - Send SIGTERM to proxy\n      - Wait up to 5s for graceful shutdown\n      - SIGKILL if needed\n   b. Forward child exit code as adapters exit code\n2. On SIGINT/SIGTERM to adapters:\n   a. Forward signal to child\n   b. Wait for child exit\n   c. Clean up proxy\n   d. Exit with child's code (or 130 for SIGINT)\n```\n\n---\n\n## 5. Interactive vs Non-Interactive Mode\n\n### 5.1 Interactive Mode (default)\n\nWhen no `--prompt` flag is given:\n\n- stdin, stdout, and stderr are passed through directly to the harness\n- adapters does **not** parse or transform the output\n- The user interacts with the harness TUI natively\n- adapters only manages the proxy lifecycle and process signals\n- PTY allocation follows the harness's native preference (most harnesses need a PTY for their TUI)\n\n```bash\n# Interactive Claude Code session via Bedrock\nadapters launch claude bedrock --region us-east-1 --with-proxy-if-needed\n\n# Interactive Codex session with a custom provider\nadapters launch codex custom --api-base https://my-llm.corp.net --api-key $KEY --transport openai-responses\n```\n\n### 5.2 Non-Interactive Mode\n\nWhen `--prompt` is given:\n\n- The prompt is delivered to the harness via its native mechanism\n- stdout and stderr are still passed through (no AgentEvent normalization)\n- The process exits when the harness completes its response\n- Suitable for scripting and CI/CD pipelines\n\n```bash\n# One-shot Claude via Vertex\nadapters launch claude vertex --project my-project --region us-central1 \\\n  -p \"Explain the authentication flow in this codebase\" \\\n  --max-turns 3\n\n# One-shot Codex via Bedrock (needs proxy: Codex speaks OpenAI, Bedrock speaks Anthropic)\nadapters launch codex bedrock --region us-west-2 --model anthropic.claude-sonnet-4 \\\n  --with-proxy-if-needed \\\n  -p \"Fix the failing test in src/auth.ts\"\n```\n\n---\n\n## 6. Dry Run Output\n\n`--dry-run` prints the resolved launch plan as JSON and exits:\n\n```json\n{\n  \"harness\": \"claude\",\n  \"provider\": \"bedrock\",\n  \"transport\": \"anthropic\",\n  \"model\": \"anthropic.claude-sonnet-4-20250514-v1:0\",\n  \"proxyNeeded\": false,\n  \"proxyReason\": \"claude supports bedrock natively via CLAUDE_CODE_USE_BEDROCK\",\n  \"command\": \"claude\",\n  \"args\": [\"--print\", \"--output-format\", \"stream-json\", \"--model\", \"claude-sonnet-4-20250514\"],\n  \"env\": {\n    \"CLAUDE_CODE_USE_BEDROCK\": \"1\",\n    \"AWS_REGION\": \"us-east-1\"\n  },\n  \"harnessArgs\": []\n}\n```\n\nWhen proxy is needed:\n\n```json\n{\n  \"harness\": \"codex\",\n  \"provider\": \"bedrock\",\n  \"transport\": \"openai-responses\",\n  \"model\": \"anthropic.claude-sonnet-4-20250514-v1:0\",\n  \"proxyNeeded\": true,\n  \"proxyReason\": \"codex does not support bedrock natively; proxy bridges bedrock → openai-responses\",\n  \"proxy\": {\n    \"targetProvider\": \"bedrock\",\n    \"targetModel\": \"anthropic.claude-sonnet-4-20250514-v1:0\",\n    \"exposedTransport\": \"openai-responses\",\n    \"port\": 0,\n    \"command\": \"adapters-proxy\",\n    \"env\": {\n      \"ADAPTERS_PROXY_TARGET_PROVIDER\": \"bedrock\",\n      \"ADAPTERS_PROXY_TARGET_MODEL\": \"anthropic.claude-sonnet-4-20250514-v1:0\",\n      \"ADAPTERS_PROXY_EXPOSED_TRANSPORT\": \"openai-responses\",\n      \"ADAPTERS_PROXY_PORT\": \"0\",\n      \"AWS_REGION\": \"us-east-1\"\n    }\n  },\n  \"command\": \"codex\",\n  \"args\": [\"exec\"],\n  \"env\": {\n    \"OPENAI_BASE_URL\": \"http://127.0.0.1:<resolved-port>\",\n    \"OPENAI_API_KEY\": \"adapters-proxy\"\n  },\n  \"harnessArgs\": []\n}\n```\n\n---\n\n## 7. Error Catalog\n\n| Code | Condition | Message Template |\n|---|---|---|\n| `HARNESS_NOT_FOUND` | Unknown harness name | `Unknown harness '{name}'. Available: {list}` |\n| `HARNESS_NOT_INSTALLED` | Harness binary not in PATH | `{harness} is not installed. Install with: {installCommand}` |\n| `PROVIDER_UNSUPPORTED` | Harness+provider combo not feasible | `{harness} cannot use provider '{provider}' (no native support and proxy not enabled)` |\n| `PROXY_REQUIRED` | Harness needs proxy but `--no-proxy` set | `{harness} requires a proxy for {provider}. Remove --no-proxy or use --with-proxy-if-needed` |\n| `PROXY_LAUNCH_FAILED` | adapters-proxy failed to start | `Failed to launch proxy: {error}. Is adapters-proxy installed? (pip install adapters-proxy)` |\n| `PROXY_HEALTH_TIMEOUT` | Proxy didn't become healthy | `Proxy health check timed out after 15s on port {port}` |\n| `AUTH_MISSING` | Required auth not provided | `Provider '{provider}' requires authentication. Set {envVar} or use --api-key` |\n| `TRANSPORT_MISMATCH` | Explicit --transport not feasible | `Transport '{transport}' is not available for {harness}+{provider}` |\n| `RESUME_NOT_SUPPORTED` | Harness doesn't support resume | `{harness} does not support session resumption` |\n| `MODEL_NOT_SPECIFIED` | Provider requires explicit model | `Provider '{provider}' requires --model to be specified` |\n\n---\n\n## 8. Relationship to `adapters run`\n\n`adapters launch` and `adapters run` are complementary:\n\n| | `adapters launch` | `adapters run` |\n|---|---|---|\n| **Primary user** | Humans, scripts wanting raw harness UX | Applications, orchestrators, multi-agent systems |\n| **Output** | Raw harness output (bypass) | Normalized `AgentEvent` stream |\n| **Provider flexibility** | Full (any provider via proxy) | Limited to harness native |\n| **Session management** | Delegates to harness | Managed by adapters SessionManager |\n| **Cost tracking** | Delegated to harness | Tracked by adapters |\n| **Hooks** | Not fired (bypass) | Full hook lifecycle |\n| **Multi-agent** | Single harness only | Dispatch across multiple agents |\n\nA future enhancement could add `--observe` to `adapters launch` that tees the harness output to both stdout (raw) and an internal parser (for cost tracking and session recording), without transforming the user-facing output.\n\n---\n\n## 9. Implementation Notes\n\n### 9.1 Package Location\n\nThe `launch` command is implemented in `packages/cli/src/commands/launch.ts` as part of the existing `@a5c-ai/adapters-cli` package. It reuses:\n\n- `AdapterRegistry` for harness lookup and capability checking\n- `BaseAgentAdapter.detectInstallation()` for binary discovery\n- `BaseAgentAdapter.detectAuth()` for auth validation\n- Provider resolution from `@a5c-ai/comm-adapter` (new module: `provider-config.ts`)\n\n### 9.2 Proxy Process Management\n\nThe proxy is spawned as a detached child process with stdio set to `pipe` (not inherited). Its stdout/stderr are captured and logged at the `--proxy-log-level`. The proxy PID is tracked via `ProcessTracker` for cleanup guarantees.\n\n### 9.3 Signal Handling\n\nOn Windows, `SIGINT` is not reliable for child processes. The launcher uses `process.kill(child.pid, 'SIGTERM')` and falls back to `taskkill /PID <pid> /F` after timeout.\n\n### 9.4 PTY Allocation\n\nInteractive mode allocates a PTY for harnesses that require it (most TUI-based harnesses). The `node-pty` library is used, matching the existing `SpawnRunner` implementation. Non-interactive mode uses plain pipes.\n",
    "documents": []
  },
  "outgoingEdges": [],
  "incomingEdges": [
    {
      "from": "page:docs-adapters-archive-design",
      "to": "page:docs-adapters-archive-design-launcher",
      "kind": "contains_page"
    }
  ]
}

Shortcuts

Back to overview
Open graph tab