diff --git a/README.md b/README.md index 9012434..cabad01 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,14 @@ For the full user-facing documentation, see the [Coasts docs](https://coasts.dev Want a concrete example to explore? Check out the [`coasts-demo` repository](https://github.com/coast-guard/coasts-demo) for a small demo project you can use to try Coasts end to end. +## Harness Demos + +[![Coasts + Claude Code](https://img.youtube.com/vi/yjMFVoOiAW0/maxresdefault.jpg)](https://www.youtube.com/watch?v=yjMFVoOiAW0) + +[![Coasts + Codex](https://img.youtube.com/vi/MDidmMQtaqU/maxresdefault.jpg)](https://www.youtube.com/watch?v=MDidmMQtaqU) + +[![Coasts + Conductor](https://img.youtube.com/vi/mbwilJHlanQ/maxresdefault.jpg)](https://www.youtube.com/watch?v=mbwilJHlanQ) + ## Contributing To contribute, read the [contributing guide](CONTRIBUTING.md) for PR guidelines. diff --git a/coast-guard/src/generated/docs-manifest.json b/coast-guard/src/generated/docs-manifest.json index 59e847f..c1580b4 100644 --- a/coast-guard/src/generated/docs-manifest.json +++ b/coast-guard/src/generated/docs-manifest.json @@ -346,10 +346,10 @@ "files": { "README.md": "# Coasts Documentation\n\n```youtube\nMBGKSKau4sU\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## Installing\n\n- `curl -fsSL https://coasts.dev/install | sh`\n- `coast daemon install`\n\n*If you decide not to run `coast daemon install`, you are responsible for starting the daemon manually with `coast daemon start` every single time.*\n\n## What Are Coasts?\n\nA Coast (**containerized host**) is a local development runtime. Coasts let you run multiple isolated environments for the same project on one machine.\n\nCoasts are especially useful for complex `docker-compose` stacks with many interdependent services, but they are equally effective for non-containerized local dev setups. Coasts support a wide range of [runtime configuration patterns](concepts_and_terminology/RUNTIMES_AND_SERVICES.md) so you can shape the ideal environment for multiple agents working in parallel.\n\nCoasts are built for local development, not as a hosted cloud service. Your environments run locally on your machine.\n\nThe Coasts project is free, local, MIT-licensed, agent-provider agnostic, and agent-harness agnostic software with no AI upsells.\n\nCoasts work with any agentic coding workflow that uses worktrees. No special harness-side configuration is required.\n\n## Why Coasts for Worktrees\n\nGit worktrees are excellent for isolating code changes, but they do not solve runtime isolation by themselves.\n\nWhen you run multiple worktrees in parallel, you quickly hit ergonomic problems:\n\n- [Port conflicts](concepts_and_terminology/PORTS.md) between services that expect the same host ports.\n- Per-worktree database and [volume setup](concepts_and_terminology/VOLUMES.md) that is tedious to manage.\n- Integration test environments that need custom runtime wiring per worktree.\n- The living hell of switching worktrees and rebuilding runtime context each time. See [Assign and Unassign](concepts_and_terminology/ASSIGN.md).\n\nIf Git is version control for your code, Coasts are like Git for your worktree runtimes.\n\nEach environment gets its own ports, so you can inspect any worktree runtime in parallel. When you [check out](concepts_and_terminology/CHECKOUT.md) a worktree runtime, Coasts remap that runtime to your project's canonical ports.\n\nCoasts abstract runtime configuration into a simple modular layer on top of worktrees, so each worktree can run with the isolation it needs without hand-maintaining complex per-worktree setup.\n\n## Requirements\n\n- macOS or Linux\n- Docker Desktop on macOS, or Docker Engine with the Compose plugin on Linux\n- A project using Git\n- Node.js\n- `socat` (`brew install socat` on macOS, `sudo apt install socat` on Ubuntu)\n\n```text\nLinux note: Dynamic ports work out of the box on Linux.\nIf you need canonical ports below `1024`, see the checkout docs for the required host configuration.\n```\n\n## Containerizing Agents?\n\nYou can containerize an agent with a Coast. That might sound like a great idea at first, but in many cases you do not actually need to run your coding agent inside a container.\n\nBecause Coasts share the [filesystem](concepts_and_terminology/FILESYSTEM.md) with your host machine through a shared volume mount, the easiest and most reliable workflow is to run the agent on your host and instruct it to execute runtime-heavy tasks (such as integration tests) inside the Coast instance using [`coast exec`](concepts_and_terminology/EXEC_AND_DOCKER.md).\n\nHowever, if you do want to run your agent in a container, Coasts absolutely support that via [Agent Shells](concepts_and_terminology/AGENT_SHELLS.md). You can build an incredibly intricate rig for this setup including [MCP server configuration](concepts_and_terminology/MCP_SERVERS.md), but it may not interoperate cleanly with the orchestration software that exists today. For most workflows, host-side agents are simpler and more reliable.\n\n## Coasts vs Dev Containers\n\nCoasts are not dev containers, and they are not the same thing.\n\nDev containers are generally designed for mounting an IDE into a single containerized development workspace. Coasts are headless and optimized as lightweight environments for parallel agent usage with worktrees — multiple isolated, worktree-aware runtime environments running side by side, with fast checkout switching and runtime isolation controls for each instance.\n\n## Demo Repo\n\nIf you want a small example project to try with Coasts, start with the [`coasts-demo` repository](https://github.com/coast-guard/coasts-demo).\n\n## Coasts Video Course\n\nIf you prefer video, the [Coasts Video Course](learn-coasts-videos/README.md) covers every core concept in under three minutes each.\n\n", "GETTING_STARTED.md": "# Getting Started with Coasts\n\n```youtube\nJe921fgJ4RY\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## Installing\n\n```bash\ncurl -fsSL https://coasts.dev/install | sh\ncoast daemon install\n```\n\n*If you decide not to run `coast daemon install`, you are responsible for starting the daemon manually with `coast daemon start` every single time.*\n\n## Requirements\n\n- macOS or Linux\n- Docker Desktop on macOS, or Docker Engine with the Compose plugin on Linux\n- A project using Git\n- Node.js\n- `socat` (`brew install socat` on macOS, `sudo apt install socat` on Ubuntu)\n\n```text\nLinux note: Dynamic ports work out of the box on Linux.\nIf you need canonical ports below `1024`, see the checkout docs for the required host configuration.\n```\n\n## Setting Up Coasts in a Project\n\nAdd a Coastfile to the root of your project. Make sure you are not on a worktree when installing.\n\n```text\nmy-project/\n├── Coastfile <-- this is what Coast reads\n├── docker-compose.yml\n├── Dockerfile\n├── src/\n│ └── ...\n└── ...\n```\n\nThe `Coastfile` points at your existing local development resources and adds Coasts-specific configuration — see the [Coastfiles documentation](coastfiles/README.md) for the full schema:\n\n```toml\n[coast]\nname = \"my-project\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\ndb = 5432\n```\n\nA Coastfile is a lightweight TOML file that *typically* points to your existing `docker-compose.yml` (it also works with non-containerized local dev setups) and describes the modifications needed to run your project in parallel — port mappings, volume strategies, and secrets. Place it at your project root.\n\nThe fastest way to create a Coastfile for your project is to let your coding agent do it.\n\nThe Coasts CLI ships with a built-in prompt that teaches any AI agent the full Coastfile schema and CLI. Copy it into your agent's chat and it will analyze your project and generate a Coastfile.\n\n```prompt-copy\ninstallation_prompt.txt\n```\n\nYou can also get the same output from the CLI by running `coast installation-prompt`.\n\n## Your First Coast\n\nBefore starting your first Coast, bring down any running development environment. If you are using Docker Compose, run `docker-compose down`. If you have local dev servers running, stop them. Coasts manage their own ports and will conflict with anything already listening.\n\nOnce your Coastfile is ready:\n\n```bash\ncoast build\ncoast run dev-1\n```\n\nCheck that your instance is running:\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ~/dev/my-project\n```\n\nSee where your services are listening:\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\nEach instance gets its own set of dynamic ports so multiple instances can run side by side. To map an instance back to your project's canonical ports, check it out:\n\n```bash\ncoast checkout dev-1\n```\n\nThis means the runtime is now checked out and your project's canonical ports (like `3000`, `5432`) will route to this Coast instance.\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ✓ ~/dev/my-project\n```\n\nTo bring up the Coastguard observability UI for your project:\n\n```bash\ncoast ui\n```\n\n## What's Next?\n\n- Set up a [skill for your host agent](SKILLS_FOR_HOST_AGENTS.md) so it knows how to interact with Coasts\n", - "SKILLS_FOR_HOST_AGENTS.md": "# Skills for Host Agents\n\nIf you use AI coding agents on the host while your app runs inside Coasts, your\nagent usually needs two Coast-specific pieces of setup:\n\n1. an always-on Coast Runtime section in the harness's project instruction file\n or rule file\n2. a reusable Coast workflow skill such as `/coasts` when the harness supports\n project skills\n\nWithout the first piece, the agent edits files but forgets to use `coast exec`.\nWithout the second, every Coast assignment, log, and UI flow has to be\nre-explained in chat.\n\nThis guide keeps the setup concrete and Coast-specific: which file to create,\nwhat text goes in it, and how that changes by harness.\n\n## Why agents need this\n\nCoasts share the [filesystem](concepts_and_terminology/FILESYSTEM.md) between\nyour host machine and the Coast container. Your agent edits files on the host\nand the running services inside the Coast see the changes immediately. But the\nagent still needs to:\n\n1. discover which Coast instance matches the current checkout\n2. run tests, builds, and runtime commands inside that Coast\n3. read logs and service status from the Coast\n4. handle worktree assignment safely when no Coast is already attached\n\n## What goes where\n\n- `AGENTS.md`, `CLAUDE.md`, or `.cursor/rules/coast.md` — short Coast rules\n that should apply on every task, even if no skill is invoked\n- skill (`.agents/skills/...`, `.claude/skills/...`, or `.cursor/skills/...`)\n — the reusable Coast workflow itself, such as `/coasts`\n- command file (`.claude/commands/...` or `.cursor/commands/...`) — optional\n explicit entrypoint for harnesses that support it; one simple option is to\n have the command reuse the skill\n\nIf one repo uses more than one harness, keep the canonical Coast skill in one\nplace and expose it where needed. See\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md).\n\n## 1. Always-on Coast Runtime rules\n\nAdd the following block to the harness's always-on project instruction file or\nrule file (`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/coast.md`, or equivalent):\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n coast exec --service # service shell\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Use `coast exec --service ` when you need to run inside an app/service container.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\nThis block belongs in the always-on file because the rules should apply on\nevery task, not only when the agent explicitly enters a `/coasts` workflow.\n\n## 2. Reusable `/coasts` skill\n\nWhen the harness supports project skills, save the skill content as a\n`SKILL.md` in your skills directory. The full skill text is in\n[skills_prompt.txt](skills_prompt.txt) (if in CLI mode, use\n`coast skills-prompt`) — everything after the Coast Runtime block is the skill\ncontent, starting from the `---` frontmatter.\n\nIf you are using Codex or OpenAI-specific surfaces, you can optionally add\n`agents/openai.yaml` beside the skill for display metadata or invocation\npolicy. That metadata should live beside the skill, not replace it.\n\n## Harness quick start\n\n| Harness | Always-on file | Reusable Coast workflow | Notes |\n|---------|----------------|-------------------------|-------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | No separate project command file to recommend for Coast docs. See [Codex](harnesses/CODEX.md). |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md` is optional, but keep the logic in the skill. See [Claude Code](harnesses/CLAUDE_CODE.md). |\n| Cursor | `AGENTS.md` or `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` or shared `.agents/skills/coasts/SKILL.md` | `.cursor/commands/coasts.md` is optional. `.cursor/worktrees.json` is for Cursor worktree bootstrap, not Coast policy. See [Cursor](harnesses/CURSOR.md). |\n| Conductor | `CLAUDE.md` | Start with `CLAUDE.md`; use Conductor scripts and settings for Conductor-specific behavior | Do not assume full Claude Code project command behavior. If a new command does not appear, fully close and reopen Conductor. See [Conductor](harnesses/CONDUCTOR.md). |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | This is the most limited harness surface here. Use the Codex-style layout and do not invent a T3-native command layer for Coast docs. See [T3 Code](harnesses/T3_CODE.md). |\n\n## Let the agent set itself up\n\nThe fastest way is to let the agent write the right files itself. Copy the\nprompt below into your agent's chat — it includes the Coast Runtime block, the\n`coasts` skill block, and harness-specific instructions for where each piece\nbelongs.\n\n```prompt-copy\nskills_prompt.txt\n```\n\nYou can also get the same output from the CLI by running `coast skills-prompt`.\n\n## Manual setup\n\n- **Codex:** put the Coast Runtime section in `AGENTS.md`, then put the\n reusable `coasts` skill in `.agents/skills/coasts/SKILL.md`.\n- **Claude Code:** put the Coast Runtime section in `CLAUDE.md`, then put the\n reusable `coasts` skill in `.claude/skills/coasts/SKILL.md`. Only add\n `.claude/commands/coasts.md` if you specifically want a command file.\n- **Cursor:** put the Coast Runtime section in `AGENTS.md` if you want the most\n portable instructions, or in `.cursor/rules/coast.md` if you want a\n Cursor-native project rule. Put the reusable `coasts` workflow in\n `.cursor/skills/coasts/SKILL.md` for a Cursor-only repo, or in\n `.agents/skills/coasts/SKILL.md` if the repo is shared with other harnesses.\n Only add `.cursor/commands/coasts.md` if you specifically want an explicit\n command file.\n- **Conductor:** put the Coast Runtime section in `CLAUDE.md`. Use Conductor\n Repository Settings scripts for Conductor-specific bootstrap or run behavior.\n If you add a command and it does not appear, fully close and reopen the app.\n- **T3 Code:** use the same layout as Codex: `AGENTS.md` plus\n `.agents/skills/coasts/SKILL.md`. Treat T3 Code as a thin Codex-style\n harness here, not as a separate Coast command surface.\n- **Multiple harnesses:** keep the canonical skill in\n `.agents/skills/coasts/SKILL.md`. Cursor can load that directly; expose it to\n Claude Code through `.claude/skills/coasts/` if needed.\n\n## Further reading\n\n- Read the [Harnesses guide](harnesses/README.md) for the per-harness matrix\n- Read [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md) for the shared\n layout pattern\n- Read the [Coastfiles documentation](coastfiles/README.md) to learn the full\n configuration schema\n- Learn the [Coast CLI](concepts_and_terminology/CLI.md) commands for managing\n instances\n- Explore [Coastguard](concepts_and_terminology/COASTGUARD.md), the web UI for\n observing and controlling your Coasts\n", + "SKILLS_FOR_HOST_AGENTS.md": "# Skills for Host Agents\n\nIf you use AI coding agents on the host while your app runs inside Coasts, your\nagent usually needs two Coast-specific pieces of setup:\n\n1. an always-on Coast Runtime section in the harness's project instruction file\n or rule file\n2. a reusable Coast workflow skill such as `/coasts` when the harness supports\n project skills\n\nWithout the first piece, the agent edits files but forgets to use `coast exec`.\nWithout the second, every Coast assignment, log, and UI flow has to be\nre-explained in chat.\n\nThis guide keeps the setup concrete and Coast-specific: which file to create,\nwhat text goes in it, and how that changes by harness.\n\n## Why agents need this\n\nCoasts share the [filesystem](concepts_and_terminology/FILESYSTEM.md) between\nyour host machine and the Coast container. Your agent edits files on the host\nand the running services inside the Coast see the changes immediately. But the\nagent still needs to:\n\n1. discover which Coast instance matches the current checkout\n2. run tests, builds, and runtime commands inside that Coast\n3. read logs and service status from the Coast\n4. handle worktree assignment safely when no Coast is already attached\n\n## What goes where\n\n- `AGENTS.md`, `CLAUDE.md`, or `.cursor/rules/coast.md` — short Coast rules\n that should apply on every task, even if no skill is invoked\n- skill (`.agents/skills/...`, `.claude/skills/...`, or `.cursor/skills/...`)\n — the reusable Coast workflow itself, such as `/coasts`\n- command file (`.claude/commands/...` or `.cursor/commands/...`) — optional\n explicit entrypoint for harnesses that support it; one simple option is to\n have the command reuse the skill\n\nIf one repo uses more than one harness, keep the canonical Coast skill in one\nplace and expose it where needed. See\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md).\n\n## 1. Always-on Coast Runtime rules\n\nAdd the following block to the harness's always-on project instruction file or\nrule file (`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/coast.md`, or equivalent):\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n coast exec --service # service shell\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Troubleshooting\n\nIf you run into issues with harness configuration (e.g. worktrees not being\nfound, `coast lookup` not matching), read the troubleshooting section of the\nrelevant harness doc:\n\n coast docs --path harnesses/CLAUDE_CODE.md\n coast docs --path harnesses/CODEX.md\n coast docs --path harnesses/CONDUCTOR.md\n coast docs --path harnesses/CURSOR.md\n coast docs --path harnesses/T3_CODE.md\n coast docs --path harnesses/SHEP.md\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Use `coast exec --service ` when you need to run inside an app/service container.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\nThis block belongs in the always-on file because the rules should apply on\nevery task, not only when the agent explicitly enters a `/coasts` workflow.\n\n## 2. Reusable `/coasts` skill\n\nWhen the harness supports project skills, save the skill content as a\n`SKILL.md` in your skills directory. The full skill text is in\n[skills_prompt.txt](skills_prompt.txt) (if in CLI mode, use\n`coast skills-prompt`) — everything after the Coast Runtime block is the skill\ncontent, starting from the `---` frontmatter.\n\nIf you are using Codex or OpenAI-specific surfaces, you can optionally add\n`agents/openai.yaml` beside the skill for display metadata or invocation\npolicy. That metadata should live beside the skill, not replace it.\n\n## Harness quick start\n\n| Harness | Always-on file | Reusable Coast workflow | Notes |\n|---------|----------------|-------------------------|-------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | No separate project command file to recommend for Coast docs. See [Codex](harnesses/CODEX.md). |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md` is optional, but keep the logic in the skill. See [Claude Code](harnesses/CLAUDE_CODE.md). |\n| Cursor | `AGENTS.md` or `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` or shared `.agents/skills/coasts/SKILL.md` | `.cursor/commands/coasts.md` is optional. `.cursor/worktrees.json` is for Cursor worktree bootstrap, not Coast policy. See [Cursor](harnesses/CURSOR.md). |\n| Conductor | `CLAUDE.md` | Start with `CLAUDE.md`; use Conductor scripts and settings for Conductor-specific behavior | Do not assume full Claude Code project command behavior. If a new command does not appear, fully close and reopen Conductor. See [Conductor](harnesses/CONDUCTOR.md). |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | This is the most limited harness surface here. Use the Codex-style layout and do not invent a T3-native command layer for Coast docs. See [T3 Code](harnesses/T3_CODE.md). |\n\n## Let the agent set itself up\n\nThe fastest way is to let the agent write the right files itself. Copy the\nprompt below into your agent's chat — it includes the Coast Runtime block, the\n`coasts` skill block, and harness-specific instructions for where each piece\nbelongs.\n\n```prompt-copy\nskills_prompt.txt\n```\n\nYou can also get the same output from the CLI by running `coast skills-prompt`.\n\n## Manual setup\n\n- **Codex:** put the Coast Runtime section in `AGENTS.md`, then put the\n reusable `coasts` skill in `.agents/skills/coasts/SKILL.md`.\n- **Claude Code:** put the Coast Runtime section in `CLAUDE.md`, then put the\n reusable `coasts` skill in `.claude/skills/coasts/SKILL.md`. Only add\n `.claude/commands/coasts.md` if you specifically want a command file.\n- **Cursor:** put the Coast Runtime section in `AGENTS.md` if you want the most\n portable instructions, or in `.cursor/rules/coast.md` if you want a\n Cursor-native project rule. Put the reusable `coasts` workflow in\n `.cursor/skills/coasts/SKILL.md` for a Cursor-only repo, or in\n `.agents/skills/coasts/SKILL.md` if the repo is shared with other harnesses.\n Only add `.cursor/commands/coasts.md` if you specifically want an explicit\n command file.\n- **Conductor:** put the Coast Runtime section in `CLAUDE.md`. Use Conductor\n Repository Settings scripts for Conductor-specific bootstrap or run behavior.\n If you add a command and it does not appear, fully close and reopen the app.\n- **T3 Code:** use the same layout as Codex: `AGENTS.md` plus\n `.agents/skills/coasts/SKILL.md`. Treat T3 Code as a thin Codex-style\n harness here, not as a separate Coast command surface.\n- **Multiple harnesses:** keep the canonical skill in\n `.agents/skills/coasts/SKILL.md`. Cursor can load that directly; expose it to\n Claude Code through `.claude/skills/coasts/` if needed.\n\n## Further reading\n\n- Read the [Harnesses guide](harnesses/README.md) for the per-harness matrix\n- Read [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md) for the shared\n layout pattern\n- Read the [Coastfiles documentation](coastfiles/README.md) to learn the full\n configuration schema\n- Learn the [Coast CLI](concepts_and_terminology/CLI.md) commands for managing\n instances\n- Explore [Coastguard](concepts_and_terminology/COASTGUARD.md), the web UI for\n observing and controlling your Coasts\n", "doc_ordering.txt": "# Top-level\nREADME.md\nGETTING_STARTED.md\nSKILLS_FOR_HOST_AGENTS.md\n\n# Learn Coasts\nlearn-coasts-videos/README.md\nlearn-coasts-videos/coasts.md\nlearn-coasts-videos/ports.md\nlearn-coasts-videos/assign.md\nlearn-coasts-videos/checkout.md\nlearn-coasts-videos/volumes.md\nlearn-coasts-videos/secrets.md\nlearn-coasts-videos/getting-started.md\nlearn-coasts-videos/coast-ui.md\n\n# Harnesses\nharnesses/README.md\nharnesses/CODEX.md\nharnesses/CONDUCTOR.md\nharnesses/CLAUDE_CODE.md\nharnesses/CURSOR.md\nharnesses/T3_CODE.md\nharnesses/SHEP.md\nharnesses/MULTIPLE_HARNESSES.md\n\n# Concepts and Terminology\nconcepts_and_terminology/README.md\nconcepts_and_terminology/COASTS.md\nconcepts_and_terminology/RUN.md\nconcepts_and_terminology/REMOVE.md\nconcepts_and_terminology/FILESYSTEM.md\nconcepts_and_terminology/DAEMON.md\nconcepts_and_terminology/CLI.md\nconcepts_and_terminology/COASTGUARD.md\nconcepts_and_terminology/PORTS.md\nconcepts_and_terminology/PRIMARY_PORT_AND_DNS.md\nconcepts_and_terminology/ASSIGN.md\nconcepts_and_terminology/CHECKOUT.md\nconcepts_and_terminology/LOOKUP.md\nconcepts_and_terminology/VOLUMES.md\nconcepts_and_terminology/SHARED_SERVICES.md\nconcepts_and_terminology/SECRETS.md\nconcepts_and_terminology/BUILDS.md\nconcepts_and_terminology/COASTFILE_TYPES.md\nconcepts_and_terminology/RUNTIMES_AND_SERVICES.md\nconcepts_and_terminology/BARE_SERVICES.md\nconcepts_and_terminology/MIXED_SERVICE_TYPES.md\nconcepts_and_terminology/LOGS.md\nconcepts_and_terminology/EXEC_AND_DOCKER.md\nconcepts_and_terminology/AGENT_SHELLS.md\nconcepts_and_terminology/MCP_SERVERS.md\nconcepts_and_terminology/PERFORMANCE_OPTIMIZATIONS.md\nconcepts_and_terminology/TROUBLESHOOTING.md\n\n# Coastfiles\ncoastfiles/README.md\ncoastfiles/PROJECT.md\ncoastfiles/WORKTREE_DIR.md\ncoastfiles/PORTS.md\ncoastfiles/SHARED_SERVICES.md\ncoastfiles/SERVICES.md\ncoastfiles/SECRETS.md\ncoastfiles/VOLUMES.md\ncoastfiles/ASSIGN.md\ncoastfiles/INHERITANCE.md\ncoastfiles/AGENT_SHELL.md\ncoastfiles/MCP.md\n\n# Recipes\nrecipes/README.md\nrecipes/FULLSTACK_MONOREPO.md\n\n", "installation_prompt.txt": "You are installing Coasts into this project. Coast (containerized host) is a CLI tool that runs multiple isolated development environments on a single machine using Docker-in-Docker containers. Each environment gets its own ports, volumes, and runtime — ideal for parallel worktree workflows.\n\nYour job: analyze this project and generate a Coastfile (a TOML file named \"Coastfile\" at the project root).\n\n=== DOCUMENTATION ===\n\nCoast has built-in docs accessible from the CLI. Use these to understand the full Coastfile schema, volume strategies, assign behavior, and other configuration options before generating a Coastfile.\n\nBrowse the docs tree:\n\n coast docs\n\nThis prints the full docs tree. Start by reading the README files — they provide indexes to help you find the right documentation for each topic:\n\n coast docs --path README.md\n coast docs --path coastfiles/README.md\n coast docs --path concepts_and_terminology/README.md\n\nRead a specific doc:\n\n coast docs --path coastfiles/PROJECT.md\n coast docs --path coastfiles/VOLUMES.md\n\nSearch the docs (semantic search — describe what you're looking for in natural language):\n\n coast search-docs \"how do volume strategies work\"\n coast search-docs \"shared postgres across instances\"\n coast search-docs \"secret injection from environment variables\"\n\nUse the docs to make informed decisions about this project's Coastfile configuration. The coastfiles/ section covers every Coastfile directive in detail.\n\n=== COASTFILE SCHEMA (quick reference) ===\n\n[coast] — Required. Project metadata.\n\n name (string, required) Project identifier used in container/volume naming.\n compose (string, optional) Path to docker-compose.yml relative to the Coastfile.\n runtime (string, optional) \"dind\" (default), \"sysbox\", or \"podman\".\n root (string, optional) Project root override (relative or absolute).\n worktree_dir (string or array, optional) Directory or directories for git worktrees (default: \".worktrees\"). Accepts a single string or an array of strings. Auto-detected from existing worktrees at runtime.\n\n[coast.setup] — Optional. Customize the DinD container itself.\n\n packages (array of strings) Alpine packages to install (e.g. [\"nodejs\", \"npm\", \"git\"]).\n run (array of strings) Arbitrary commands to run during setup.\n\n[ports] — Required (at least one). Map of logical name to port number.\n These ports are forwarded to the host when the coast is checked out.\n\n Example:\n [ports]\n web = 3000\n api = 8080\n postgres = 5432\n\n[volumes.*] — Optional. Per-volume configuration.\n\n strategy \"isolated\" (default) or \"shared\"\n service Compose service name that owns this volume.\n mount Mount path inside the service container.\n snapshot_source (isolated only) Seed from an existing volume name.\n\n Example:\n [volumes.postgres_data]\n strategy = \"isolated\"\n service = \"db\"\n mount = \"/var/lib/postgresql/data\"\n\n[secrets.*] — Optional. Secret extraction and injection.\n\n extractor \"file\", \"env\", \"command\", or \"macos-keychain\"\n inject \"env:VAR_NAME\" or \"file:/path/in/container\"\n ttl Optional expiry (e.g. \"1h\", \"30m\").\n\n Extractor-specific params:\n file: path = \"./path/to/secret\"\n env: var = \"HOST_ENV_VAR\"\n command: run = \"echo secret-value\"\n macos-keychain: item = \"keychain-item-name\"\n\n Example:\n [secrets.db_password]\n extractor = \"env\"\n var = \"DB_PASSWORD\"\n inject = \"env:DATABASE_PASSWORD\"\n\n[inject] — Optional. Non-secret host file/env injection.\n\n env Array of host env var names to forward.\n files Array of host file paths to mount.\n\n Example:\n [inject]\n env = [\"NODE_ENV\", \"DEBUG\"]\n files = [\"~/.ssh/id_ed25519\", \"~/.gitconfig\"]\n\n[shared_services.*] — Optional. Services on the host Docker daemon shared across instances.\n\n image Docker image.\n ports Array of port numbers.\n volumes Array of volume mounts.\n env Inline table of environment variables.\n auto_create_db (bool) Create a per-instance database automatically.\n inject Inject connection string into coast containers.\n\n Example:\n [shared_services.postgres]\n image = \"postgres:16-alpine\"\n ports = [5432]\n volumes = [\"postgres_data:/var/lib/postgresql/data\"]\n env = { POSTGRES_USER = \"dev\", POSTGRES_PASSWORD = \"dev\", POSTGRES_DB = \"app\" }\n auto_create_db = true\n inject = \"env:DATABASE_URL\"\n\n[assign] — Optional. Controls what happens on branch switch (coast assign).\n\n default \"none\", \"restart\", or \"rebuild\"\n [assign.services] Per-service overrides.\n [assign.rebuild_triggers] Per-service file globs that trigger rebuild.\n\n Example:\n [assign]\n default = \"none\"\n [assign.services]\n api = \"restart\"\n worker = \"rebuild\"\n [assign.rebuild_triggers]\n worker = [\"Dockerfile\", \"package.json\"]\n\n[services.*] — Optional. Bare process services (no docker-compose needed).\n\n command Shell command to run.\n port Port number.\n restart \"on-failure\" or \"always\".\n\n Example:\n [services.web]\n command = \"node server.js\"\n port = 3000\n restart = \"on-failure\"\n\n=== EXAMPLE: Minimal (no compose) ===\n\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[ports]\napp = 3000\n\n=== EXAMPLE: With docker-compose ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\npostgres = 5432\nredis = 6379\n\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n\n=== EXAMPLE: With secrets ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\n\n[secrets.api_key]\nextractor = \"env\"\nvar = \"API_KEY\"\ninject = \"env:API_KEY\"\n\n[secrets.ssh_key]\nextractor = \"file\"\npath = \"~/.ssh/id_ed25519\"\ninject = \"file:/run/secrets/ssh_key\"\n\n=== KEY TRADEOFFS TO DISCUSS WITH THE USER ===\n\nBefore generating the Coastfile, ask the user about any ambiguous configuration choices. Here are the main ones:\n\nDatabase and infrastructure strategy — there are three options for services like postgres and redis:\n - Isolated volumes (default): each Coast instance gets its own copy of the data inside its DinD container. Instances cannot interfere with each other. Best when you want per-branch database state.\n - Shared volumes: all instances read and write the same volume inside their DinD containers. Saves disk space but concurrent writes from multiple instances can corrupt data.\n - Shared services: run the database on the host Docker daemon instead of inside each Coast. All instances connect to one shared server. Uses the least memory, supports auto_create_db for per-instance databases on a single postgres, and data outlives instance deletion. Best for large teams or memory-constrained machines.\n - If the project has a database, ask the user which approach they want. Explain the tradeoffs — isolated is safest, shared services is most memory-efficient.\n\nAssign strategy — what happens when switching a Coast between worktrees:\n - \"none\": do nothing (for services like postgres/redis that don't change between branches).\n - \"restart\": restart the container (for interpreted services that just need a process restart).\n - \"rebuild\": rebuild the Docker image and restart (for services where the branch change affects the Dockerfile or build dependencies).\n - If the project has multiple services, ask which ones need rebuilding vs restarting on branch switch.\n\n=== INSTRUCTIONS ===\n\n1. Look at this project's structure. If there is a docker-compose.yml, read it to identify services, ports, and volumes.\n2. Detect the existing git worktree directory. Run `git worktree list` to check if the project already has git worktrees set up.\n - If worktrees exist, examine their paths to determine the common parent directory (e.g., if worktrees are at `../.worktrees/feat-a` and `../.worktrees/feat-b`, the worktree_dir is `\"../.worktrees\"`).\n - Set `worktree_dir` in the Coastfile to match the detected directory.\n - If no worktrees exist, omit `worktree_dir` (Coast defaults to \".worktrees\"). Do NOT use \".coasts\" — that pollutes the project with a Coast-branded directory.\n3. Ask the user if they use any of these coding harnesses with this project:\n - **Claude Code** — worktrees at `.claude/worktrees`\n - **OpenAI Codex** — worktrees at `~/.codex/worktrees`\n - **Cursor** — worktrees at `~/.cursor/worktrees/` (where `` is the coast name from `[coast] name`)\n - **Conductor** — worktrees at `~/conductor/workspaces/`\n - **T3 Code** — worktrees at `~/.t3/worktrees/`\n For each harness the user selects, include its worktree directory in the `worktree_dir` array. Combine these with any directory detected in step 2. If the user selects none and no worktrees were detected in step 2, omit `worktree_dir` (Coast defaults to \".worktrees\").\n4. Read the relevant Coast docs (use `coast docs` and `coast search-docs`) to understand volume strategies, assign behavior, and any configuration options that apply to this project's stack.\n5. Ask the user about any ambiguous configuration choices (see tradeoffs above). Do not guess — explain the options and let them decide.\n6. Generate a Coastfile at the project root based on the project analysis and user input.\n7. If the project has no docker-compose.yml, use [services.*] for bare process definitions or [coast.setup] to install dependencies.\n8. Run `coast build`. If it fails, check the error and consult the docs (`coast search-docs \"\"`) to troubleshoot.\n9. Run `coast run dev-1`. If it fails, check the error and consult the docs.\n10. Run `coast ui` to open the Coastguard dashboard (this is for the user when you are done).\n", - "skills_prompt.txt": "# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (unit tests that are integrated with services or dbs, integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n coast exec --service # service shell\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nAn already occupied Coast can also be reassigned with `coast assign`, but check\nwith the user first because that will disrupt the current slot.\n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Use `coast exec --service ` when you need to run inside an app/service container.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n\n---\nname: coasts\ndescription: Inspect and control Coast instances for the current checkout. Use\n when the user says \"/coasts\", asks to assign or reassign a Coast, wants to\n run commands or read logs in the matching Coast, wants to create a new Coast,\n or explicitly asks to open Coast UI.\n---\n\n# Coasts\n\nUse the Coast CLI directly. Do not add wrappers.\n\n## Orient Yourself\n\nStart by exploring the CLI and docs:\n\n coast # see all available commands\n coast docs # list all doc pages\n coast search-docs \"your question\" # semantic search\n\nWhen anything about Coast behavior is unclear, read the docs before guessing:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\nRoute requests into one of these modes:\n\n1. **Use Coast** — run `coast lookup`, then use `coast exec`, `coast ps`,\n or `coast logs` with the matching instance.\n2. **Create or Assign** — run `coast ls`, then `coast run` to create a new\n Coast or `coast assign` to repoint an existing one.\n3. **Open UI** — run `coast ui`.\n\n## What Runs Where\n\nThe host and the Coast share the filesystem. Only use `coast exec` for things\nthat need running services inside the container.\n\n**Use `coast exec` for:**\n- Integration tests, API tests, anything that needs databases or services\n- Service restarts, compose operations\n- Commands that talk to container-only processes\n\n**Run on the host:**\n- Linting (`eslint`, `rubocop`, `golangci-lint`)\n- Typechecking (`tsc --noEmit`, `go vet`)\n- Formatting (`prettier`, `gofmt`)\n- Git operations\n- Playwright and browser tests\n- Static analysis, code generation\n- Package installs (`npm install`, `pip install`)\n\n## Create and Assign\n\nWhen `coast lookup` returns no match:\n\n1. Run `coast ls` to see available slots.\n2. Prefer `coast run -w ` to create and assign in one step.\n3. If no build exists yet, run `coast build` first.\n4. After creating, rerun `coast lookup` to confirm.\n\nWhen you want to switch an existing Coast to a different worktree:\n\n coast assign -w \n\nThat also works for an already assigned or checked-out Coast, but ask the user\nfirst before reassigning an occupied slot.\n\n## Coastfile Setup\n\nIf the project needs a new or modified Coastfile, read the docs first:\n\n coast docs --path coastfiles/README.md\n\nThe Coastfile docs cover compose setup, ports, volumes, secrets, shared\nservices, bare services, and inheritance.\n\n## Safety Rules\n\n- Run `coast lookup` before taking action and again after any topology change.\n- Ask before `coast assign`, `coast unassign`, or `coast checkout` if it would\n disrupt an existing slot.\n- Prefer creating a new Coast over reusing a checked-out or already-assigned\n one unless the user explicitly wants the existing slot to be reassigned.\n- Use `coast docs` or `coast search-docs` before guessing.\n", + "skills_prompt.txt": "# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (unit tests that are integrated with services or dbs, integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n coast exec --service # service shell\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nAn already occupied Coast can also be reassigned with `coast assign`, but check\nwith the user first because that will disrupt the current slot.\n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Troubleshooting\n\nIf you run into issues with harness configuration (e.g. worktrees not being\nfound, `coast lookup` not matching), read the troubleshooting section of the\nrelevant harness doc:\n\n coast docs --path harnesses/CLAUDE_CODE.md\n coast docs --path harnesses/CODEX.md\n coast docs --path harnesses/CONDUCTOR.md\n coast docs --path harnesses/CURSOR.md\n coast docs --path harnesses/T3_CODE.md\n coast docs --path harnesses/SHEP.md\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Use `coast exec --service ` when you need to run inside an app/service container.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n\n---\nname: coasts\ndescription: Inspect and control Coast instances for the current checkout. Use\n when the user says \"/coasts\", asks to assign or reassign a Coast, wants to\n run commands or read logs in the matching Coast, wants to create a new Coast,\n or explicitly asks to open Coast UI.\n---\n\n# Coasts\n\nUse the Coast CLI directly. Do not add wrappers.\n\n## Orient Yourself\n\nStart by exploring the CLI and docs:\n\n coast # see all available commands\n coast docs # list all doc pages\n coast search-docs \"your question\" # semantic search\n\nWhen anything about Coast behavior is unclear, read the docs before guessing:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\nRoute requests into one of these modes:\n\n1. **Use Coast** — run `coast lookup`, then use `coast exec`, `coast ps`,\n or `coast logs` with the matching instance.\n2. **Create or Assign** — run `coast ls`, then `coast run` to create a new\n Coast or `coast assign` to repoint an existing one.\n3. **Open UI** — run `coast ui`.\n\n## What Runs Where\n\nThe host and the Coast share the filesystem. Only use `coast exec` for things\nthat need running services inside the container.\n\n**Use `coast exec` for:**\n- Integration tests, API tests, anything that needs databases or services\n- Service restarts, compose operations\n- Commands that talk to container-only processes\n\n**Run on the host:**\n- Linting (`eslint`, `rubocop`, `golangci-lint`)\n- Typechecking (`tsc --noEmit`, `go vet`)\n- Formatting (`prettier`, `gofmt`)\n- Git operations\n- Playwright and browser tests\n- Static analysis, code generation\n- Package installs (`npm install`, `pip install`)\n\n## Create and Assign\n\nWhen `coast lookup` returns no match:\n\n1. Run `coast ls` to see available slots.\n2. Prefer `coast run -w ` to create and assign in one step.\n3. If no build exists yet, run `coast build` first.\n4. After creating, rerun `coast lookup` to confirm.\n\nWhen you want to switch an existing Coast to a different worktree:\n\n coast assign -w \n\nThat also works for an already assigned or checked-out Coast, but ask the user\nfirst before reassigning an occupied slot.\n\n## Coastfile Setup\n\nIf the project needs a new or modified Coastfile, read the docs first:\n\n coast docs --path coastfiles/README.md\n\nThe Coastfile docs cover compose setup, ports, volumes, secrets, shared\nservices, bare services, and inheritance.\n\n## Safety Rules\n\n- Run `coast lookup` before taking action and again after any topology change.\n- Ask before `coast assign`, `coast unassign`, or `coast checkout` if it would\n disrupt an existing slot.\n- Prefer creating a new Coast over reusing a checked-out or already-assigned\n one unless the user explicitly wants the existing slot to be reassigned.\n- Use `coast docs` or `coast search-docs` before guessing.\n", "coastfiles/README.md": "# Coastfiles\n\nA Coastfile is a TOML configuration file that lives at the root of your project. It tells Coast everything it needs to know to build and run isolated development environments for that project — which services to run, which ports to forward, how to handle data, and how to manage secrets.\n\nEvery Coast project needs at least one Coastfile. The file is always named `Coastfile` (capital C, no extension). If you need variants for different workflows, you create typed Coastfiles like `Coastfile.light` or `Coastfile.snap` that [inherit from the base](INHERITANCE.md).\n\nFor a deeper understanding of how Coastfiles relate to the rest of Coast, see [Coasts](../concepts_and_terminology/COASTS.md) and [Builds](../concepts_and_terminology/BUILDS.md).\n\n## Quickstart\n\nThe smallest possible Coastfile:\n\n```toml\n[coast]\nname = \"my-app\"\n```\n\nThis gives you a DinD container you can `coast exec` into. Most projects will want either a `compose` reference or [bare services](SERVICES.md):\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\napi = 8080\n```\n\nOr without compose, using bare services:\n\n```toml\n[coast]\nname = \"my-app\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\nrestart = \"on-failure\"\n\n[ports]\nweb = 3000\n```\n\nRun `coast build` then `coast run dev-1` and you have an isolated environment.\n\n## Example Coastfiles\n\n### Simple bare-service project\n\nA Next.js app with no compose file. Coast installs Node, runs `npm install`, and starts the dev server directly.\n\n```toml\n[coast]\nname = \"my-crm\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --turbopack --port 3002 --hostname 0.0.0.0\"\nport = 3002\nrestart = \"on-failure\"\n\n[ports]\nweb = 3002\n```\n\n### Full-stack compose project\n\nA multi-service project with shared databases, secrets, volume strategies, and custom setup.\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./infra/docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"python3\", \"curl\", \"git\", \"bash\", \"ca-certificates\", \"wget\"]\nrun = [\n \"ARCH=$(uname -m | sed 's/aarch64/arm64/' | sed 's/x86_64/amd64/') && wget -qO /tmp/go.tar.gz https://go.dev/dl/go1.24.1.linux-${ARCH}.tar.gz && tar -C /usr/local -xzf /tmp/go.tar.gz && rm /tmp/go.tar.gz\",\n \"GOBIN=/usr/local/bin go install github.com/air-verse/air@v1.61.7\",\n]\n\n[ports]\nweb = 3000\nbackend = 8080\npostgres = 5432\nredis = 6379\n\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\" }\n\n[shared_services.redis]\nimage = \"redis:7\"\nports = [6379]\n\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n\n[secrets.db_password]\nextractor = \"env\"\nvar = \"DB_PASSWORD\"\ninject = \"env:DB_PASSWORD\"\n\n[omit]\nservices = [\"monitoring\", \"admin-panel\", \"nginx-proxy\"]\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### Lightweight test variant (inheritance)\n\nExtends the base Coastfile but strips it down to only what's needed for running backend tests. No ports, no shared services, isolated databases.\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n\n[unset]\nports = [\"web\", \"backend\", \"postgres\", \"redis\"]\nshared_services = [\"postgres\", \"redis\"]\n\n[omit]\nservices = [\"redis\", \"backend\", \"web\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend-test = \"rebuild\"\n```\n\n### Snapshot-seeded variant\n\nEach coast instance starts with a copy of the host's existing database volumes, then diverges independently.\n\n```toml\n[coast]\nextends = \"Coastfile\"\n\n[unset]\nshared_services = [\"postgres\", \"redis\", \"mongodb\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_mongodb_data\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n\n## Conventions\n\n- The file must be named `Coastfile` (capital C, no extension) and live at the project root.\n- Typed variants use the pattern `Coastfile.{type}` — for example `Coastfile.light`, `Coastfile.snap`. See [Inheritance and Types](INHERITANCE.md).\n- The reserved name `Coastfile.default` is not allowed.\n- TOML syntax is used throughout. All section headers use `[brackets]` and named entries use `[section.name]` (not array-of-tables).\n- You cannot use both `compose` and `[services]` in the same Coastfile — pick one.\n- Relative paths (for `compose`, `root`, etc.) are resolved against the Coastfile's parent directory.\n\n## Reference\n\n| Page | Sections | What it covers |\n|------|----------|----------------|\n| [Project and Setup](PROJECT.md) | `[coast]`, `[coast.setup]` | Name, compose path, runtime, worktree dir, container setup |\n| [Worktree Directories](WORKTREE_DIR.md) | `worktree_dir`, `default_worktree_dir` | Local and external worktree dirs, tilde paths, Codex/Claude integration |\n| [Ports](PORTS.md) | `[ports]`, `[egress]` | Port forwarding, egress declarations, primary port |\n| [Volumes](VOLUMES.md) | `[volumes.*]` | Isolated, shared, and snapshot-seeded volume strategies |\n| [Shared Services](SHARED_SERVICES.md) | `[shared_services.*]` | Host-level databases and infrastructure services |\n| [Secrets](SECRETS.md) | `[secrets.*]`, `[inject]` | Secret extraction, injection, and host env/file forwarding |\n| [Bare Services](SERVICES.md) | `[services.*]` | Running processes directly without Docker Compose |\n| [Agent Shell](AGENT_SHELL.md) | `[agent_shell]` | Containerized agent TUI runtimes |\n| [MCP Servers](MCP.md) | `[mcp.*]`, `[mcp_clients.*]` | Internal and host-proxied MCP servers, client connectors |\n| [Assign](ASSIGN.md) | `[assign]` | Branch-switch behavior per service |\n| [Inheritance and Types](INHERITANCE.md) | `extends`, `includes`, `[unset]`, `[omit]` | Typed Coastfiles, composition, and overrides |\n", "coastfiles/AGENT_SHELL.md": "# Agent Shell\n\n> **In most workflows, you do not need to containerize your coding agent.** Because Coasts share the [filesystem](../concepts_and_terminology/FILESYSTEM.md) with your host machine, the simplest approach is to run the agent on your host and use [`coast exec`](../concepts_and_terminology/EXEC_AND_DOCKER.md) for runtime-heavy tasks like integration tests. Agent shells are for cases where you specifically want the agent running inside the container — for example, to give it direct access to the inner Docker daemon or to fully isolate its environment.\n\nThe `[agent_shell]` section configures an agent TUI — such as Claude Code or Codex — to run inside the Coast container. When present, Coast automatically spawns a persistent PTY session running the configured command when an instance starts.\n\nFor the full picture of how agent shells work — the active agent model, sending input, lifecycle and recovery — see [Agent Shells](../concepts_and_terminology/AGENT_SHELLS.md).\n\n## Configuration\n\nThe section has a single required field: `command`.\n\n```toml\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\n### `command` (required)\n\nThe shell command to run in the agent PTY. This is typically a coding agent CLI that you've installed via `[coast.setup]`.\n\nThe command runs inside the DinD container at `/workspace` (the project root). It is not a compose service — it runs alongside your compose stack or bare services, not inside them.\n\n## Lifecycle\n\n- The agent shell spawns automatically on `coast run`.\n- In [Coastguard](../concepts_and_terminology/COASTGUARD.md), it appears as a persistent \"Agent\" tab that cannot be closed.\n- If the agent process exits, Coast can respawn it.\n- You can send input to a running agent shell via `coast agent-shell input`.\n\n## Examples\n\n### Claude Code\n\nInstall Claude Code in `[coast.setup]`, configure credentials via [secrets](SECRETS.md), then set up the agent shell:\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"git\", \"bash\"]\nrun = [\n \"npm install -g @anthropic-ai/claude-code\",\n \"mkdir -p /root/.claude\",\n]\n\n[secrets.claude_credentials]\nextractor = \"keychain\"\nservice = \"Claude Code-credentials\"\ninject = \"file:/root/.claude/.credentials.json\"\n\n[agent_shell]\ncommand = \"cd /workspace; exec claude --dangerously-skip-permissions --effort high\"\n```\n\n### Simple agent shell\n\nA minimal agent shell for testing that the feature works:\n\n```toml\n[coast]\nname = \"test-agent\"\n\n[coast.setup]\npackages = [\"bash\"]\n\n[agent_shell]\ncommand = \"exec sh -c 'while true; do echo agent-heartbeat; sleep 5; done'\"\n```\n", "coastfiles/ASSIGN.md": "# Assign\n\nThe `[assign]` section controls what happens to services inside a Coast instance when you switch branches with `coast assign`. Each service can be configured with a different strategy depending on whether it needs a full rebuild, a restart, a hot-reload, or nothing at all.\n\nFor how `coast assign` and `coast unassign` work at runtime, see [Assign](../concepts_and_terminology/ASSIGN.md).\n\n## `[assign]`\n\n### `default`\n\nThe default action applied to all services on branch switch. Defaults to `\"restart\"` if the entire `[assign]` section is omitted.\n\n- **`\"none\"`** — do nothing. The service keeps running as-is. Good for databases and caches that don't depend on code.\n- **`\"hot\"`** — the code is already live-mounted via the [filesystem](../concepts_and_terminology/FILESYSTEM.md), so the service picks up changes automatically (e.g. via a file watcher or hot-reload). No container restart needed.\n- **`\"restart\"`** — restart the service container. Use when the service reads code at startup but doesn't need a full image rebuild.\n- **`\"rebuild\"`** — rebuild the service's Docker image and restart. Required when code is baked into the image via `COPY` or `ADD` in the Dockerfile.\n\n```toml\n[assign]\ndefault = \"none\"\n```\n\n### `[assign.services]`\n\nPer-service overrides. Each key is a compose service name, and the value is one of the four actions above.\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\nThis lets you leave databases and caches untouched (`\"none\"` via the default) while rebuilding or restarting only the services that depend on the code that changed.\n\n### `[assign.rebuild_triggers]`\n\nFile patterns that force a rebuild for specific services, even if their default action is something lighter. Each key is a service name, and the value is a list of file paths or patterns.\n\n```toml\n[assign]\ndefault = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\", \"package-lock.json\"]\n```\n\n### `exclude_paths`\n\nA list of paths to exclude from worktree sync during `coast assign`. Useful in large monorepos where certain directories are irrelevant to the services running in the Coast and would otherwise slow down the assign operation.\n\n```toml\n[assign]\ndefault = \"none\"\nexclude_paths = [\"apps/ide\", \"apps/extension\", \"apps/ide-extension\"]\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n## Examples\n\n### Rebuild app, leave everything else alone\n\nWhen your app service bakes code into its Docker image but your databases are independent of code changes:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\n### Hot-reload frontend and backend\n\nWhen both services use file watchers (e.g. Next.js dev server, Go air, nodemon) and code is live-mounted:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### Per-service rebuild with triggers\n\nThe API service normally just restarts, but if `Dockerfile` or `package.json` changed, it rebuilds:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napi = \"restart\"\nworker = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\"]\n```\n\n### Full rebuild for everything\n\nWhen all services bake code into their images:\n\n```toml\n[assign]\ndefault = \"rebuild\"\n```\n", @@ -390,13 +390,13 @@ "concepts_and_terminology/TROUBLESHOOTING.md": "# Troubleshooting\n\nMost issues with Coasts come from stale state, orphaned Docker resources, or a daemon that got out of sync. This page covers the escalation path from mild to nuclear.\n\n## Doctor\n\nIf things feel off — instances show as running but nothing responds, ports seem stuck, or the UI shows stale data — start with `coast doctor`:\n\n```bash\ncoast doctor\n```\n\nDoctor scans the state database and Docker for inconsistencies: orphaned instance records with missing containers, dangling containers with no state record, and shared services marked running that are actually dead. It fixes what it finds automatically.\n\nTo preview what it would do without changing anything:\n\n```bash\ncoast doctor --dry-run\n```\n\n## Daemon Restart\n\nIf the daemon itself seems unresponsive or you suspect it is in a bad state, restart it:\n\n```bash\ncoast daemon restart\n```\n\nThis sends a graceful shutdown signal, waits for the daemon to exit, and starts a fresh process. Your instances and state are preserved.\n\n## Removing a Single Project\n\nIf the problem is isolated to one project, you can remove its build artifacts and associated Docker resources without affecting anything else:\n\n```bash\ncoast rm-build my-project\n```\n\nThis deletes the project's artifact directory, Docker images, volumes, and containers. It asks for confirmation first. Pass `--force` to skip the prompt.\n\n## Missing Shared Service Images\n\nIf `coast run` fails while creating a shared service with an error like `No such image: postgres:15`, the image is missing from your host Docker daemon.\n\nThis most commonly happens when your `Coastfile` defines `shared_services` such as Postgres or Redis and Docker has not pulled those images yet.\n\nPull the missing image, then run the instance again:\n\n```bash\ndocker pull postgres:15\ndocker pull redis:7\ncoast run my-instance\n```\n\nIf you are not sure which image is missing, the failing `coast run` output will include the image name in the Docker error. After a failed provisioning attempt, Coasts cleans up the partial instance automatically, so seeing the instance return to `stopped` is expected.\n\n## Factory Reset with Nuke\n\nWhen nothing else works — or you just want a completely clean slate — `coast nuke` performs a full factory reset:\n\n```bash\ncoast nuke\n```\n\nThis will:\n\n1. Stop the `coastd` daemon.\n2. Remove **all** coast-managed Docker containers.\n3. Remove **all** coast-managed Docker volumes.\n4. Remove **all** coast-managed Docker networks.\n5. Remove **all** coast Docker images.\n6. Delete the entire `~/.coast/` directory (state database, builds, logs, secrets, image cache).\n7. Recreate `~/.coast/` and restart the daemon so coast is immediately usable again.\n\nBecause this destroys everything, you must type `nuke` at the confirmation prompt:\n\n```text\n$ coast nuke\nWARNING: This will permanently destroy ALL coast data:\n\n - Stop the coastd daemon\n - Remove all coast-managed Docker containers\n - Remove all coast-managed Docker volumes\n - Remove all coast-managed Docker networks\n - Remove all coast Docker images\n - Delete ~/.coast/ (state DB, builds, logs, secrets, image cache)\n\nType \"nuke\" to confirm:\n```\n\nPass `--force` to skip the prompt (useful in scripts):\n\n```bash\ncoast nuke --force\n```\n\nAfter a nuke, coast is ready to use — the daemon is running and the home directory exists. You just need to `coast build` and `coast run` your projects again.\n\n## Reporting Bugs\n\nIf you hit a problem that is not resolved by any of the above, include the daemon logs when reporting:\n\n```bash\ncoast daemon logs\n```\n", "concepts_and_terminology/VOLUMES.md": "# Volume Topology\n\nCoast provides three volume strategies that control how data-heavy services (databases, caches, etc.) store and share their data across Coast instances. Choosing the right strategy depends on how much isolation you need and how much overhead you can tolerate.\n\n## Shared Services\n\n[Shared services](SHARED_SERVICES.md) run on your host Docker daemon, outside of any Coast container. Services like Postgres, MongoDB, and Redis stay on the host machine and Coast instances route their calls back to the host over a bridge network.\n\n```text\nHost machine\n |\n +--> Postgres (host daemon, existing volume)\n +--> Redis (host daemon, existing volume)\n |\n +--> Coast: dev-1 --connects to--> host Postgres, host Redis\n +--> Coast: dev-2 --connects to--> host Postgres, host Redis\n```\n\nThere is no data isolation between instances — every Coast talks to the same database. In return you get:\n\n- Lighter Coast instances since they do not run their own database containers.\n- Your existing host volumes are reused directly, so any data you already have is available immediately.\n- MCP integrations that connect to your local database continue to work out of the box.\n\nThis is configured in your [Coastfile](COASTFILE_TYPES.md) under `[shared_services]`.\n\n## Shared Volumes\n\nShared volumes mount a single Docker volume that is shared across all Coast instances. The services themselves (Postgres, Redis, etc.) run inside each Coast container, but they all read and write to the same underlying volume.\n\n```text\nCoast: dev-1 --mounts--> shared volume \"my-project-postgres\"\nCoast: dev-2 --mounts--> shared volume \"my-project-postgres\"\n```\n\nThis isolates your Coast data from whatever is on your host machine, but instances still share data with each other. This is useful when you want a clean separation from your host development environment without the overhead of per-instance volumes.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## Isolated Volumes\n\nIsolated volumes give each Coast instance its own independent volume. No data is shared between instances or with the host. Each instance starts empty (or from a snapshot — see below) and diverges independently.\n\n```text\nCoast: dev-1 --mounts--> volume \"dev-1-postgres\"\nCoast: dev-2 --mounts--> volume \"dev-2-postgres\"\n```\n\nThis is the best choice for projects that are integration-test heavy and need true volume isolation between parallel environments. The tradeoff is slower startup and larger Coast builds since each instance maintains its own copy of the data.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## Snapshotting\n\nBoth the shared and isolated strategies start with empty volumes by default. If you want instances to start with a copy of an existing host volume, set `snapshot_source` to the name of the Docker volume to copy from:\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\nThe snapshot is taken at [build time](BUILDS.md). After creation, each instance's volume diverges independently — mutations do not propagate back to the source or to other instances.\n\nCoast does not yet support runtime snapshotting (e.g., snapshotting a volume from a running instance). This is planned for a future release.\n", "harnesses/README.md": "# Harnesses\n\nEach harness creates git worktrees in a different location. In Coasts, the\n[`worktree_dir`](../coastfiles/WORKTREE_DIR.md) array tells it where to look --\nincluding external paths like `~/.codex/worktrees` that require additional\nbind mounts.\n\nEach harness also has its own conventions for project-level instructions, skills, and commands. The matrix below shows what each harness supports so you know where to put guidance for Coasts. Each page covers the Coastfile configuration, the recommended file layout, and any caveats specific to that harness.\n\nIf one repo is used from multiple harnesses, see [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n\n| Harness | Worktree location | Project instructions | Skills | Commands | Page |\n|---------|-------------------|----------------------|--------|----------|------|\n| OpenAI Codex | `~/.codex/worktrees` | `AGENTS.md` | `.agents/skills/` | Skills surface as `/` commands | [Codex](CODEX.md) |\n| Claude Code | `.claude/worktrees` | `CLAUDE.md` | `.claude/skills/` | `.claude/commands/` | [Claude Code](CLAUDE_CODE.md) |\n| Cursor | `~/.cursor/worktrees/` | `AGENTS.md` or `.cursor/rules/` | `.cursor/skills/` or `.agents/skills/` | `.cursor/commands/` | [Cursor](CURSOR.md) |\n| Conductor | `~/conductor/workspaces/` | `CLAUDE.md` | -- | -- | [Conductor](CONDUCTOR.md) |\n| T3 Code | `~/.t3/worktrees/` | `AGENTS.md` | `.agents/skills/` | -- | [T3 Code](T3_CODE.md) |\n| Shep | `~/.shep/repos/*/wt` | `CLAUDE.md` | `.agents/skills/` or `.claude/skills/` | -- | [Shep](SHEP.md) |\n\n## Skills vs Commands\n\nSkills and commands both let you define a reusable `/coasts` workflow. You can use either or both, depending on what the harness supports.\n\nIf your harness supports commands and you want an explicit `/coasts`\nentrypoint, one simple option is to add a command that reuses the skill.\nCommands are explicitly invoked by name, so you know exactly when the\n`/coasts` workflow runs. Skills can also be loaded automatically by the agent\nbased on context, which is useful but means you have less control over when the\ninstructions are pulled in.\n\nYou can use both. If you do, let the command reuse the skill instead of\nmaintaining a separate copy of the workflow.\n\nIf the harness only supports skills (T3 Code), use a skill. If it supports\nneither (Conductor), put the `/coasts` workflow directly in the project\ninstructions file.\n", - "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n## Quick setup\n\nRequires the [Coast CLI](../GETTING_STARTED.md). Copy this prompt into your\nagent's chat to set up Coasts automatically:\n\n```prompt-copy\nclaude_code_setup_prompt.txt\n```\n\nYou can also get the skill content from the CLI: `coast skills-prompt`.\n\nAfter setup, **start a new Claude Code session** — skills and `CLAUDE.md` changes\nare loaded at session start.\n\n---\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) creates\nworktrees inside the project at `.claude/worktrees/`. Because that directory\nlives inside the repo, Coasts can discover and assign Claude Code worktrees\nwithout any external bind mount.\n\nClaude Code is also the harness here with the clearest split between three\nlayers for Coasts:\n\n- `CLAUDE.md` for short, always-on rules for working with Coasts\n- `.claude/skills/coasts/SKILL.md` for the reusable `/coasts` workflow\n- `.claude/commands/coasts.md` only when you want a command file as an extra\n entrypoint\n\n## Setup\n\nAdd `.claude/worktrees` to `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\nBecause `.claude/worktrees` is project-relative, no external bind mount is\nneeded.\n\n## Where Coasts guidance goes\n\n### `CLAUDE.md`\n\nPut the rules for Coasts that should apply on every task here. Keep this short and\noperational:\n\n- run `coast lookup` before the first runtime command in a session\n- use `coast exec` for tests, builds, and service commands\n- use `coast ps` and `coast logs` for runtime feedback\n- ask before creating or reassigning a Coast when no match exists\n\n### `.claude/skills/coasts/SKILL.md`\n\nPut the reusable `/coasts` workflow here. This is the right home for a flow\nthat:\n\n1. runs `coast lookup` and reuses the matching Coast\n2. falls back to `coast ls` when there is no match\n3. offers `coast run`, `coast assign`, `coast unassign`, `coast checkout`, and\n `coast ui`\n4. uses the Coast CLI directly as the contract instead of wrapping it\n\nIf this repo also uses Codex, T3 Code, or Cursor, see\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) and keep the canonical skill in\n`.agents/skills/coasts/`, then expose it to Claude Code.\n\n### `.claude/commands/coasts.md`\n\nClaude Code also supports project command files. For docs about Coasts, treat\nthis as optional:\n\n- use it only when you specifically want a command file\n- one simple option is to have the command reuse the same skill\n- if you give the command its own separate instructions, you are taking on a\n second copy of the workflow to maintain\n\n## Example layout\n\n### Claude Code only\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\nIf this repo also uses Codex, T3 Code, or Cursor, use the shared pattern in\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) instead of duplicating it here,\nbecause duplicated provider-specific guidance gets harder to keep in sync every\ntime you add another harness.\n\n## What Coasts does\n\n- **Run** — `coast run ` creates a new Coast instance from the latest build. Use `coast run -w ` to create and assign a Claude Code worktree in one step. See [Run](../concepts_and_terminology/RUN.md).\n- **Discovery** — Coasts reads `.claude/worktrees` like any other local worktree\n directory.\n- **Naming** — Claude Code worktrees follow the same local worktree naming\n behavior as other in-repo worktrees in the Coasts UI and CLI.\n- **Assign** — `coast assign` can switch `/workspace` to a Claude Code worktree\n without any external bind-mount indirection.\n- **Gitignored sync** — Works normally because the worktrees live inside the\n repository tree.\n- **Orphan detection** — If Claude Code removes a worktree, Coasts can detect\n the missing gitdir and unassign it when needed.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code worktrees\n- `~/.codex/worktrees/` — Codex worktrees if you also use Codex in this repo\n\n## Limitations\n\n- If you duplicate the same `/coasts` workflow across `CLAUDE.md`,\n `.claude/skills`, and `.claude/commands`, those copies will drift. Keep\n `CLAUDE.md` short and keep the reusable workflow in one skill.\n- If you want one repo to work cleanly in multiple harnesses, prefer the shared\n pattern in [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", - "harnesses/CODEX.md": "# Codex\n\n## Quick setup\n\nRequires the [Coast CLI](../GETTING_STARTED.md). Copy this prompt into your\nagent's chat to set up Coasts automatically:\n\n```prompt-copy\ncodex_setup_prompt.txt\n```\n\nYou can also get the skill content from the CLI: `coast skills-prompt`.\n\nAfter setup, **quit and reopen Codex** for the new skill and `AGENTS.md` to take\neffect.\n\n---\n\n[Codex](https://developers.openai.com/codex/app/worktrees/) creates worktrees at `$CODEX_HOME/worktrees` (typically `~/.codex/worktrees`). Each worktree lives under an opaque hash directory like `~/.codex/worktrees/a0db/project-name`, starts on a detached HEAD, and is cleaned up automatically based on Codex's retention policy.\n\nFrom the [Codex docs](https://developers.openai.com/codex/app/worktrees/):\n\n> Can I control where worktrees are created?\n> Not today. Codex creates worktrees under `$CODEX_HOME/worktrees` so it can manage them consistently.\n\nBecause these worktrees live outside the project root, Coasts needs explicit\nconfiguration to discover and mount them.\n\n## Setup\n\nAdd `~/.codex/worktrees` to `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nCoasts expands `~` at runtime and treats any path starting with `~/` or `/` as\nexternal. See [Worktree Directories](../coastfiles/WORKTREE_DIR.md) for\ndetails.\n\nAfter changing `worktree_dir`, existing instances must be **recreated** for the bind mount to take effect:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nThe worktree listing updates immediately (Coasts reads the new Coastfile), but\nassigning to a Codex worktree requires the bind mount inside the container.\n\n## Where Coasts guidance goes\n\nUse Codex's project instruction file and shared skill layout for working with\nCoasts:\n\n- put the short Coast Runtime rules in `AGENTS.md`\n- put the reusable `/coasts` workflow in `.agents/skills/coasts/SKILL.md`\n- Codex surfaces that skill as the `/coasts` command\n- if you use Codex-specific metadata, keep it beside the skill in\n `.agents/skills/coasts/agents/openai.yaml`\n- do not create a separate project command file just for docs about Coasts; the\n skill is the reusable surface\n- if this repo also uses Cursor or Claude Code, keep the canonical skill in\n `.agents/skills/` and expose it from there. See\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) and\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\nFor example, a minimal `.agents/skills/coasts/agents/openai.yaml` could look\nlike this:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\nThat keeps the skill visible in Codex with a nicer label and makes `/coasts` an\nexplicit command. Only add `dependencies.tools` if the skill also needs MCP\nservers or other OpenAI-managed tool wiring.\n\n## What Coasts does\n\n- **Run** -- `coast run ` creates a new Coast instance from the latest build. Use `coast run -w ` to create and assign a Codex worktree in one step. See [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** -- At container creation, Coasts mounts\n `~/.codex/worktrees` into the container at `/host-external-wt/{index}`.\n- **Discovery** -- `git worktree list --porcelain` is repo-scoped, so only Codex worktrees belonging to the current project appear, even though the directory contains worktrees for many projects.\n- **Naming** -- Detached HEAD worktrees show as their relative path within the external dir (`a0db/my-app`, `eca7/my-app`). Branch-based worktrees show the branch name.\n- **Assign** -- `coast assign` remounts `/workspace` from the external bind mount path.\n- **Gitignored sync** -- Runs on the host filesystem with absolute paths, works without the bind mount.\n- **Orphan detection** -- The git watcher scans external directories\n recursively, filtering by `.git` gitdir pointers. If Codex deletes a\n worktree, Coasts auto-unassigns the instance.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code (local, no special handling)\n- `~/.codex/worktrees/` -- Codex (external, bind-mounted)\n\n## Limitations\n\n- Codex may clean up worktrees at any time. The orphan detection in Coasts\n handles this gracefully.\n", - "harnesses/CONDUCTOR.md": "# Conductor\n\n## Quick setup\n\nRequires the [Coast CLI](../GETTING_STARTED.md). Copy this prompt into your\nagent's chat to set up Coasts automatically:\n\n```prompt-copy\nconductor_setup_prompt.txt\n```\n\nYou can also get the skill content from the CLI: `coast skills-prompt`.\n\n> **Important:** Conductor runs each session in an isolated git worktree. The\n> setup prompt creates files that only exist in the current workspace — commit\n> and merge them into your main branch or they won't be available in new\n> sessions.\n\nAfter setup, **fully close and reopen Conductor** for changes to take effect. If\nthe `/coasts` command does not appear, close and reopen again.\n\n## Setup\n\nAdd `~/conductor/workspaces/` to `worktree_dir`. Unlike Codex (which stores all projects under one flat directory), Conductor nests worktrees under a per-project subdirectory, so the path must include the project name. In the example below, `my-app` must match the actual folder name under `~/conductor/workspaces/` for your repo.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nConductor allows you to configure the workspaces path per-repository, so the default `~/conductor/workspaces` may not match your setup. Check your Conductor repository settings to find the actual path and adjust accordingly — the principle is the same regardless of where the directory lives.\n\nCoasts expands `~` at runtime and treats any path starting with `~/` or `/` as\nexternal. See [Worktree Directories](../coastfiles/WORKTREE_DIR.md) for\ndetails.\n\nAfter changing `worktree_dir`, existing instances must be **recreated** for the bind mount to take effect:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nThe worktree listing updates immediately (Coasts reads the new Coastfile), but\nassigning to a Conductor worktree requires the bind mount inside the container.\n\n## Where Coasts guidance goes\n\nTreat Conductor as its own harness for working with Coasts:\n\n- put the short Coast Runtime rules in `CLAUDE.md`\n- use Conductor Repository Settings scripts for setup or run behavior that is\n actually Conductor-specific\n- do not assume full Claude Code project command or project skill behavior here\n- if you add a command and it does not appear, fully close and reopen\n Conductor before testing again\n- if this repo also uses other harnesses, see\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) and\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md) for ways to keep the\n shared `/coasts` workflow in one place\n\n## What Coasts does\n\n- **Run** — `coast run ` creates a new Coast instance from the latest build. Use `coast run -w ` to create and assign a Conductor worktree in one step. See [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — At container creation, Coasts mounts\n `~/conductor/workspaces/` into the container at\n `/host-external-wt/{index}`.\n- **Discovery** — `git worktree list --porcelain` is repo-scoped, so only worktrees belonging to the current project appear.\n- **Naming** — Conductor worktrees use named branches, so they appear by branch\n name in the Coasts UI and CLI (e.g., `scroll-to-bottom-btn`). A branch can\n only be checked out in one Conductor workspace at a time.\n- **Assign** — `coast assign` remounts `/workspace` from the external bind mount path.\n- **Gitignored sync** — Runs on the host filesystem with absolute paths, works without the bind mount.\n- **Orphan detection** — The git watcher scans external directories\n recursively, filtering by `.git` gitdir pointers. If Conductor archives or\n deletes a workspace, Coasts auto-unassigns the instance.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor (external, bind-mounted; replace `my-app` with your repo folder name)\n\n## Conductor Env Vars\n\n- Avoid relying on Conductor-specific environment variables (e.g.,\n `CONDUCTOR_PORT`, `CONDUCTOR_WORKSPACE_PATH`) for runtime configuration\n inside Coasts. Coasts manages ports, workspace paths, and service discovery\n independently — use Coastfile `[ports]` and `coast exec` instead.", - "harnesses/CURSOR.md": "# Cursor\n\n## Quick setup\n\nRequires the [Coast CLI](../GETTING_STARTED.md). Copy this prompt into your\nagent's chat to set up Coasts automatically:\n\n```prompt-copy\ncursor_setup_prompt.txt\n```\n\nYou can also get the skill content from the CLI: `coast skills-prompt`.\n\nAfter setup, **restart Cursor** for the skill and rules changes to take effect.\n\n---\n\n[Cursor](https://cursor.com/docs/agent/overview) can work directly in your\ncurrent checkout, and its Parallel Agents feature can also create git\nworktrees under `~/.cursor/worktrees//`.\n\nFor docs about Coasts, that means there are two setup cases:\n\n- if you are just using Cursor in the current checkout, no Cursor-specific\n `worktree_dir` entry is required\n- if you use Cursor Parallel Agents, add the Cursor worktree directory to\n `worktree_dir` so Coasts can discover and assign those worktrees\n\n## Setup\n\n### Current checkout only\n\nIf Cursor is just editing the checkout you already opened, Coasts does not need\nany special Cursor-specific worktree path. Coasts will treat that checkout like\nany other local repository root.\n\n### Cursor Parallel Agents\n\nIf you use Parallel Agents, add `~/.cursor/worktrees/` to\n`worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nCursor stores each agent worktree beneath that per-project directory. Coasts\nexpands `~` at runtime and treats the path as external, so existing instances\nmust be recreated for the bind mount to take effect:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nThe worktree listing updates immediately after the Coastfile change, but\nassigning to a Cursor Parallel Agent worktree requires the external bind mount\ninside the container.\n\n## Where Coasts guidance goes\n\n### `AGENTS.md` or `.cursor/rules/coast.md`\n\nPut the short, always-on Coast Runtime rules here:\n\n- use `AGENTS.md` if you want the most portable project instructions\n- use `.cursor/rules/coast.md` if you want Cursor-native project rules and\n settings UI support\n- do not duplicate the same Coast Runtime block in both unless you have a clear\n reason\n\n### `.cursor/skills/coasts/SKILL.md` or shared `.agents/skills/coasts/SKILL.md`\n\nPut the reusable `/coasts` workflow here:\n\n- for a Cursor-only repo, `.cursor/skills/coasts/SKILL.md` is a natural home\n- for a multi-harness repo, keep the canonical skill in\n `.agents/skills/coasts/SKILL.md`; Cursor can load that directly\n- the skill should own the real `/coasts` workflow: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout`, and `coast ui`\n\n### `.cursor/commands/coasts.md`\n\nCursor also supports project commands. For docs about Coasts, treat commands as\noptional:\n\n- add a command only when you want an explicit `/coasts` entrypoint\n- one simple option is to have the command reuse the same skill\n- if you give the command its own separate instructions, you are taking on a\n second copy of the workflow to maintain\n\n### `.cursor/worktrees.json`\n\nUse `.cursor/worktrees.json` for Cursor's own worktree bootstrap, not for Coasts\npolicy:\n\n- install dependencies\n- copy or symlink `.env` files\n- run database migrations or other one-time bootstrap steps\n\nDo not move the Coast Runtime rules or Coast CLI workflow into\n`.cursor/worktrees.json`.\n\n## Example layout\n\n### Cursor only\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # optional\n.cursor/rules/coast.md # optional alternative to AGENTS.md\n.cursor/worktrees.json # optional, for Parallel Agents bootstrap\n```\n\n### Cursor plus other harnesses\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional\n```\n\n## What Coasts does\n\n- **Run** — `coast run ` creates a new Coast instance from the latest build. Use `coast run -w ` to create and assign a Cursor worktree in one step. See [Run](../concepts_and_terminology/RUN.md).\n- **Current checkout** — No special Cursor handling is required when Cursor is\n working directly in the repo you opened.\n- **Bind mount** — For Parallel Agents, Coasts mounts\n `~/.cursor/worktrees/` into the container at\n `/host-external-wt/{index}`.\n- **Discovery** — `git worktree list --porcelain` remains repo-scoped, so Coasts\n only shows Cursor worktrees that belong to the current project.\n- **Naming** — Cursor Parallel Agent worktrees appear by their branch names in\n Coasts' CLI and UI.\n- **Assign** — `coast assign` remounts `/workspace` from the external bind\n mount path when a Cursor worktree is selected.\n- **Gitignored sync** — Continues to work on the host filesystem with absolute\n paths.\n- **Orphan detection** — If Cursor cleans up old worktrees, Coasts can detect\n the missing gitdir and unassign them when needed.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code worktrees\n- `~/.codex/worktrees/` — Codex worktrees\n- `~/.cursor/worktrees/my-app/` — Cursor Parallel Agent worktrees\n\n## Limitations\n\n- If you are not using Cursor Parallel Agents, do not add\n `~/.cursor/worktrees/` just because you happen to be editing in\n Cursor.\n- Keep the Coast Runtime rules in one always-on place: `AGENTS.md` or\n `.cursor/rules/coast.md`. Duplicating both invites drift.\n- Keep the reusable `/coasts` workflow in a skill. `.cursor/worktrees.json` is\n for Cursor bootstrap, not Coasts policy.\n- If one repo is shared across Cursor, Codex, Claude Code, or T3 Code, prefer\n the shared layout in [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", + "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n## Quick setup\n\nRequires the [Coast CLI](../GETTING_STARTED.md). Copy this prompt into your\nagent's chat to set up Coasts automatically:\n\n```prompt-copy\nclaude_code_setup_prompt.txt\n```\n\nYou can also get the skill content from the CLI: `coast skills-prompt`.\n\nAfter setup, **start a new Claude Code session** — skills and `CLAUDE.md` changes\nare loaded at session start.\n\n---\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) creates\nworktrees inside the project at `.claude/worktrees/`. Because that directory\nlives inside the repo, Coasts can discover and assign Claude Code worktrees\nwithout any external bind mount.\n\nClaude Code is also the harness here with the clearest split between three\nlayers for Coasts:\n\n- `CLAUDE.md` for short, always-on rules for working with Coasts\n- `.claude/skills/coasts/SKILL.md` for the reusable `/coasts` workflow\n- `.claude/commands/coasts.md` only when you want a command file as an extra\n entrypoint\n\n```youtube\nyjMFVoOiAW0\n```\n\n## Setup\n\nAdd `.claude/worktrees` to `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\nBecause `.claude/worktrees` is project-relative, no external bind mount is\nneeded.\n\n## Where Coasts guidance goes\n\n### `CLAUDE.md`\n\nPut the rules for Coasts that should apply on every task here. Keep this short and\noperational:\n\n- run `coast lookup` before the first runtime command in a session\n- use `coast exec` for tests, builds, and service commands\n- use `coast ps` and `coast logs` for runtime feedback\n- ask before creating or reassigning a Coast when no match exists\n\n### `.claude/skills/coasts/SKILL.md`\n\nPut the reusable `/coasts` workflow here. This is the right home for a flow\nthat:\n\n1. runs `coast lookup` and reuses the matching Coast\n2. falls back to `coast ls` when there is no match\n3. offers `coast run`, `coast assign`, `coast unassign`, `coast checkout`, and\n `coast ui`\n4. uses the Coast CLI directly as the contract instead of wrapping it\n\nIf this repo also uses Codex, T3 Code, or Cursor, see\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) and keep the canonical skill in\n`.agents/skills/coasts/`, then expose it to Claude Code.\n\n### `.claude/commands/coasts.md`\n\nClaude Code also supports project command files. For docs about Coasts, treat\nthis as optional:\n\n- use it only when you specifically want a command file\n- one simple option is to have the command reuse the same skill\n- if you give the command its own separate instructions, you are taking on a\n second copy of the workflow to maintain\n\n## Example layout\n\n### Claude Code only\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\nIf this repo also uses Codex, T3 Code, or Cursor, use the shared pattern in\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) instead of duplicating it here,\nbecause duplicated provider-specific guidance gets harder to keep in sync every\ntime you add another harness.\n\n## What Coasts does\n\n- **Run** — `coast run ` creates a new Coast instance from the latest build. Use `coast run -w ` to create and assign a Claude Code worktree in one step. See [Run](../concepts_and_terminology/RUN.md).\n- **Discovery** — Coasts reads `.claude/worktrees` like any other local worktree\n directory.\n- **Naming** — Claude Code worktrees follow the same local worktree naming\n behavior as other in-repo worktrees in the Coasts UI and CLI.\n- **Assign** — `coast assign` can switch `/workspace` to a Claude Code worktree\n without any external bind-mount indirection.\n- **Gitignored sync** — Works normally because the worktrees live inside the\n repository tree.\n- **Orphan detection** — If Claude Code removes a worktree, Coasts can detect\n the missing gitdir and unassign it when needed.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code worktrees\n- `~/.codex/worktrees/` — Codex worktrees if you also use Codex in this repo\n\n## Troubleshooting\n\n- **Worktree not found** — If Coasts expects a worktree to exist but cannot\n find it, verify that the Coastfile's `worktree_dir` includes\n `.claude/worktrees`. See [Worktree Directories](../coastfiles/WORKTREE_DIR.md)\n for syntax and path types.\n\n## Limitations\n\n- If you duplicate the same `/coasts` workflow across `CLAUDE.md`,\n `.claude/skills`, and `.claude/commands`, those copies will drift. Keep\n `CLAUDE.md` short and keep the reusable workflow in one skill.\n- If you want one repo to work cleanly in multiple harnesses, prefer the shared\n pattern in [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", + "harnesses/CODEX.md": "# Codex\n\n## Quick setup\n\nRequires the [Coast CLI](../GETTING_STARTED.md). Copy this prompt into your\nagent's chat to set up Coasts automatically:\n\n```prompt-copy\ncodex_setup_prompt.txt\n```\n\nYou can also get the skill content from the CLI: `coast skills-prompt`.\n\nAfter setup, **quit and reopen Codex** for the new skill and `AGENTS.md` to take\neffect.\n\n---\n\n[Codex](https://developers.openai.com/codex/app/worktrees/) creates worktrees at `$CODEX_HOME/worktrees` (typically `~/.codex/worktrees`). Each worktree lives under an opaque hash directory like `~/.codex/worktrees/a0db/project-name`, starts on a detached HEAD, and is cleaned up automatically based on Codex's retention policy.\n\nFrom the [Codex docs](https://developers.openai.com/codex/app/worktrees/):\n\n> Can I control where worktrees are created?\n> Not today. Codex creates worktrees under `$CODEX_HOME/worktrees` so it can manage them consistently.\n\nBecause these worktrees live outside the project root, Coasts needs explicit\nconfiguration to discover and mount them.\n\n```youtube\nMDidmMQtaqU\n```\n\n## Setup\n\nAdd `~/.codex/worktrees` to `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nCoasts expands `~` at runtime and treats any path starting with `~/` or `/` as\nexternal. See [Worktree Directories](../coastfiles/WORKTREE_DIR.md) for\ndetails.\n\nAfter changing `worktree_dir`, existing instances must be **recreated** for the bind mount to take effect:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nThe worktree listing updates immediately (Coasts reads the new Coastfile), but\nassigning to a Codex worktree requires the bind mount inside the container.\n\n## Where Coasts guidance goes\n\nUse Codex's project instruction file and shared skill layout for working with\nCoasts:\n\n- put the short Coast Runtime rules in `AGENTS.md`\n- put the reusable `/coasts` workflow in `.agents/skills/coasts/SKILL.md`\n- Codex surfaces that skill as the `/coasts` command\n- if you use Codex-specific metadata, keep it beside the skill in\n `.agents/skills/coasts/agents/openai.yaml`\n- do not create a separate project command file just for docs about Coasts; the\n skill is the reusable surface\n- if this repo also uses Cursor or Claude Code, keep the canonical skill in\n `.agents/skills/` and expose it from there. See\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) and\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\nFor example, a minimal `.agents/skills/coasts/agents/openai.yaml` could look\nlike this:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\nThat keeps the skill visible in Codex with a nicer label and makes `/coasts` an\nexplicit command. Only add `dependencies.tools` if the skill also needs MCP\nservers or other OpenAI-managed tool wiring.\n\n## What Coasts does\n\n- **Run** -- `coast run ` creates a new Coast instance from the latest build. Use `coast run -w ` to create and assign a Codex worktree in one step. See [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** -- At container creation, Coasts mounts\n `~/.codex/worktrees` into the container at `/host-external-wt/{index}`.\n- **Discovery** -- `git worktree list --porcelain` is repo-scoped, so only Codex worktrees belonging to the current project appear, even though the directory contains worktrees for many projects.\n- **Naming** -- Detached HEAD worktrees show as their relative path within the external dir (`a0db/my-app`, `eca7/my-app`). Branch-based worktrees show the branch name.\n- **Assign** -- `coast assign` remounts `/workspace` from the external bind mount path.\n- **Gitignored sync** -- Runs on the host filesystem with absolute paths, works without the bind mount.\n- **Orphan detection** -- The git watcher scans external directories\n recursively, filtering by `.git` gitdir pointers. If Codex deletes a\n worktree, Coasts auto-unassigns the instance.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code (local, no special handling)\n- `~/.codex/worktrees/` -- Codex (external, bind-mounted)\n\n## Troubleshooting\n\n- **Worktree not found** — If Coasts expects a worktree to exist but cannot\n find it, verify that the Coastfile's `worktree_dir` includes\n `~/.codex/worktrees`. See [Worktree Directories](../coastfiles/WORKTREE_DIR.md)\n for syntax and path types.\n\n## Limitations\n\n- Codex may clean up worktrees at any time. The orphan detection in Coasts\n handles this gracefully.\n", + "harnesses/CONDUCTOR.md": "# Conductor\n\n## Quick setup\n\nRequires the [Coast CLI](../GETTING_STARTED.md). Copy this prompt into your\nagent's chat to set up Coasts automatically:\n\n```prompt-copy\nconductor_setup_prompt.txt\n```\n\nYou can also get the skill content from the CLI: `coast skills-prompt`.\n\n> **Important:** Conductor runs each session in an isolated git worktree. The\n> setup prompt creates files that only exist in the current workspace — commit\n> and merge them into your main branch or they won't be available in new\n> sessions.\n\nAfter setup, **fully close and reopen Conductor** for changes to take effect. If\nthe `/coasts` command does not appear, close and reopen again.\n\n```youtube\nmbwilJHlanQ\n```\n\n## Setup\n\nAdd `~/conductor/workspaces/` to `worktree_dir`. Unlike Codex (which stores all projects under one flat directory), Conductor nests worktrees under a per-project subdirectory, so the path must include the project name. In the example below, `my-app` must match the actual folder name under `~/conductor/workspaces/` for your repo.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nConductor allows you to configure the workspaces path per-repository, so the default `~/conductor/workspaces` may not match your setup. Check your Conductor repository settings to find the actual path and adjust accordingly — the principle is the same regardless of where the directory lives.\n\nIf you have more than one Conductor project configured for the same repository, each project creates workspaces under its own subdirectory (e.g. `~/conductor/workspaces/my-app-frontend`, `~/conductor/workspaces/my-app-backend`). The `worktree_dir` entry must match the directory name Conductor actually creates, so you may need multiple entries or need to update the path when switching between projects.\n\nCoasts expands `~` at runtime and treats any path starting with `~/` or `/` as\nexternal. See [Worktree Directories](../coastfiles/WORKTREE_DIR.md) for\ndetails.\n\nAfter changing `worktree_dir`, existing instances must be **recreated** for the bind mount to take effect:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nThe worktree listing updates immediately (Coasts reads the new Coastfile), but\nassigning to a Conductor worktree requires the bind mount inside the container.\n\n## Where Coasts guidance goes\n\nTreat Conductor as its own harness for working with Coasts:\n\n- put the short Coast Runtime rules in `CLAUDE.md`\n- use Conductor Repository Settings scripts for setup or run behavior that is\n actually Conductor-specific\n- do not assume full Claude Code project command or project skill behavior here\n- if you add a command and it does not appear, fully close and reopen\n Conductor before testing again\n- if this repo also uses other harnesses, see\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) and\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md) for ways to keep the\n shared `/coasts` workflow in one place\n\n## What Coasts does\n\n- **Run** — `coast run ` creates a new Coast instance from the latest build. Use `coast run -w ` to create and assign a Conductor worktree in one step. See [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — At container creation, Coasts mounts\n `~/conductor/workspaces/` into the container at\n `/host-external-wt/{index}`.\n- **Discovery** — `git worktree list --porcelain` is repo-scoped, so only worktrees belonging to the current project appear.\n- **Naming** — Conductor worktrees use named branches, so they appear by branch\n name in the Coasts UI and CLI (e.g., `scroll-to-bottom-btn`). A branch can\n only be checked out in one Conductor workspace at a time.\n- **Assign** — `coast assign` remounts `/workspace` from the external bind mount path.\n- **Gitignored sync** — Runs on the host filesystem with absolute paths, works without the bind mount.\n- **Orphan detection** — The git watcher scans external directories\n recursively, filtering by `.git` gitdir pointers. If Conductor archives or\n deletes a workspace, Coasts auto-unassigns the instance.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor (external, bind-mounted; replace `my-app` with your repo folder name)\n\n## Troubleshooting\n\n- **Worktree not found** — If Coasts expects a worktree to exist but cannot\n find it, verify that the Coastfile's `worktree_dir` includes the correct\n `~/conductor/workspaces/` path. The `` segment\n must match the actual folder name Conductor creates under\n `~/conductor/workspaces/`. See\n [Worktree Directories](../coastfiles/WORKTREE_DIR.md) for syntax and path\n types.\n- **Multiple projects for the same repo** — If more than one Conductor project\n is configured for the same repository, each project creates workspaces under\n a different subdirectory. The `worktree_dir` must be updated to match the\n directory Conductor dynamically creates for the active project. If you switch\n between projects, the path changes and the Coastfile needs to reflect that.\n\n## Conductor Env Vars\n\n- Avoid relying on Conductor-specific environment variables (e.g.,\n `CONDUCTOR_PORT`, `CONDUCTOR_WORKSPACE_PATH`) for runtime configuration\n inside Coasts. Coasts manages ports, workspace paths, and service discovery\n independently — use Coastfile `[ports]` and `coast exec` instead.", + "harnesses/CURSOR.md": "# Cursor\n\n## Quick setup\n\nRequires the [Coast CLI](../GETTING_STARTED.md). Copy this prompt into your\nagent's chat to set up Coasts automatically:\n\n```prompt-copy\ncursor_setup_prompt.txt\n```\n\nYou can also get the skill content from the CLI: `coast skills-prompt`.\n\nAfter setup, **restart Cursor** for the skill and rules changes to take effect.\n\n---\n\n[Cursor](https://cursor.com/docs/agent/overview) can work directly in your\ncurrent checkout, and its Parallel Agents feature can also create git\nworktrees under `~/.cursor/worktrees//`.\n\nFor docs about Coasts, that means there are two setup cases:\n\n- if you are just using Cursor in the current checkout, no Cursor-specific\n `worktree_dir` entry is required\n- if you use Cursor Parallel Agents, add the Cursor worktree directory to\n `worktree_dir` so Coasts can discover and assign those worktrees\n\n## Setup\n\n### Current checkout only\n\nIf Cursor is just editing the checkout you already opened, Coasts does not need\nany special Cursor-specific worktree path. Coasts will treat that checkout like\nany other local repository root.\n\n### Cursor Parallel Agents\n\nIf you use Parallel Agents, add `~/.cursor/worktrees/` to\n`worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nCursor stores each agent worktree beneath that per-project directory. Coasts\nexpands `~` at runtime and treats the path as external, so existing instances\nmust be recreated for the bind mount to take effect:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nThe worktree listing updates immediately after the Coastfile change, but\nassigning to a Cursor Parallel Agent worktree requires the external bind mount\ninside the container.\n\n## Where Coasts guidance goes\n\n### `AGENTS.md` or `.cursor/rules/coast.md`\n\nPut the short, always-on Coast Runtime rules here:\n\n- use `AGENTS.md` if you want the most portable project instructions\n- use `.cursor/rules/coast.md` if you want Cursor-native project rules and\n settings UI support\n- do not duplicate the same Coast Runtime block in both unless you have a clear\n reason\n\n### `.cursor/skills/coasts/SKILL.md` or shared `.agents/skills/coasts/SKILL.md`\n\nPut the reusable `/coasts` workflow here:\n\n- for a Cursor-only repo, `.cursor/skills/coasts/SKILL.md` is a natural home\n- for a multi-harness repo, keep the canonical skill in\n `.agents/skills/coasts/SKILL.md`; Cursor can load that directly\n- the skill should own the real `/coasts` workflow: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout`, and `coast ui`\n\n### `.cursor/commands/coasts.md`\n\nCursor also supports project commands. For docs about Coasts, treat commands as\noptional:\n\n- add a command only when you want an explicit `/coasts` entrypoint\n- one simple option is to have the command reuse the same skill\n- if you give the command its own separate instructions, you are taking on a\n second copy of the workflow to maintain\n\n### `.cursor/worktrees.json`\n\nUse `.cursor/worktrees.json` for Cursor's own worktree bootstrap, not for Coasts\npolicy:\n\n- install dependencies\n- copy or symlink `.env` files\n- run database migrations or other one-time bootstrap steps\n\nDo not move the Coast Runtime rules or Coast CLI workflow into\n`.cursor/worktrees.json`.\n\n## Example layout\n\n### Cursor only\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # optional\n.cursor/rules/coast.md # optional alternative to AGENTS.md\n.cursor/worktrees.json # optional, for Parallel Agents bootstrap\n```\n\n### Cursor plus other harnesses\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional\n```\n\n## What Coasts does\n\n- **Run** — `coast run ` creates a new Coast instance from the latest build. Use `coast run -w ` to create and assign a Cursor worktree in one step. See [Run](../concepts_and_terminology/RUN.md).\n- **Current checkout** — No special Cursor handling is required when Cursor is\n working directly in the repo you opened.\n- **Bind mount** — For Parallel Agents, Coasts mounts\n `~/.cursor/worktrees/` into the container at\n `/host-external-wt/{index}`.\n- **Discovery** — `git worktree list --porcelain` remains repo-scoped, so Coasts\n only shows Cursor worktrees that belong to the current project.\n- **Naming** — Cursor Parallel Agent worktrees appear by their branch names in\n Coasts' CLI and UI.\n- **Assign** — `coast assign` remounts `/workspace` from the external bind\n mount path when a Cursor worktree is selected.\n- **Gitignored sync** — Continues to work on the host filesystem with absolute\n paths.\n- **Orphan detection** — If Cursor cleans up old worktrees, Coasts can detect\n the missing gitdir and unassign them when needed.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code worktrees\n- `~/.codex/worktrees/` — Codex worktrees\n- `~/.cursor/worktrees/my-app/` — Cursor Parallel Agent worktrees\n\n## Troubleshooting\n\n- **Worktree not found** — If Coasts expects a worktree to exist but cannot\n find it, verify that the Coastfile's `worktree_dir` includes\n `~/.cursor/worktrees/` and that `` matches the\n actual folder name under `~/.cursor/worktrees/`. See\n [Worktree Directories](../coastfiles/WORKTREE_DIR.md) for syntax and path\n types.\n\n## Limitations\n\n- If you are not using Cursor Parallel Agents, do not add\n `~/.cursor/worktrees/` just because you happen to be editing in\n Cursor.\n- Keep the Coast Runtime rules in one always-on place: `AGENTS.md` or\n `.cursor/rules/coast.md`. Duplicating both invites drift.\n- Keep the reusable `/coasts` workflow in a skill. `.cursor/worktrees.json` is\n for Cursor bootstrap, not Coasts policy.\n- If one repo is shared across Cursor, Codex, Claude Code, or T3 Code, prefer\n the shared layout in [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", "harnesses/MULTIPLE_HARNESSES.md": "# Multiple Harnesses\n\nIf one repository is used from more than one harness, one way to consolidate\nthe Coasts setup is to keep the shared `/coasts` workflow in one place and keep\nthe harness-specific always-on rules in the files for each harness.\n\n## Recommended layout\n\n```text\nAGENTS.md\nCLAUDE.md\n.cursor/rules/coast.md # optional Cursor-native always-on rules\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional, thin, harness-specific\n.claude/commands/coasts.md # optional, thin, harness-specific\n```\n\nUse this layout like this:\n\n- `AGENTS.md` — short, always-on rules for working with Coasts in Codex and T3\n Code\n- `.cursor/rules/coast.md` — optional Cursor-native always-on rules\n- `CLAUDE.md` — short, always-on rules for working with Coasts in Claude Code\n and Conductor\n- `.agents/skills/coasts/SKILL.md` — canonical reusable `/coasts` workflow\n- `.agents/skills/coasts/agents/openai.yaml` — optional Codex/OpenAI metadata\n- `.claude/skills/coasts` — Claude-facing mirror or symlink when Claude Code\n also needs the same skill\n- `.cursor/commands/coasts.md` — optional Cursor command file; one simple\n option is to have it reuse the same skill\n- `.claude/commands/coasts.md` — optional explicit command file; one simple\n option is to have it reuse the same skill\n\n## Step-by-step\n\n1. Put the Coast Runtime rules in the always-on instruction files.\n - `AGENTS.md`, `CLAUDE.md`, or `.cursor/rules/coast.md` should answer the\n \"every task\" rules: run `coast lookup` first, use `coast exec`, read logs\n with `coast logs`, ask before `coast assign` or `coast run` when there is\n no match.\n2. Create one canonical skill for Coasts.\n - Put the reusable `/coasts` workflow in `.agents/skills/coasts/SKILL.md`.\n - Use the Coast CLI directly inside that skill: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout`, and `coast ui`.\n3. Expose that skill only where a harness needs a different path.\n - Codex, T3 Code, and Cursor can all use `.agents/skills/` directly.\n - Claude Code needs `.claude/skills/`, so mirror or symlink the canonical\n skill into that location.\n4. Add a command file only if you want an explicit `/coasts` entrypoint.\n - If you create `.claude/commands/coasts.md` or\n `.cursor/commands/coasts.md`, one simple option is to have the command\n reuse the same skill.\n - If you give the command its own separate instructions, you are taking on a\n second copy of the workflow to maintain.\n5. Keep Conductor-specific setup in Conductor, not in the skill.\n - Use Conductor Repository Settings scripts for bootstrap or run behavior\n that belongs to Conductor itself.\n - Keep Coasts policy and use of the `coast` CLI in `CLAUDE.md` and the\n shared skill.\n\n## Concrete `/coasts` example\n\nA good shared `coasts` skill should do three jobs:\n\n1. `Use Existing Coast`\n - run `coast lookup`\n - if a match exists, use `coast exec`, `coast ps`, and `coast logs`\n2. `Manage Assignment`\n - run `coast ls`\n - offer `coast run`, `coast assign`, `coast unassign`, or\n `coast checkout`\n - ask before reusing or disrupting an existing slot\n3. `Open UI`\n - run `coast ui`\n\nThat is the right place for the `/coasts` workflow. The always-on files should\nonly hold the short rules that must apply even when the skill is never invoked.\n\n## Symlink pattern\n\nIf you want Claude Code to reuse the same skill as Codex, T3 Code, or Cursor,\none option is a symlink:\n\n```bash\nmkdir -p .claude/skills\nln -s ../../.agents/skills/coasts .claude/skills/coasts\n```\n\nA checked-in mirror is also fine if your team prefers not to use symlinks. The\nmain goal is just to avoid unnecessary drift between copies.\n\n## Harness-specific cautions\n\n- Claude Code: project skills and optional project commands are both valid, but\n keep the logic in the skill.\n- Cursor: use `AGENTS.md` or `.cursor/rules/coast.md` for the short Coast\n Runtime rules, use a skill for the reusable workflow, and keep\n `.cursor/commands` optional.\n- Conductor: treat it as `CLAUDE.md` plus Conductor scripts and settings first.\n If you add a command and it does not appear, fully close and reopen the app\n before checking again.\n- T3 Code: this is the thinnest harness surface here. Use the Codex-style\n `AGENTS.md` plus `.agents/skills` pattern, and do not invent a separate\n T3-specific command layout for docs about Coasts.\n- Codex: keep `AGENTS.md` short and put the reusable workflow in\n `.agents/skills`.\n", - "harnesses/SHEP.md": "# Shep\n\n## Quick setup\n\nRequires the [Coast CLI](../GETTING_STARTED.md). Copy this prompt into your\nagent's chat to set up Coasts automatically:\n\n```prompt-copy\nshep_setup_prompt.txt\n```\n\nYou can also get the skill content from the CLI: `coast skills-prompt`.\n\nAfter setup, **quit and reopen your editor** for the new skill and project\ninstructions to take effect.\n\n---\n\n[Shep](https://shep-ai.github.io/cli/) creates worktrees at `~/.shep/repos/{hash}/wt/{branch-slug}`. The hash is the first 16 hex characters of the SHA-256 of the repository's absolute path, so it is deterministic per-repo but opaque. All worktrees for a given repo share the same hash and are differentiated by the `wt/{branch-slug}` subdirectory.\n\nFrom the Shep CLI, `shep feat show ` prints the worktree path, or\n`ls ~/.shep/repos` lists the per-repo hash directories.\n\nBecause the hash varies per repo, Coasts uses a **glob pattern** to discover\nshep worktrees without requiring the user to hard-code the hash.\n\n## Setup\n\nAdd `~/.shep/repos/*/wt` to `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\nThe `*` matches the per-repo hash directory. At runtime Coasts expands the glob,\nfinds the matching directory (e.g. `~/.shep/repos/a21f0cda9ab9d456/wt`), and\nbind-mounts it into the container. See\n[Worktree Directories](../coastfiles/WORKTREE_DIR.md) for full details on glob\npatterns.\n\nAfter changing `worktree_dir`, existing instances must be **recreated** for the bind mount to take effect:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nThe worktree listing updates immediately (Coasts reads the new Coastfile), but\nassigning to a Shep worktree requires the bind mount inside the container.\n\n## Where Coasts guidance goes\n\nShep wraps Claude Code under the hood, so follow the Claude Code conventions:\n\n- put the short Coast Runtime rules in `CLAUDE.md`\n- put the reusable `/coasts` workflow in `.claude/skills/coasts/SKILL.md` or\n the shared `.agents/skills/coasts/SKILL.md`\n- if this repo also uses other harnesses, see\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) and\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)\n\n## What Coasts does\n\n- **Run** -- `coast run ` creates a new Coast instance from the latest build. Use `coast run -w ` to create and assign a Shep worktree in one step. See [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** -- At container creation, Coasts resolves the glob\n `~/.shep/repos/*/wt` and mounts each matching directory into the container at\n `/host-external-wt/{index}`.\n- **Discovery** -- `git worktree list --porcelain` is repo-scoped, so only\n worktrees belonging to the current project appear.\n- **Naming** -- Shep worktrees use named branches, so they appear by branch\n name in the Coasts UI and CLI (e.g., `feat-green-background`).\n- **Assign** -- `coast assign` remounts `/workspace` from the external bind mount path.\n- **Gitignored sync** -- Runs on the host filesystem with absolute paths, works without the bind mount.\n- **Orphan detection** -- The git watcher scans external directories\n recursively, filtering by `.git` gitdir pointers. If Shep deletes a\n worktree, Coasts auto-unassigns the instance.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/.shep/repos/*/wt` -- Shep (external, bind-mounted via glob expansion)\n\n## Shep path structure\n\n```\n~/.shep/repos/\n {sha256-of-repo-path-first-16-chars}/\n wt/\n {branch-slug}/ <-- git worktree\n {branch-slug}/\n```\n\nKey points:\n- Same repo = same hash every time (deterministic, not random)\n- Different repos = different hashes\n- Path separators are normalized to `/` before hashing\n- The hash can be found via `shep feat show ` or `ls ~/.shep/repos`\n", - "harnesses/T3_CODE.md": "# T3 Code\n\n## Quick setup\n\nRequires the [Coast CLI](../GETTING_STARTED.md). Copy this prompt into your\nagent's chat to set up Coasts automatically:\n\n```prompt-copy\nt3_code_setup_prompt.txt\n```\n\nYou can also get the skill content from the CLI: `coast skills-prompt`.\n\nAfter setup, **restart T3 Code** for the skill and rules changes to take effect.\n\n**Note:** T3 Code may not load project-level skills from `.agents/skills/` or\n`.claude/skills/` yet. The setup prompt also places the skill in\n`~/.codex/skills/coasts/` so it is available globally to the Codex provider.\nThe Coast Runtime rules in `AGENTS.md` and `CLAUDE.md` still apply on every\ntask regardless.\n\n---\n\n[T3 Code](https://github.com/pingdotgg/t3code) creates git worktrees at\n`~/.t3/worktrees//`, checked out on named branches.\n\nT3 Code wraps Codex, so it uses `AGENTS.md` for always-on rules and\n`.agents/skills/coasts/SKILL.md` for the reusable `/coasts` workflow.\n\nBecause these worktrees live outside the project root, Coasts needs explicit\nconfiguration to discover and mount them.\n\n## Setup\n\nAdd `~/.t3/worktrees/` to `worktree_dir`. T3 Code nests worktrees under a per-project subdirectory, so the path must include the project name. In the example below, `my-app` must match the actual folder name under `~/.t3/worktrees/` for your repo.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nCoasts expands `~` at runtime and treats any path starting with `~/` or `/` as\nexternal. See [Worktree Directories](../coastfiles/WORKTREE_DIR.md) for\ndetails.\n\nAfter changing `worktree_dir`, existing instances must be **recreated** for the bind mount to take effect:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nThe worktree listing updates immediately (Coasts reads the new Coastfile), but\nassigning to a T3 Code worktree requires the bind mount inside the container.\n\n## Where Coasts guidance goes\n\nUse this layout for T3 Code:\n\n- put the short Coast Runtime rules in `AGENTS.md`\n- put the reusable `/coasts` workflow in `.agents/skills/coasts/SKILL.md`\n- do not add a separate T3-specific project command or slash-command layer for\n Coasts\n- if this repo uses multiple harnesses, see\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) and\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\n## What Coasts does\n\n- **Run** — `coast run ` creates a new Coast instance from the latest build. Use `coast run -w ` to create and assign a T3 Code worktree in one step. See [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — At container creation, Coasts mounts\n `~/.t3/worktrees/` into the container at\n `/host-external-wt/{index}`.\n- **Discovery** — `git worktree list --porcelain` is repo-scoped, so only worktrees belonging to the current project appear.\n- **Naming** — T3 Code worktrees use named branches, so they appear by branch\n name in the Coasts UI and CLI.\n- **Assign** — `coast assign` remounts `/workspace` from the external bind mount path.\n- **Gitignored sync** — Runs on the host filesystem with absolute paths, works without the bind mount.\n- **Orphan detection** — The git watcher scans external directories\n recursively, filtering by `.git` gitdir pointers. If T3 Code removes a\n workspace, Coasts auto-unassigns the instance.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code (local, no special handling)\n- `~/.codex/worktrees/` — Codex (external, bind-mounted)\n- `~/.t3/worktrees/my-app/` — T3 Code (external, bind-mounted; replace `my-app` with your repo folder name)\n\n## Limitations\n\n- Avoid relying on T3 Code-specific environment variables for runtime\n configuration inside Coasts. Coasts manages ports, workspace paths, and\n service discovery independently — use Coastfile `[ports]` and `coast exec`\n instead.\n", + "harnesses/SHEP.md": "# Shep\n\n## Quick setup\n\nRequires the [Coast CLI](../GETTING_STARTED.md). Copy this prompt into your\nagent's chat to set up Coasts automatically:\n\n```prompt-copy\nshep_setup_prompt.txt\n```\n\nYou can also get the skill content from the CLI: `coast skills-prompt`.\n\nAfter setup, **quit and reopen your editor** for the new skill and project\ninstructions to take effect.\n\n---\n\n[Shep](https://shep-ai.github.io/cli/) creates worktrees at `~/.shep/repos/{hash}/wt/{branch-slug}`. The hash is the first 16 hex characters of the SHA-256 of the repository's absolute path, so it is deterministic per-repo but opaque. All worktrees for a given repo share the same hash and are differentiated by the `wt/{branch-slug}` subdirectory.\n\nFrom the Shep CLI, `shep feat show ` prints the worktree path, or\n`ls ~/.shep/repos` lists the per-repo hash directories.\n\nBecause the hash varies per repo, Coasts uses a **glob pattern** to discover\nshep worktrees without requiring the user to hard-code the hash.\n\n## Setup\n\nAdd `~/.shep/repos/*/wt` to `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\nThe `*` matches the per-repo hash directory. At runtime Coasts expands the glob,\nfinds the matching directory (e.g. `~/.shep/repos/a21f0cda9ab9d456/wt`), and\nbind-mounts it into the container. See\n[Worktree Directories](../coastfiles/WORKTREE_DIR.md) for full details on glob\npatterns.\n\nAfter changing `worktree_dir`, existing instances must be **recreated** for the bind mount to take effect:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nThe worktree listing updates immediately (Coasts reads the new Coastfile), but\nassigning to a Shep worktree requires the bind mount inside the container.\n\n## Where Coasts guidance goes\n\nShep wraps Claude Code under the hood, so follow the Claude Code conventions:\n\n- put the short Coast Runtime rules in `CLAUDE.md`\n- put the reusable `/coasts` workflow in `.claude/skills/coasts/SKILL.md` or\n the shared `.agents/skills/coasts/SKILL.md`\n- if this repo also uses other harnesses, see\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) and\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)\n\n## What Coasts does\n\n- **Run** -- `coast run ` creates a new Coast instance from the latest build. Use `coast run -w ` to create and assign a Shep worktree in one step. See [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** -- At container creation, Coasts resolves the glob\n `~/.shep/repos/*/wt` and mounts each matching directory into the container at\n `/host-external-wt/{index}`.\n- **Discovery** -- `git worktree list --porcelain` is repo-scoped, so only\n worktrees belonging to the current project appear.\n- **Naming** -- Shep worktrees use named branches, so they appear by branch\n name in the Coasts UI and CLI (e.g., `feat-green-background`).\n- **Assign** -- `coast assign` remounts `/workspace` from the external bind mount path.\n- **Gitignored sync** -- Runs on the host filesystem with absolute paths, works without the bind mount.\n- **Orphan detection** -- The git watcher scans external directories\n recursively, filtering by `.git` gitdir pointers. If Shep deletes a\n worktree, Coasts auto-unassigns the instance.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/.shep/repos/*/wt` -- Shep (external, bind-mounted via glob expansion)\n\n## Shep path structure\n\n```\n~/.shep/repos/\n {sha256-of-repo-path-first-16-chars}/\n wt/\n {branch-slug}/ <-- git worktree\n {branch-slug}/\n```\n\nKey points:\n- Same repo = same hash every time (deterministic, not random)\n- Different repos = different hashes\n- Path separators are normalized to `/` before hashing\n- The hash can be found via `shep feat show ` or `ls ~/.shep/repos`\n\n## Troubleshooting\n\n- **Worktree not found** — If Coasts expects a worktree to exist but cannot\n find it, verify that the Coastfile's `worktree_dir` includes\n `~/.shep/repos/*/wt`. The glob pattern must match Shep's directory structure.\n See [Worktree Directories](../coastfiles/WORKTREE_DIR.md) for syntax and\n path types.\n", + "harnesses/T3_CODE.md": "# T3 Code\n\n## Quick setup\n\nRequires the [Coast CLI](../GETTING_STARTED.md). Copy this prompt into your\nagent's chat to set up Coasts automatically:\n\n```prompt-copy\nt3_code_setup_prompt.txt\n```\n\nYou can also get the skill content from the CLI: `coast skills-prompt`.\n\nAfter setup, **restart T3 Code** for the skill and rules changes to take effect.\n\n**Note:** T3 Code may not load project-level skills from `.agents/skills/` or\n`.claude/skills/` yet. The setup prompt also places the skill in\n`~/.codex/skills/coasts/` so it is available globally to the Codex provider.\nThe Coast Runtime rules in `AGENTS.md` and `CLAUDE.md` still apply on every\ntask regardless.\n\n---\n\n[T3 Code](https://github.com/pingdotgg/t3code) creates git worktrees at\n`~/.t3/worktrees//`, checked out on named branches.\n\nT3 Code wraps Codex, so it uses `AGENTS.md` for always-on rules and\n`.agents/skills/coasts/SKILL.md` for the reusable `/coasts` workflow.\n\nBecause these worktrees live outside the project root, Coasts needs explicit\nconfiguration to discover and mount them.\n\n## Setup\n\nAdd `~/.t3/worktrees/` to `worktree_dir`. T3 Code nests worktrees under a per-project subdirectory, so the path must include the project name. In the example below, `my-app` must match the actual folder name under `~/.t3/worktrees/` for your repo.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nCoasts expands `~` at runtime and treats any path starting with `~/` or `/` as\nexternal. See [Worktree Directories](../coastfiles/WORKTREE_DIR.md) for\ndetails.\n\nAfter changing `worktree_dir`, existing instances must be **recreated** for the bind mount to take effect:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nThe worktree listing updates immediately (Coasts reads the new Coastfile), but\nassigning to a T3 Code worktree requires the bind mount inside the container.\n\n## Where Coasts guidance goes\n\nUse this layout for T3 Code:\n\n- put the short Coast Runtime rules in `AGENTS.md`\n- put the reusable `/coasts` workflow in `.agents/skills/coasts/SKILL.md`\n- do not add a separate T3-specific project command or slash-command layer for\n Coasts\n- if this repo uses multiple harnesses, see\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) and\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\n## What Coasts does\n\n- **Run** — `coast run ` creates a new Coast instance from the latest build. Use `coast run -w ` to create and assign a T3 Code worktree in one step. See [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — At container creation, Coasts mounts\n `~/.t3/worktrees/` into the container at\n `/host-external-wt/{index}`.\n- **Discovery** — `git worktree list --porcelain` is repo-scoped, so only worktrees belonging to the current project appear.\n- **Naming** — T3 Code worktrees use named branches, so they appear by branch\n name in the Coasts UI and CLI.\n- **Assign** — `coast assign` remounts `/workspace` from the external bind mount path.\n- **Gitignored sync** — Runs on the host filesystem with absolute paths, works without the bind mount.\n- **Orphan detection** — The git watcher scans external directories\n recursively, filtering by `.git` gitdir pointers. If T3 Code removes a\n workspace, Coasts auto-unassigns the instance.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code (local, no special handling)\n- `~/.codex/worktrees/` — Codex (external, bind-mounted)\n- `~/.t3/worktrees/my-app/` — T3 Code (external, bind-mounted; replace `my-app` with your repo folder name)\n\n## Troubleshooting\n\n- **Worktree not found** — If Coasts expects a worktree to exist but cannot\n find it, verify that the Coastfile's `worktree_dir` includes\n `~/.t3/worktrees/` and that `` matches the\n actual folder name under `~/.t3/worktrees/`. See\n [Worktree Directories](../coastfiles/WORKTREE_DIR.md) for syntax and path\n types.\n\n## Limitations\n\n- Avoid relying on T3 Code-specific environment variables for runtime\n configuration inside Coasts. Coasts manages ports, workspace paths, and\n service discovery independently — use Coastfile `[ports]` and `coast exec`\n instead.\n", "harnesses/claude_code_setup_prompt.txt": "You are setting up the Coasts skill for Claude Code in this project. Run all\ncommands from the project root.\n\n## Step 1: Check for Coast CLI\n\nRun this command:\n\n coast --version\n\nIf the `coast` command is not found, stop here and tell the user:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nDo not continue until the CLI is available.\n\n## Step 2: Get the skill content\n\nRun this command:\n\n coast skills-prompt\n\nThe output has two parts:\n\n- **Coast Runtime rules** — everything from the start up to (but not including) the line that begins with `---`\n- **Coasts skill** — everything from the `---` frontmatter block onward (including the `---` lines and everything after them)\n\nSave both parts for the steps below.\n\n## Step 3: Ask the user\n\nAsk the user: should I set this up **globally** (available in every project on this machine) or **for this project only**?\n\n## Step 4: Place files\n\nIf a target file already exists, append the Coast Runtime section rather than overwriting — but check first whether a `# Coast Runtime` section is already present and skip if so.\n\n**Global setup:**\n- Append the Coast Runtime rules to `~/.claude/CLAUDE.md`\n- Write the Coasts skill to `~/.claude/skills/coasts/SKILL.md`\n\n**Project setup:**\n- Append the Coast Runtime rules to `CLAUDE.md` at the project root\n- Write the Coasts skill to `.claude/skills/coasts/SKILL.md`\n\n## Step 5: Update the Coastfile\n\nRead the `Coastfile` at the project root. Look at the `worktree_dir` field in the\n`[coast]` section.\n\nIf `.claude/worktrees` is **not** already listed in `worktree_dir`:\n\n- If `worktree_dir` is a single string, convert it to an array and append\n `.claude/worktrees`. For example, `worktree_dir = \".worktrees\"` becomes\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]`.\n- If `worktree_dir` is already an array, append `.claude/worktrees` to it.\n- If `worktree_dir` is not present at all, add\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]`.\n\nThis is a relative path (inside the project root), so no container recreation is\nneeded — changes take effect immediately for worktree listing.\n\n## Step 6: Confirm\n\nAfter placing files, show the user a summary of what was created and where.\n\nTell the user: **Start a new Claude Code session** for the skill and CLAUDE.md\nchanges to take effect.\n", "harnesses/codex_setup_prompt.txt": "You are setting up the Coasts skill for OpenAI Codex in this project. Run all\ncommands from the project root.\n\n## Step 1: Check for Coast CLI\n\nRun this command:\n\n coast --version\n\nIf the `coast` command is not found, stop here and tell the user:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nDo not continue until the CLI is available.\n\n## Step 2: Get the skill content\n\nRun this command:\n\n coast skills-prompt\n\nThe output has two parts:\n\n- **Coast Runtime rules** — everything from the start up to (but not including) the line that begins with `---`\n- **Coasts skill** — everything from the `---` frontmatter block onward (including the `---` lines and everything after them)\n\nSave both parts for the steps below.\n\n## Step 3: Place files\n\nCodex setup is always project-level. If a target file already exists, append the Coast Runtime section rather than overwriting — but check first whether a `# Coast Runtime` section is already present and skip if so.\n\n- Append the Coast Runtime rules to `AGENTS.md` at the project root\n- Write the Coasts skill to `.agents/skills/coasts/SKILL.md`\n- Create `.agents/skills/coasts/agents/openai.yaml` with this content:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## Step 4: Update the Coastfile\n\nRead the `Coastfile` at the project root. Look at the `worktree_dir` field in the\n`[coast]` section.\n\nIf `~/.codex/worktrees` is **not** already listed in `worktree_dir`:\n\n- If `worktree_dir` is a single string, convert it to an array and append\n `~/.codex/worktrees`. For example, `worktree_dir = \".worktrees\"` becomes\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]`.\n- If `worktree_dir` is already an array, append `~/.codex/worktrees` to it.\n- If `worktree_dir` is not present at all, add\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]`.\n\nThis is an external path, so if a Coast instance is already running for this\nproject it must be recreated with `coast run` for the new bind mount to take\neffect. Tell the user this.\n\n## Step 5: Confirm\n\nAfter placing files, show the user a summary of what was created and where.\n\nTell the user: **Quit and reopen Codex** for the skill and AGENTS.md changes to\ntake effect.\n", "harnesses/conductor_setup_prompt.txt": "You are setting up the Coasts skill for Conductor in this project. Run all\ncommands from the project root.\n\n## Step 1: Check for Coast CLI\n\nRun this command:\n\n coast --version\n\nIf the `coast` command is not found, stop here and tell the user:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nDo not continue until the CLI is available.\n\n## Step 2: Get the skill content\n\nRun this command:\n\n coast skills-prompt\n\nThe output has two parts:\n\n- **Coast Runtime rules** — everything from the start up to (but not including) the line that begins with `---`\n- **Coasts skill** — everything from the `---` frontmatter block onward (including the `---` lines and everything after them)\n\nSave both parts for the steps below.\n\n## Step 3: Ask the user\n\nAsk the user: which providers do you use in Conductor?\n\n- **Claude** (Anthropic)\n- **Codex** (OpenAI)\n- **Both**\n- **Other** — if the user names a different provider, run\n `coast docs --path SKILLS_FOR_HOST_AGENTS.md` and\n `coast docs --path harnesses/README.md` to determine where that provider\n expects project instructions and skills, then follow the same pattern\n\n## Step 4: Place files\n\nConductor setup is always project-level. If a target file already exists, append\nthe Coast Runtime section rather than overwriting — but check first whether a\n`# Coast Runtime` section is already present and skip if so.\n\n**If the user selected Claude (or both):**\n- Append the Coast Runtime rules to `CLAUDE.md` at the project root\n- Write the Coasts skill to `.claude/skills/coasts/SKILL.md`\n\n**If the user selected Codex (or both):**\n- Append the Coast Runtime rules to `AGENTS.md` at the project root\n- Write the Coasts skill to `.agents/skills/coasts/SKILL.md`\n- Create `.agents/skills/coasts/agents/openai.yaml` with this content:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## Step 5: Confirm\n\nAfter placing files, show the user a summary of what was created and where.\n\nTell the user: **Fully close and reopen Conductor** for changes to take effect.\nIf the `/coasts` command does not appear immediately, close and reopen again.\n\n## Step 6: Update the Coastfile\n\nRead the `Coastfile` at the project root. Look at the `worktree_dir` field in the\n`[coast]` section. Also read the `name` field — you will need it to construct the\nworktree path.\n\nThe Conductor worktree directory is `~/conductor/workspaces/`, where\n`` is the value of the `name` field in the Coastfile.\n\nIf that path is **not** already listed in `worktree_dir`:\n\n- If `worktree_dir` is a single string, convert it to an array and append the\n Conductor path. For example, `worktree_dir = \".worktrees\"` becomes\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]`.\n- If `worktree_dir` is already an array, append the Conductor path to it.\n- If `worktree_dir` is not present at all, add\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/\"]` using the\n actual project name.\n\nThis is an external path, so if a Coast instance is already running for this\nproject it must be recreated with `coast run` for the new bind mount to take\neffect. Tell the user this.\n\n## Step 7: Commit the new files\n\nConductor runs each session in an isolated git worktree. Uncommitted files will\nnot carry over to new sessions. Commit the files you just created so they are\navailable in every future workspace:\n\n git add CLAUDE.md .claude/ AGENTS.md .agents/ 2>/dev/null; git status\n\nShow the user which files are staged and ask them to confirm before committing.\nUse a commit message like `[dh] feat: add Coasts skill for Conductor`.\n", @@ -682,6 +682,11 @@ "path": "harnesses/MULTIPLE_HARNESSES.md", "type": "file" }, + { + "name": "SHEP.md", + "path": "harnesses/SHEP.md", + "type": "file" + }, { "name": "T3_CODE.md", "path": "harnesses/T3_CODE.md", @@ -762,11 +767,11 @@ "files": { "README.md": "# Coasts 文档\n\n```youtube\nMBGKSKau4sU\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## 安装\n\n- `curl -fsSL https://coasts.dev/install | sh`\n- `coast daemon install`\n\n*如果你决定不运行 `coast daemon install`,那么你需要负责在每一次都手动通过 `coast daemon start` 启动守护进程。*\n\n## 什么是 Coasts?\n\n一个 Coast(**容器化主机**)是本地开发运行时。Coasts 让你可以在同一台机器上为同一个项目运行多个彼此隔离的环境。\n\nCoasts 对于包含许多相互依赖服务的复杂 `docker-compose` 栈尤其有用,但它们对非容器化的本地开发设置同样有效。Coasts 支持广泛的[运行时配置模式](concepts_and_terminology/RUNTIMES_AND_SERVICES.md),因此你可以为多个并行工作的代理塑造理想环境。\n\nCoasts 是为本地开发而构建的,而不是作为托管的云服务。你的环境会在你的机器上本地运行。\n\nCoasts 项目是免费、本地、MIT 许可、与代理提供方无关、与代理编排工具无关的软件,没有任何 AI 加购。\n\nCoasts 可与任何使用 worktrees 的代理式编码工作流配合使用。不需要在编排工具侧做任何特殊配置。\n\n## 为什么 Coasts 适用于 Worktrees\n\nGit worktrees 非常适合隔离代码变更,但它们本身并不能解决运行时隔离。\n\n当你并行运行多个 worktrees 时,很快就会遇到易用性问题:\n\n- 在期望使用相同主机端口的服务之间发生[端口冲突](concepts_and_terminology/PORTS.md)。\n- 每个 worktree 的数据库与[卷设置](concepts_and_terminology/VOLUMES.md)管理起来很繁琐。\n- 需要为每个 worktree 定制运行时接线的集成测试环境。\n- 在不同 worktree 之间切换并每次都重建运行时上下文的“人间地狱”。参见 [Assign and Unassign](concepts_and_terminology/ASSIGN.md)。\n\n如果说 Git 是你的代码的版本控制,那么 Coasts 就像是你的 worktree 运行时的 Git。\n\n每个环境都会获得自己的一组端口,因此你可以并行检查任何 worktree 运行时。当你[检出](concepts_and_terminology/CHECKOUT.md)某个 worktree 运行时时,Coasts 会将该运行时重新映射到你项目的规范端口。\n\nCoasts 将运行时配置抽象为位于 worktrees 之上的一个简单模块化层,这样每个 worktree 都能以所需的隔离方式运行,而无需手动维护复杂的按 worktree 划分的配置。\n\n## 要求\n\n- macOS 或 Linux\n- macOS 上使用 Docker Desktop,或 Linux 上使用带 Compose 插件的 Docker Engine\n- 一个使用 Git 的项目\n- Node.js\n- `socat`(macOS 上使用 `brew install socat`,Ubuntu 上使用 `sudo apt install socat`)\n\n```text\nLinux 注意:动态端口在 Linux 上开箱即用。\n如果你需要低于 `1024` 的规范端口,请参阅 checkout 文档了解所需的主机配置。\n```\n\n## 将代理容器化?\n\n你可以用一个 Coast 将代理容器化。乍一听这似乎是个好主意,但在很多情况下,你其实并不需要把你的编码代理运行在容器里。\n\n因为 Coasts 通过共享卷挂载与宿主机共享[文件系统](concepts_and_terminology/FILESYSTEM.md),最简单且最可靠的工作流是:在宿主机上运行代理,并指示它使用 [`coast exec`](concepts_and_terminology/EXEC_AND_DOCKER.md) 在 Coast 实例内执行运行时开销较大的任务(例如集成测试)。\n\n不过,如果你确实想在容器中运行你的代理,Coasts 当然也支持通过 [Agent Shells](concepts_and_terminology/AGENT_SHELLS.md) 来实现。你可以为该设置构建一个极其复杂的装置,包括 [MCP 服务器配置](concepts_and_terminology/MCP_SERVERS.md),但它可能无法与当今已有的编排软件良好互操作。对大多数工作流而言,宿主机侧代理更简单也更可靠。\n\n## Coasts vs Dev Containers\n\nCoasts 不是 dev containers,它们也不是同一种东西。\n\nDev containers 通常旨在将一个 IDE 挂载到单个容器化的开发工作区中。Coasts 则是无头的,并且针对使用 worktrees 的并行代理使用场景进行了优化——多个彼此隔离、具备 worktree 感知的运行时环境并排运行,具备快速的检出切换以及针对每个实例的运行时隔离控制。\n\n## 演示仓库\n\n如果你想要一个小型示例项目来试用 Coasts,可以从 [`coasts-demo` 仓库](https://github.com/coast-guard/coasts-demo)开始。\n\n## Coasts 视频课程\n\n如果你更喜欢视频,[Coasts Video Course](learn-coasts-videos/README.md) 会在每节不超过三分钟的内容中讲解每一个核心概念。\n", "GETTING_STARTED.md": "# Coasts 入门\n\n```youtube\nJe921fgJ4RY\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## 安装\n\n```bash\ncurl -fsSL https://coasts.dev/install | sh\ncoast daemon install\n```\n\n*如果你决定不运行 `coast daemon install`,那么你需要负责每一次都手动通过 `coast daemon start` 启动守护进程。*\n\n## 要求\n\n- macOS 或 Linux\n- 在 macOS 上使用 Docker Desktop,或在 Linux 上使用带 Compose 插件的 Docker Engine\n- 使用 Git 的项目\n- Node.js\n- `socat`(在 macOS 上运行 `brew install socat`,在 Ubuntu 上运行 `sudo apt install socat`)\n\n```text\nLinux note: Dynamic ports work out of the box on Linux.\nIf you need canonical ports below `1024`, see the checkout docs for the required host configuration.\n```\n\n## 在项目中设置 Coasts\n\n在项目根目录添加一个 Coastfile。安装时请确保你不在 worktree 上。\n\n```text\nmy-project/\n├── Coastfile <-- this is what Coast reads\n├── docker-compose.yml\n├── Dockerfile\n├── src/\n│ └── ...\n└── ...\n```\n\n`Coastfile` 指向你现有的本地开发资源,并添加 Coasts 特有的配置——完整 schema 请参阅 [Coastfiles documentation](coastfiles/README.md):\n\n```toml\n[coast]\nname = \"my-project\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\ndb = 5432\n```\n\nCoastfile 是一个轻量级的 TOML 文件,*通常*会指向你现有的 `docker-compose.yml`(也适用于非容器化的本地开发设置),并描述为了并行运行你的项目所需的修改——端口映射、卷策略以及密钥。将它放在你的项目根目录。\n\n为你的项目创建 Coastfile 的最快方式是让你的编码智能体来完成。\n\nCoasts CLI 内置了一个 prompt,可向任何 AI 智能体讲解完整的 Coastfile schema 和 CLI。把它复制到你智能体的聊天中,它会分析你的项目并生成一个 Coastfile。\n\n```prompt-copy\ninstallation_prompt.txt\n```\n\n你也可以通过运行 `coast installation-prompt` 从 CLI 获取相同的输出。\n\n## 你的第一个 Coast\n\n在启动你的第一个 Coast 之前,先关闭任何正在运行的开发环境。如果你使用 Docker Compose,请运行 `docker-compose down`。如果你有本地开发服务器在运行,请停止它们。Coasts 会管理自己的端口,并且会与任何已在监听的服务产生冲突。\n\n当你的 Coastfile 准备好后:\n\n```bash\ncoast build\ncoast run dev-1\n```\n\n检查你的实例是否在运行:\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ~/dev/my-project\n```\n\n查看你的服务在监听哪些端口:\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\n每个实例都会获得自己的一组动态端口,这样多个实例就可以并排运行。要将实例映射回你项目的规范端口,请将其 checkout:\n\n```bash\ncoast checkout dev-1\n```\n\n这意味着运行时现在已被 checkout,你项目的规范端口(例如 `3000`、`5432`)将路由到这个 Coast 实例。\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ✓ ~/dev/my-project\n```\n\n为你的项目打开 Coastguard 可观测性 UI:\n\n```bash\ncoast ui\n```\n\n## 接下来做什么?\n\n- 为你的主机智能体设置一个 [skill for your host agent](SKILLS_FOR_HOST_AGENTS.md),让它知道如何与 Coasts 交互\n", - "SKILLS_FOR_HOST_AGENTS.md": "# 主机代理的技能\n\n如果你在主机上使用 AI 编码代理,而你的应用运行在 Coasts 内部,那么你的代理通常需要两项 Coasts 特定的设置:\n\n1. 在 harness 的项目说明文件或规则文件中加入始终启用的 Coast Runtime 部分\n2. 在 harness 支持项目技能时,添加一个可复用的 Coast 工作流技能,例如 `/coasts`\n\n如果缺少第一项,代理会编辑文件,但会忘记使用 `coast exec`。\n如果缺少第二项,那么每次涉及 Coast 分配、日志和 UI 流程时,都必须在聊天中重新解释。\n\n本指南会把设置讲得具体且聚焦于 Coasts:要创建哪个文件、其中应放入什么文本,以及这些内容如何因 harness 而异。\n\n## 为什么代理需要这个\n\nCoasts 在你的主机和 Coast 容器之间共享[文件系统](concepts_and_terminology/FILESYSTEM.md)。你的代理在主机上编辑文件,而 Coast 内运行的服务会立即看到这些更改。但代理仍然需要:\n\n1. 发现哪个 Coast 实例与当前 checkout 匹配\n2. 在该 Coast 内运行测试、构建和运行时命令\n3. 从 Coast 读取日志和服务状态\n4. 在尚未附加任何 Coast 时安全地处理 worktree 分配\n\n## 各部分应放在哪里\n\n- `AGENTS.md`、`CLAUDE.md` 或 `.cursor/rules/coast.md` —— 简短的 Coast 规则\n 即使未调用任何技能,也应在每个任务中生效\n- skill(`.agents/skills/...`、`.claude/skills/...` 或 `.cursor/skills/...`)\n —— 可复用的 Coast 工作流本身,例如 `/coasts`\n- command file(`.claude/commands/...` 或 `.cursor/commands/...`)—— 可选的\n 显式入口点,供支持它的 harness 使用;一个简单的做法是让命令复用该技能\n\n如果一个仓库使用多个 harness,请将规范的 Coast 技能保存在一个位置,\n并在需要的地方暴露出来。参见\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md)。\n\n## 1. 始终启用的 Coast Runtime 规则\n\n将以下代码块添加到 harness 的始终启用项目说明文件或规则文件中\n(`AGENTS.md`、`CLAUDE.md`、`.cursor/rules/coast.md` 或等效文件):\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\n这个代码块应放在始终启用的文件中,因为这些规则应在每个任务中生效,\n而不仅仅是在代理显式进入 `/coasts` 工作流时才生效。\n\n## 2. 可复用的 `/coasts` 技能\n\n当 harness 支持项目技能时,请将技能内容保存为技能目录中的\n`SKILL.md`。完整的技能文本位于\n[skills_prompt.txt](skills_prompt.txt)(如果使用 CLI 模式,请使用\n`coast skills-prompt`)—— Coast Runtime 代码块之后的所有内容都是技能\n内容,从 `---` frontmatter 开始。\n\n如果你使用 Codex 或 OpenAI 特定的界面,还可以选择在技能旁边添加\n`agents/openai.yaml`,用于显示元数据或调用策略。\n这些元数据应与技能放在一起,而不是取代技能本身。\n\n## Harness 快速开始\n\n| Harness | 始终启用文件 | 可复用的 Coast 工作流 | 说明 |\n|---------|----------------|-------------------------|-------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | 对于 Coast 文档,不建议单独使用项目命令文件。参见 [Codex](harnesses/CODEX.md)。 |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md` 是可选的,但逻辑应保留在技能中。参见 [Claude Code](harnesses/CLAUDE_CODE.md)。 |\n| Cursor | `AGENTS.md` 或 `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` 或共享的 `.agents/skills/coasts/SKILL.md` | `.cursor/commands/coasts.md` 是可选的。`.cursor/worktrees.json` 用于 Cursor worktree 引导,而不是 Coast 策略。参见 [Cursor](harnesses/CURSOR.md)。 |\n| Conductor | `CLAUDE.md` | 从 `CLAUDE.md` 开始;使用 Conductor 脚本和设置来处理 Conductor 特定行为 | 不要假设其完整支持 Claude Code 的项目命令行为。如果新命令没有出现,请彻底关闭并重新打开 Conductor。参见 [Conductor](harnesses/CONDUCTOR.md)。 |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | 这是这里功能最有限的 harness 界面。使用 Codex 风格的布局,不要为 Coast 文档虚构 T3 原生命令层。参见 [T3 Code](harnesses/T3_CODE.md)。 |\n\n## 让代理自行完成设置\n\n最快的方法是让代理自己写入正确的文件。将下面的提示复制到你的代理聊天中——它包含 Coast Runtime 代码块、`coasts` 技能代码块,以及每个部分应放在哪里的 harness 特定说明。\n\n```prompt-copy\nskills_prompt.txt\n```\n\n你也可以通过运行 `coast skills-prompt` 从 CLI 获取相同的输出。\n\n## 手动设置\n\n- **Codex:** 将 Coast Runtime 部分放入 `AGENTS.md`,然后将可复用的\n `coasts` 技能放入 `.agents/skills/coasts/SKILL.md`。\n- **Claude Code:** 将 Coast Runtime 部分放入 `CLAUDE.md`,然后将可复用的\n `coasts` 技能放入 `.claude/skills/coasts/SKILL.md`。只有在你明确需要命令文件时,\n 才添加 `.claude/commands/coasts.md`。\n- **Cursor:** 如果你想要最具可移植性的说明,请将 Coast Runtime 部分放入 `AGENTS.md`;\n 如果你想使用 Cursor 原生项目规则,则放入 `.cursor/rules/coast.md`。将可复用的\n `coasts` 工作流放入 `.cursor/skills/coasts/SKILL.md`(适用于仅使用 Cursor 的仓库),\n 或放入 `.agents/skills/coasts/SKILL.md`(适用于与其他 harness 共享的仓库)。\n 只有在你明确想要显式命令文件时,才添加 `.cursor/commands/coasts.md`。\n- **Conductor:** 将 Coast Runtime 部分放入 `CLAUDE.md`。使用 Conductor\n Repository Settings 脚本来处理 Conductor 特定的引导或运行行为。\n 如果你添加了命令但没有显示出来,请彻底关闭并重新打开应用。\n- **T3 Code:** 使用与 Codex 相同的布局:`AGENTS.md` 加上\n `.agents/skills/coasts/SKILL.md`。这里应将 T3 Code 视为轻量的 Codex 风格\n harness,而不是单独的 Coast 命令界面。\n- **多个 harness:** 将规范技能保存在\n `.agents/skills/coasts/SKILL.md` 中。Cursor 可以直接加载它;如有需要,\n 可通过 `.claude/skills/coasts/` 将其暴露给 Claude Code。\n\n## 延伸阅读\n\n- 阅读 [Harnesses guide](harnesses/README.md) 了解各 harness 的矩阵\n- 阅读 [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md) 了解共享布局模式\n- 阅读 [Coastfiles documentation](coastfiles/README.md) 以了解完整的配置模式\n- 学习用于管理实例的 [Coast CLI](concepts_and_terminology/CLI.md) 命令\n- 探索 [Coastguard](concepts_and_terminology/COASTGUARD.md),这是用于观察和控制你的 Coasts 的 Web UI\n", + "SKILLS_FOR_HOST_AGENTS.md": "# 主机代理的技能\n\n如果你在主机上使用 AI 编码代理,而你的应用运行在 Coasts 内部,那么你的代理通常需要两项 Coasts 特定的设置:\n\n1. 在 harness 的项目说明文件或规则文件中加入始终启用的 Coast Runtime 部分\n2. 在 harness 支持项目技能时,添加一个可复用的 Coast 工作流技能,例如 `/coasts`\n\n如果缺少第一项,代理会编辑文件,但会忘记使用 `coast exec`。\n如果缺少第二项,那么每次涉及 Coast 分配、日志和 UI 流程时,都必须在聊天中重新解释。\n\n本指南会把设置讲得具体且聚焦于 Coasts:要创建哪个文件、其中应放入什么文本,以及这些内容如何因 harness 而异。\n\n## 为什么代理需要这个\n\nCoasts 在你的主机和 Coast 容器之间共享[文件系统](concepts_and_terminology/FILESYSTEM.md)。你的代理在主机上编辑文件,而 Coast 内运行的服务会立即看到这些更改。但代理仍然需要:\n\n1. 发现哪个 Coast 实例与当前 checkout 匹配\n2. 在该 Coast 内运行测试、构建和运行时命令\n3. 从 Coast 读取日志和服务状态\n4. 在尚未附加任何 Coast 时安全地处理 worktree 分配\n\n## 各部分应放在哪里\n\n- `AGENTS.md`、`CLAUDE.md` 或 `.cursor/rules/coast.md` —— 简短的 Coast 规则\n 即使未调用任何技能,也应在每个任务中生效\n- skill(`.agents/skills/...`、`.claude/skills/...` 或 `.cursor/skills/...`)\n —— 可复用的 Coast 工作流本身,例如 `/coasts`\n- command file(`.claude/commands/...` 或 `.cursor/commands/...`)—— 可选的\n 显式入口点,供支持它的 harness 使用;一个简单的做法是让命令复用该技能\n\n如果一个仓库使用多个 harness,请将规范的 Coast 技能保存在一个位置,\n并在需要的地方暴露出来。参见\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md)。\n\n## 1. 始终启用的 Coast Runtime 规则\n\n将以下代码块添加到 harness 的始终启用项目说明文件或规则文件中\n(`AGENTS.md`、`CLAUDE.md`、`.cursor/rules/coast.md` 或等效文件):\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n coast exec --service # service shell\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Use `coast exec --service ` when you need to run inside an app/service container.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\n这个代码块应放在始终启用的文件中,因为这些规则应在每个任务中生效,\n而不仅仅是在代理显式进入 `/coasts` 工作流时才生效。\n\n## 2. 可复用的 `/coasts` 技能\n\n当 harness 支持项目技能时,请将技能内容保存为技能目录中的\n`SKILL.md`。完整的技能文本位于\n[skills_prompt.txt](skills_prompt.txt)(如果使用 CLI 模式,请使用\n`coast skills-prompt`)—— Coast Runtime 代码块之后的所有内容都是技能\n内容,从 `---` frontmatter 开始。\n\n如果你使用 Codex 或 OpenAI 特定的界面,还可以选择在技能旁边添加\n`agents/openai.yaml`,用于显示元数据或调用策略。\n这些元数据应与技能放在一起,而不是取代技能本身。\n\n## Harness 快速开始\n\n| Harness | 始终启用文件 | 可复用的 Coast 工作流 | 说明 |\n|---------|----------------|-------------------------|-------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | 对于 Coast 文档,不建议单独使用项目命令文件。参见 [Codex](harnesses/CODEX.md)。 |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md` 是可选的,但逻辑应保留在技能中。参见 [Claude Code](harnesses/CLAUDE_CODE.md)。 |\n| Cursor | `AGENTS.md` 或 `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` 或共享的 `.agents/skills/coasts/SKILL.md` | `.cursor/commands/coasts.md` 是可选的。`.cursor/worktrees.json` 用于 Cursor worktree 引导,而不是 Coast 策略。参见 [Cursor](harnesses/CURSOR.md)。 |\n| Conductor | `CLAUDE.md` | 从 `CLAUDE.md` 开始;使用 Conductor 脚本和设置来处理 Conductor 特定行为 | 不要假设其完整支持 Claude Code 的项目命令行为。如果新命令没有出现,请彻底关闭并重新打开 Conductor。参见 [Conductor](harnesses/CONDUCTOR.md)。 |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | 这是这里功能最有限的 harness 界面。使用 Codex 风格的布局,不要为 Coast 文档虚构 T3 原生命令层。参见 [T3 Code](harnesses/T3_CODE.md)。 |\n\n## 让代理自行完成设置\n\n最快的方法是让代理自己写入正确的文件。将下面的提示复制到你的代理聊天中——它包含 Coast Runtime 代码块、`coasts` 技能代码块,以及每个部分应放在哪里的 harness 特定说明。\n\n```prompt-copy\nskills_prompt.txt\n```\n\n你也可以通过运行 `coast skills-prompt` 从 CLI 获取相同的输出。\n\n## 手动设置\n\n- **Codex:** 将 Coast Runtime 部分放入 `AGENTS.md`,然后将可复用的\n `coasts` 技能放入 `.agents/skills/coasts/SKILL.md`。\n- **Claude Code:** 将 Coast Runtime 部分放入 `CLAUDE.md`,然后将可复用的\n `coasts` 技能放入 `.claude/skills/coasts/SKILL.md`。只有在你明确需要命令文件时,\n 才添加 `.claude/commands/coasts.md`。\n- **Cursor:** 如果你想要最具可移植性的说明,请将 Coast Runtime 部分放入 `AGENTS.md`;\n 如果你想使用 Cursor 原生项目规则,则放入 `.cursor/rules/coast.md`。将可复用的\n `coasts` 工作流放入 `.cursor/skills/coasts/SKILL.md`(适用于仅使用 Cursor 的仓库),\n 或放入 `.agents/skills/coasts/SKILL.md`(适用于与其他 harness 共享的仓库)。\n 只有在你明确想要显式命令文件时,才添加 `.cursor/commands/coasts.md`。\n- **Conductor:** 将 Coast Runtime 部分放入 `CLAUDE.md`。使用 Conductor\n Repository Settings 脚本来处理 Conductor 特定的引导或运行行为。\n 如果你添加了命令但没有显示出来,请彻底关闭并重新打开应用。\n- **T3 Code:** 使用与 Codex 相同的布局:`AGENTS.md` 加上\n `.agents/skills/coasts/SKILL.md`。这里应将 T3 Code 视为轻量的 Codex 风格\n harness,而不是单独的 Coast 命令界面。\n- **多个 harness:** 将规范技能保存在\n `.agents/skills/coasts/SKILL.md` 中。Cursor 可以直接加载它;如有需要,\n 可通过 `.claude/skills/coasts/` 将其暴露给 Claude Code。\n\n## 延伸阅读\n\n- 阅读 [Harnesses guide](harnesses/README.md) 了解各 harness 的矩阵\n- 阅读 [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md) 了解共享布局模式\n- 阅读 [Coastfiles documentation](coastfiles/README.md) 以了解完整的配置模式\n- 学习用于管理实例的 [Coast CLI](concepts_and_terminology/CLI.md) 命令\n- 探索 [Coastguard](concepts_and_terminology/COASTGUARD.md),这是用于观察和控制你的 Coasts 的 Web UI\n", "VIDEO_TUTORIALS.md": "# 视频教程\n\n本页面汇总了来自 Coasts YouTube 频道的官方 Coasts 教程视频。\n\n如果你更喜欢在阅读其余文档之前先快速观看视频讲解,建议先从概览和入门视频开始,然后再跳到下面按功能分类的主题。\n\n## 链接\n\n- [Coasts YouTube channel](https://www.youtube.com/@coasts-dev) - Coasts 视频的官方频道。\n- [Coasts playlist](https://www.youtube.com/playlist?list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw) - 将完整教程播放列表集中在一处。\n\n## 视频\n\n- [Coasts Overview](https://www.youtube.com/watch?v=MBGKSKau4sU&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=1&pp=iAQB) (2:42) - 对 Coasts 是什么以及你为什么可能会使用它们的高层介绍。\n- [Coasts](https://www.youtube.com/watch?v=kYlB5U9O92E&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=2&pp=iAQB) (1:29) - 对核心 Coasts 模型的简短导览。\n- [Ports](https://www.youtube.com/watch?v=pBKkBiJ3o-g&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=3&pp=iAQB) (1:46) - Coasts 如何处理端口隔离与并行运行时访问。\n- [Assign](https://www.youtube.com/watch?v=LYCeequ54nk&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=4&pp=iAQB) (1:57) - 如何在 worktree 之间切换正在运行的 Coast。\n- [Checkout](https://www.youtube.com/watch?v=JRAXkM4U1UE&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=5&pp=iAQB) (1:46) - 如何将一个 Coast 切换到你的规范端口以便进行活跃使用。\n- [Volumes](https://www.youtube.com/watch?v=k1es1Wf0zp0&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=6&pp=iAQB) (2:00) - Coasts 如何处理卷(volumes)以及持久化的服务状态。\n- [Secrets](https://www.youtube.com/watch?v=4lAfHUjqn50&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=7&pp=iAQB) (2:09) - 在 Coast 内管理密钥(secrets)。\n- [Getting Started](https://www.youtube.com/watch?v=Je921fgJ4RY&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=8&pp=iAQB) (2:40) - 体验 Coasts 的快速上手引导。\n- [Coast UI](https://www.youtube.com/watch?v=Ts-YWkhHR8I&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=9&pp=iAQB0gcJCa4KAYcqIYzv) (1:46) - Coastguard UI 的导览及其展示的运行时信息。\n\n本页面反映官方播放列表的当前内容,并会在新增教程视频时进行更新。\n", - "doc_ordering.txt": "# 顶层\nREADME.md\nGETTING_STARTED.md\nSKILLS_FOR_HOST_AGENTS.md\n\n# 学习 Coasts\nlearn-coasts-videos/README.md\nlearn-coasts-videos/coasts.md\nlearn-coasts-videos/ports.md\nlearn-coasts-videos/assign.md\nlearn-coasts-videos/checkout.md\nlearn-coasts-videos/volumes.md\nlearn-coasts-videos/secrets.md\nlearn-coasts-videos/getting-started.md\nlearn-coasts-videos/coast-ui.md\n\n# Harnesses\nharnesses/README.md\nharnesses/CODEX.md\nharnesses/CONDUCTOR.md\nharnesses/CLAUDE_CODE.md\nharnesses/CURSOR.md\nharnesses/T3_CODE.md\nharnesses/MULTIPLE_HARNESSES.md\n\n# 概念与术语\nconcepts_and_terminology/README.md\nconcepts_and_terminology/COASTS.md\nconcepts_and_terminology/RUN.md\nconcepts_and_terminology/REMOVE.md\nconcepts_and_terminology/FILESYSTEM.md\nconcepts_and_terminology/DAEMON.md\nconcepts_and_terminology/CLI.md\nconcepts_and_terminology/COASTGUARD.md\nconcepts_and_terminology/PORTS.md\nconcepts_and_terminology/PRIMARY_PORT_AND_DNS.md\nconcepts_and_terminology/ASSIGN.md\nconcepts_and_terminology/CHECKOUT.md\nconcepts_and_terminology/LOOKUP.md\nconcepts_and_terminology/VOLUMES.md\nconcepts_and_terminology/SHARED_SERVICES.md\nconcepts_and_terminology/SECRETS.md\nconcepts_and_terminology/BUILDS.md\nconcepts_and_terminology/COASTFILE_TYPES.md\nconcepts_and_terminology/RUNTIMES_AND_SERVICES.md\nconcepts_and_terminology/BARE_SERVICES.md\nconcepts_and_terminology/MIXED_SERVICE_TYPES.md\nconcepts_and_terminology/LOGS.md\nconcepts_and_terminology/EXEC_AND_DOCKER.md\nconcepts_and_terminology/AGENT_SHELLS.md\nconcepts_and_terminology/MCP_SERVERS.md\nconcepts_and_terminology/PERFORMANCE_OPTIMIZATIONS.md\nconcepts_and_terminology/TROUBLESHOOTING.md\n\n# Coastfiles\ncoastfiles/README.md\ncoastfiles/PROJECT.md\ncoastfiles/WORKTREE_DIR.md\ncoastfiles/PORTS.md\ncoastfiles/SHARED_SERVICES.md\ncoastfiles/SERVICES.md\ncoastfiles/SECRETS.md\ncoastfiles/VOLUMES.md\ncoastfiles/ASSIGN.md\ncoastfiles/INHERITANCE.md\ncoastfiles/AGENT_SHELL.md\ncoastfiles/MCP.md\n\n# 配方\nrecipes/README.md\nrecipes/FULLSTACK_MONOREPO.md\n", - "installation_prompt.txt": "你正在将 Coasts 安装到这个项目中。Coast(容器化主机)是一个 CLI 工具,它使用 Docker-in-Docker 容器在一台机器上运行多个相互隔离的开发环境。每个环境都有自己的端口、卷和运行时——非常适合并行 worktree 工作流。\n\n你的任务:分析这个项目并生成一个 Coastfile(位于项目根目录、名为 “Coastfile” 的 TOML 文件)。\n\n=== DOCUMENTATION ===\n\nCoast 内置文档可通过 CLI 访问。在生成 Coastfile 之前,使用这些文档来理解完整的 Coastfile schema、卷策略、assign 行为以及其他配置选项。\n\n浏览文档树:\n\n coast docs\n\n这会打印完整的文档树。首先阅读 README 文件——它们提供索引,帮助你为每个主题找到合适的文档:\n\n coast docs --path README.md\n coast docs --path coastfiles/README.md\n coast docs --path concepts_and_terminology/README.md\n\n阅读特定文档:\n\n coast docs --path coastfiles/PROJECT.md\n coast docs --path coastfiles/VOLUMES.md\n\n搜索文档(语义搜索——用自然语言描述你在找什么):\n\n coast search-docs \"how do volume strategies work\"\n coast search-docs \"shared postgres across instances\"\n coast search-docs \"secret injection from environment variables\"\n\n使用文档来对该项目的 Coastfile 配置做出明智的决策。coastfiles/ 部分详细涵盖了每一条 Coastfile 指令。\n\n=== COASTFILE SCHEMA (quick reference) ===\n\n[coast] — 必需。项目元数据。\n\n name (string, required) 用于容器/卷命名的项目标识符。\n compose (string, optional) 相对于 Coastfile 的 docker-compose.yml 路径。\n runtime (string, optional) \"dind\"(默认)、\"sysbox\" 或 \"podman\"。\n root (string, optional) 项目根目录覆盖(相对或绝对)。\n worktree_dir (string, optional) git worktree 的目录(默认:\".worktrees\")。运行时会从现有 worktrees 自动检测。\n\n[coast.setup] — 可选。自定义 DinD 容器本身。\n\n packages (array of strings) 要安装的 Alpine 包(例如 [\"nodejs\", \"npm\", \"git\"])。\n run (array of strings) 在 setup 期间要运行的任意命令。\n\n[ports] — 必需(至少一个)。逻辑名称到端口号的映射。\n 当 coast 被检出时,这些端口会被转发到宿主机。\n\n 示例:\n [ports]\n web = 3000\n api = 8080\n postgres = 5432\n\n[volumes.*] — 可选。按卷的配置。\n\n strategy \"isolated\"(默认)或 \"shared\"\n service 拥有该卷的 Compose 服务名。\n mount 在服务容器内的挂载路径。\n snapshot_source (仅 isolated) 从现有卷名称进行种子初始化。\n\n 示例:\n [volumes.postgres_data]\n strategy = \"isolated\"\n service = \"db\"\n mount = \"/var/lib/postgresql/data\"\n\n[secrets.*] — 可选。机密提取与注入。\n\n extractor \"file\"、\"env\"、\"command\" 或 \"macos-keychain\"\n inject \"env:VAR_NAME\" 或 \"file:/path/in/container\"\n ttl 可选过期时间(例如 \"1h\"、\"30m\")。\n\n 提取器特定参数:\n file: path = \"./path/to/secret\"\n env: var = \"HOST_ENV_VAR\"\n command: run = \"echo secret-value\"\n macos-keychain: item = \"keychain-item-name\"\n\n 示例:\n [secrets.db_password]\n extractor = \"env\"\n var = \"DB_PASSWORD\"\n inject = \"env:DATABASE_PASSWORD\"\n\n[inject] — 可选。非机密的宿主机文件/环境变量注入。\n\n env 要转发的宿主机环境变量名数组。\n files 要挂载的宿主机文件路径数组。\n\n 示例:\n [inject]\n env = [\"NODE_ENV\", \"DEBUG\"]\n files = [\"~/.ssh/id_ed25519\", \"~/.gitconfig\"]\n\n[shared_services.*] — 可选。宿主机 Docker 守护进程上的服务,在多个实例间共享。\n\n image Docker 镜像。\n ports 端口号数组。\n volumes 卷挂载数组。\n env 环境变量内联表。\n auto_create_db (bool) 自动创建每实例一个数据库。\n inject 将连接字符串注入到 coast 容器中。\n\n 示例:\n [shared_services.postgres]\n image = \"postgres:16-alpine\"\n ports = [5432]\n volumes = [\"postgres_data:/var/lib/postgresql/data\"]\n env = { POSTGRES_USER = \"dev\", POSTGRES_PASSWORD = \"dev\", POSTGRES_DB = \"app\" }\n auto_create_db = true\n inject = \"env:DATABASE_URL\"\n\n[assign] — 可选。控制分支切换时发生什么(coast assign)。\n\n default \"none\"、\"restart\" 或 \"rebuild\"\n [assign.services] 按服务覆盖。\n [assign.rebuild_triggers] 按服务的文件 glob,触发 rebuild。\n\n 示例:\n [assign]\n default = \"none\"\n [assign.services]\n api = \"restart\"\n worker = \"rebuild\"\n [assign.rebuild_triggers]\n worker = [\"Dockerfile\", \"package.json\"]\n\n[services.*] — 可选。裸进程服务(无需 docker-compose)。\n\n command 要运行的 Shell 命令。\n port 端口号。\n restart \"on-failure\" 或 \"always\"。\n\n 示例:\n [services.web]\n command = \"node server.js\"\n port = 3000\n restart = \"on-failure\"\n\n=== EXAMPLE: Minimal (no compose) ===\n\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[ports]\napp = 3000\n\n=== EXAMPLE: With docker-compose ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\npostgres = 5432\nredis = 6379\n\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n\n=== EXAMPLE: With secrets ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\n\n[secrets.api_key]\nextractor = \"env\"\nvar = \"API_KEY\"\ninject = \"env:API_KEY\"\n\n[secrets.ssh_key]\nextractor = \"file\"\npath = \"~/.ssh/id_ed25519\"\ninject = \"file:/run/secrets/ssh_key\"\n\n=== KEY TRADEOFFS TO DISCUSS WITH THE USER ===\n\n在生成 Coastfile 之前,向用户询问任何不明确的配置选择。主要包括以下内容:\n\n数据库与基础设施策略——对于 postgres、redis 之类的服务,有三种选择:\n - 隔离卷(默认):每个 Coast 实例在其 DinD 容器内都有自己的一份数据副本。实例之间不会相互干扰。适合需要按分支维护数据库状态的场景。\n - 共享卷:所有实例在其 DinD 容器内读写同一个卷。节省磁盘空间,但多个实例并发写入可能会导致数据损坏。\n - 共享服务:在宿主机 Docker 守护进程上运行数据库,而不是在每个 Coast 内部运行。所有实例连接到一个共享服务器。占用内存最少,支持 auto_create_db 在单个 postgres 上为每个实例创建数据库,并且数据在实例删除后仍然保留。适合大型团队或内存受限的机器。\n - 如果项目有数据库,询问用户希望采用哪种方式。解释权衡——隔离最安全,共享服务最节省内存。\n\nAssign 策略——在 worktree 之间切换 Coast 时会发生什么:\n - \"none\":不做任何事(适用于 postgres/redis 等在分支之间不变化的服务)。\n - \"restart\":重启容器(适用于解释型服务,只需要重启进程)。\n - \"rebuild\":重建 Docker 镜像并重启(适用于分支变化会影响 Dockerfile 或构建依赖的服务)。\n - 如果项目有多个服务,询问哪些在分支切换时需要 rebuild,哪些只需要 restart。\n\n=== INSTRUCTIONS ===\n\n1. 查看该项目的结构。如果有 docker-compose.yml,读取它以识别服务、端口和卷。\n2. 检测现有的 git worktree 目录。运行 `git worktree list` 检查项目是否已经设置了 git worktrees。\n - 如果存在 worktrees,检查它们的路径以确定共同的父目录(例如,如果 worktrees 位于 `../.worktrees/feat-a` 和 `../.worktrees/feat-b`,则 worktree_dir 是 `\"../.worktrees\"`)。\n - 在 Coastfile 中设置 `worktree_dir` 以匹配检测到的目录。\n - 如果不存在 worktrees,省略 `worktree_dir`(Coast 默认为 \".worktrees\")。不要使用 \".coasts\"——那会用 Coast 品牌目录污染项目。\n3. 阅读相关 Coast 文档(使用 `coast docs` 和 `coast search-docs`)以理解卷策略、assign 行为以及适用于该项目技术栈的配置选项。\n4. 向用户询问任何不明确的配置选择(参见上面的权衡)。不要猜测——解释选项并让他们决定。\n5. 基于项目分析与用户输入,在项目根目录生成一个 Coastfile。\n6. 如果项目没有 docker-compose.yml,使用 [services.*] 定义裸进程,或使用 [coast.setup] 安装依赖。\n7. 运行 `coast build`。如果失败,检查错误并查阅文档(`coast search-docs \"\"`)进行排障。\n8. 运行 `coast run dev-1`。如果失败,检查错误并查阅文档。\n9. 运行 `coast ui` 打开 Coastguard 仪表盘(这是在你完成后供用户使用的)。\n", - "skills_prompt.txt": "# Coast Runtime\n\n此项目使用 Coasts——用于运行服务、测试和其他运行时命令的容器化运行时。主机与容器之间共享文件系统,因此任一侧的文件编辑都会立即对双方可见。\n\n## Discovery\n\n在会话中的第一个运行时命令之前,运行:\n\n coast lookup\n\n这会打印实例名称、端口和示例命令。对所有后续命令,都使用输出中的实例名称。\n\n## What runs where\n\n文件系统是共享的,因此只有在需要容器运行时的情况下才使用 `coast exec`(数据库、服务、集成测试)。其他所有内容都直接在主机上运行。\n\n在以下情况下使用 `coast exec`:\n- 需要运行中服务的测试(与服务或数据库集成的单元测试、集成测试、API 测试)\n- 服务重启或 compose 操作\n- 任何与数据库、缓存或其他容器服务交互的内容\n\n直接在主机上运行:\n- Lint、类型检查、格式化\n- Git 操作\n- Playwright 和浏览器测试\n- 安装主机侧依赖(npm install、pip install)\n- 文件搜索、代码生成、静态分析\n\n示例:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\n如果 `coast lookup` 没有返回匹配项,运行 `coast ls` 查看已有内容。\n\n如果此项目已有一个未分配的 Coast 正在运行,优先将你的 worktree 分配给它,而不是创建新的:\n\n coast assign -w \n\n已被占用的 Coast 也可以使用 `coast assign` 重新分配,但要先与用户确认,因为这会扰乱当前槽位。\n\n如果当前没有运行中的 Coast,请在创建前先询问用户——Coasts 可能会占用大量内存:\n\n coast run -w \n\n项目必须先构建,才能创建实例。如果 `coast run` 因为没有现有构建而失败,先运行 `coast build`。\n\n## Coastfile setup\n\n如果项目还没有 Coastfile,或者你需要修改 Coastfile,请先阅读 Coastfile 文档:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\n在猜测 Coast 行为之前,先查看文档:\n\n coast docs # 列出所有文档页面\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # 语义搜索\n\n## Rules\n\n- 在会话中的第一个运行时命令之前,始终运行 `coast lookup`。\n- 仅对需要容器运行时的内容使用 `coast exec`。\n- 直接在主机上运行 lint、类型检查、格式化和 git。\n- 在猜测 Coast 行为之前,使用 `coast docs` 或 `coast search-docs`。\n- 当项目要求使用 Coast 时,不要直接在主机上运行服务。\n\n---\nname: coasts\ndescription: Inspect and control Coast instances for the current checkout. Use\n when the user says \"/coasts\", asks to assign or reassign a Coast, wants to\n run commands or read logs in the matching Coast, wants to create a new Coast,\n or explicitly asks to open Coast UI.\n---\n\n# Coasts\n\n直接使用 Coast CLI。不要添加包装器。\n\n## Orient Yourself\n\n先浏览 CLI 和文档:\n\n coast # 查看所有可用命令\n coast docs # 列出所有文档页面\n coast search-docs \"your question\" # 语义搜索\n\n如果对 Coast 的行为有任何不清楚之处,请先阅读文档,不要猜测:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\n将请求路由到以下模式之一:\n\n1. **Use Coast** —— 运行 `coast lookup`,然后对匹配的实例使用 `coast exec`、`coast ps` 或 `coast logs`。\n2. **Create or Assign** —— 运行 `coast ls`,然后使用 `coast run` 创建新的 Coast,或使用 `coast assign` 重新指向现有 Coast。\n3. **Open UI** —— 运行 `coast ui`。\n\n## What Runs Where\n\n主机与 Coast 共享文件系统。仅在需要容器内运行中的服务时才使用 `coast exec`。\n\n**在以下情况下使用 `coast exec`:**\n- 集成测试、API 测试,以及任何需要数据库或服务的内容\n- 服务重启、compose 操作\n- 与仅存在于容器中的进程交互的命令\n\n**在主机上运行:**\n- Lint (`eslint`, `rubocop`, `golangci-lint`)\n- 类型检查 (`tsc --noEmit`, `go vet`)\n- 格式化 (`prettier`, `gofmt`)\n- Git 操作\n- Playwright 和浏览器测试\n- 静态分析、代码生成\n- 安装包 (`npm install`, `pip install`)\n\n## Create and Assign\n\n当 `coast lookup` 没有返回匹配项时:\n\n1. 运行 `coast ls` 查看可用槽位。\n2. 优先使用 `coast run -w `,一步完成创建和分配。\n3. 如果还没有构建,先运行 `coast build`。\n4. 创建后,重新运行 `coast lookup` 进行确认。\n\n当你想将现有 Coast 切换到不同的 worktree 时:\n\n coast assign -w \n\n这也适用于已经分配或已 checkout 的 Coast,但在重新分配已占用槽位前,先询问用户。\n\n## Coastfile Setup\n\n如果项目需要新的或修改后的 Coastfile,请先阅读文档:\n\n coast docs --path coastfiles/README.md\n\nCoastfile 文档涵盖 compose 配置、端口、卷、密钥、共享服务、裸服务和继承。\n\n## Safety Rules\n\n- 在采取行动前运行 `coast lookup`,并在任何拓扑变更后再次运行。\n- 如果 `coast assign`、`coast unassign` 或 `coast checkout` 会扰乱现有槽位,先征求同意。\n- 除非用户明确希望重新分配现有槽位,否则优先创建新的 Coast,而不是复用已 checkout 或已分配的 Coast。\n- 在猜测之前,使用 `coast docs` 或 `coast search-docs`。\n", + "doc_ordering.txt": "# 顶层\nREADME.md\nGETTING_STARTED.md\nSKILLS_FOR_HOST_AGENTS.md\n\n# 学习 Coasts\nlearn-coasts-videos/README.md\nlearn-coasts-videos/coasts.md\nlearn-coasts-videos/ports.md\nlearn-coasts-videos/assign.md\nlearn-coasts-videos/checkout.md\nlearn-coasts-videos/volumes.md\nlearn-coasts-videos/secrets.md\nlearn-coasts-videos/getting-started.md\nlearn-coasts-videos/coast-ui.md\n\n# Harnesses\nharnesses/README.md\nharnesses/CODEX.md\nharnesses/CONDUCTOR.md\nharnesses/CLAUDE_CODE.md\nharnesses/CURSOR.md\nharnesses/T3_CODE.md\nharnesses/SHEP.md\nharnesses/MULTIPLE_HARNESSES.md\n\n# 概念与术语\nconcepts_and_terminology/README.md\nconcepts_and_terminology/COASTS.md\nconcepts_and_terminology/RUN.md\nconcepts_and_terminology/REMOVE.md\nconcepts_and_terminology/FILESYSTEM.md\nconcepts_and_terminology/DAEMON.md\nconcepts_and_terminology/CLI.md\nconcepts_and_terminology/COASTGUARD.md\nconcepts_and_terminology/PORTS.md\nconcepts_and_terminology/PRIMARY_PORT_AND_DNS.md\nconcepts_and_terminology/ASSIGN.md\nconcepts_and_terminology/CHECKOUT.md\nconcepts_and_terminology/LOOKUP.md\nconcepts_and_terminology/VOLUMES.md\nconcepts_and_terminology/SHARED_SERVICES.md\nconcepts_and_terminology/SECRETS.md\nconcepts_and_terminology/BUILDS.md\nconcepts_and_terminology/COASTFILE_TYPES.md\nconcepts_and_terminology/RUNTIMES_AND_SERVICES.md\nconcepts_and_terminology/BARE_SERVICES.md\nconcepts_and_terminology/MIXED_SERVICE_TYPES.md\nconcepts_and_terminology/LOGS.md\nconcepts_and_terminology/EXEC_AND_DOCKER.md\nconcepts_and_terminology/AGENT_SHELLS.md\nconcepts_and_terminology/MCP_SERVERS.md\nconcepts_and_terminology/PERFORMANCE_OPTIMIZATIONS.md\nconcepts_and_terminology/TROUBLESHOOTING.md\n\n# Coastfiles\ncoastfiles/README.md\ncoastfiles/PROJECT.md\ncoastfiles/WORKTREE_DIR.md\ncoastfiles/PORTS.md\ncoastfiles/SHARED_SERVICES.md\ncoastfiles/SERVICES.md\ncoastfiles/SECRETS.md\ncoastfiles/VOLUMES.md\ncoastfiles/ASSIGN.md\ncoastfiles/INHERITANCE.md\ncoastfiles/AGENT_SHELL.md\ncoastfiles/MCP.md\n\n# 配方\nrecipes/README.md\nrecipes/FULLSTACK_MONOREPO.md\n", + "installation_prompt.txt": "你正在将 Coasts 安装到这个项目中。Coast(容器化主机)是一个 CLI 工具,它使用 Docker-in-Docker 容器在一台机器上运行多个相互隔离的开发环境。每个环境都有自己的端口、卷和运行时——非常适合并行 worktree 工作流。\n\n你的任务:分析这个项目并生成一个 Coastfile(位于项目根目录、名为 \"Coastfile\" 的 TOML 文件)。\n\n=== DOCUMENTATION ===\n\nCoast 内置文档可通过 CLI 访问。在生成 Coastfile 之前,使用这些文档来理解完整的 Coastfile schema、卷策略、assign 行为以及其他配置选项。\n\n浏览文档树:\n\n coast docs\n\n这会打印完整的文档树。首先阅读 README 文件——它们提供索引,帮助你为每个主题找到合适的文档:\n\n coast docs --path README.md\n coast docs --path coastfiles/README.md\n coast docs --path concepts_and_terminology/README.md\n\n阅读特定文档:\n\n coast docs --path coastfiles/PROJECT.md\n coast docs --path coastfiles/VOLUMES.md\n\n搜索文档(语义搜索——用自然语言描述你在找什么):\n\n coast search-docs \"how do volume strategies work\"\n coast search-docs \"shared postgres across instances\"\n coast search-docs \"secret injection from environment variables\"\n\n使用文档来对该项目的 Coastfile 配置做出明智的决策。coastfiles/ 部分详细涵盖了每一条 Coastfile 指令。\n\n=== COASTFILE SCHEMA (quick reference) ===\n\n[coast] — 必需。项目元数据。\n\n name (string, required) 用于容器/卷命名的项目标识符。\n compose (string, optional) 相对于 Coastfile 的 docker-compose.yml 路径。\n runtime (string, optional) \"dind\"(默认)、\"sysbox\" 或 \"podman\"。\n root (string, optional) 项目根目录覆盖(相对或绝对)。\n worktree_dir (string or array, optional) git worktree 的目录或目录列表(默认:\".worktrees\")。接受单个字符串或字符串数组。运行时会从现有 worktrees 自动检测。\n\n[coast.setup] — 可选。自定义 DinD 容器本身。\n\n packages (array of strings) 要安装的 Alpine 包(例如 [\"nodejs\", \"npm\", \"git\"])。\n run (array of strings) 在 setup 期间要运行的任意命令。\n\n[ports] — 必需(至少一个)。逻辑名称到端口号的映射。\n 当 coast 被检出时,这些端口会被转发到宿主机。\n\n 示例:\n [ports]\n web = 3000\n api = 8080\n postgres = 5432\n\n[volumes.*] — 可选。按卷的配置。\n\n strategy \"isolated\"(默认)或 \"shared\"\n service 拥有该卷的 Compose 服务名。\n mount 在服务容器内的挂载路径。\n snapshot_source (仅 isolated) 从现有卷名称进行种子初始化。\n\n 示例:\n [volumes.postgres_data]\n strategy = \"isolated\"\n service = \"db\"\n mount = \"/var/lib/postgresql/data\"\n\n[secrets.*] — 可选。机密提取与注入。\n\n extractor \"file\"、\"env\"、\"command\" 或 \"macos-keychain\"\n inject \"env:VAR_NAME\" 或 \"file:/path/in/container\"\n ttl 可选过期时间(例如 \"1h\"、\"30m\")。\n\n 提取器特定参数:\n file: path = \"./path/to/secret\"\n env: var = \"HOST_ENV_VAR\"\n command: run = \"echo secret-value\"\n macos-keychain: item = \"keychain-item-name\"\n\n 示例:\n [secrets.db_password]\n extractor = \"env\"\n var = \"DB_PASSWORD\"\n inject = \"env:DATABASE_PASSWORD\"\n\n[inject] — 可选。非机密的宿主机文件/环境变量注入。\n\n env 要转发的宿主机环境变量名数组。\n files 要挂载的宿主机文件路径数组。\n\n 示例:\n [inject]\n env = [\"NODE_ENV\", \"DEBUG\"]\n files = [\"~/.ssh/id_ed25519\", \"~/.gitconfig\"]\n\n[shared_services.*] — 可选。宿主机 Docker 守护进程上的服务,在多个实例间共享。\n\n image Docker 镜像。\n ports 端口号数组。\n volumes 卷挂载数组。\n env 环境变量内联表。\n auto_create_db (bool) 自动创建每实例一个数据库。\n inject 将连接字符串注入到 coast 容器中。\n\n 示例:\n [shared_services.postgres]\n image = \"postgres:16-alpine\"\n ports = [5432]\n volumes = [\"postgres_data:/var/lib/postgresql/data\"]\n env = { POSTGRES_USER = \"dev\", POSTGRES_PASSWORD = \"dev\", POSTGRES_DB = \"app\" }\n auto_create_db = true\n inject = \"env:DATABASE_URL\"\n\n[assign] — 可选。控制分支切换时发生什么(coast assign)。\n\n default \"none\"、\"restart\" 或 \"rebuild\"\n [assign.services] 按服务覆盖。\n [assign.rebuild_triggers] 按服务的文件 glob,触发 rebuild。\n\n 示例:\n [assign]\n default = \"none\"\n [assign.services]\n api = \"restart\"\n worker = \"rebuild\"\n [assign.rebuild_triggers]\n worker = [\"Dockerfile\", \"package.json\"]\n\n[services.*] — 可选。裸进程服务(无需 docker-compose)。\n\n command 要运行的 Shell 命令。\n port 端口号。\n restart \"on-failure\" 或 \"always\"。\n\n 示例:\n [services.web]\n command = \"node server.js\"\n port = 3000\n restart = \"on-failure\"\n\n=== EXAMPLE: Minimal (no compose) ===\n\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[ports]\napp = 3000\n\n=== EXAMPLE: With docker-compose ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\npostgres = 5432\nredis = 6379\n\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n\n=== EXAMPLE: With secrets ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\n\n[secrets.api_key]\nextractor = \"env\"\nvar = \"API_KEY\"\ninject = \"env:API_KEY\"\n\n[secrets.ssh_key]\nextractor = \"file\"\npath = \"~/.ssh/id_ed25519\"\ninject = \"file:/run/secrets/ssh_key\"\n\n=== KEY TRADEOFFS TO DISCUSS WITH THE USER ===\n\n在生成 Coastfile 之前,向用户询问任何不明确的配置选择。主要包括以下内容:\n\n数据库与基础设施策略——对于 postgres、redis 之类的服务,有三种选择:\n - 隔离卷(默认):每个 Coast 实例在其 DinD 容器内都有自己的一份数据副本。实例之间不会相互干扰。适合需要按分支维护数据库状态的场景。\n - 共享卷:所有实例在其 DinD 容器内读写同一个卷。节省磁盘空间,但多个实例并发写入可能会导致数据损坏。\n - 共享服务:在宿主机 Docker 守护进程上运行数据库,而不是在每个 Coast 内部运行。所有实例连接到一个共享服务器。占用内存最少,支持 auto_create_db 在单个 postgres 上为每个实例创建数据库,并且数据在实例删除后仍然保留。适合大型团队或内存受限的机器。\n - 如果项目有数据库,询问用户希望采用哪种方式。解释权衡——隔离最安全,共享服务最节省内存。\n\nAssign 策略——在 worktree 之间切换 Coast 时会发生什么:\n - \"none\":不做任何事(适用于 postgres/redis 等在分支之间不变化的服务)。\n - \"restart\":重启容器(适用于解释型服务,只需要重启进程)。\n - \"rebuild\":重建 Docker 镜像并重启(适用于分支变化会影响 Dockerfile 或构建依赖的服务)。\n - 如果项目有多个服务,询问哪些在分支切换时需要 rebuild,哪些只需要 restart。\n\n=== INSTRUCTIONS ===\n\n1. 查看该项目的结构。如果有 docker-compose.yml,读取它以识别服务、端口和卷。\n2. 检测现有的 git worktree 目录。运行 `git worktree list` 检查项目是否已经设置了 git worktrees。\n - 如果存在 worktrees,检查它们的路径以确定共同的父目录(例如,如果 worktrees 位于 `../.worktrees/feat-a` 和 `../.worktrees/feat-b`,则 worktree_dir 是 `\"../.worktrees\"`)。\n - 在 Coastfile 中设置 `worktree_dir` 以匹配检测到的目录。\n - 如果不存在 worktrees,省略 `worktree_dir`(Coast 默认为 \".worktrees\")。不要使用 \".coasts\"——那会用 Coast 品牌目录污染项目。\n3. 询问用户是否在此项目中使用以下任一编码 harness:\n - **Claude Code** — worktrees 位于 `.claude/worktrees`\n - **OpenAI Codex** — worktrees 位于 `~/.codex/worktrees`\n - **Cursor** — worktrees 位于 `~/.cursor/worktrees/`(其中 `` 是 `[coast] name` 中的 coast 名称)\n - **Conductor** — worktrees 位于 `~/conductor/workspaces/`\n - **T3 Code** — worktrees 位于 `~/.t3/worktrees/`\n 对于用户选择的每个 harness,将其 worktree 目录包含到 `worktree_dir` 数组中。将这些目录与第 2 步检测到的任何目录合并。如果用户一个都没选,且第 2 步也未检测到任何 worktrees,则省略 `worktree_dir`(Coast 默认为 \".worktrees\")。\n4. 阅读相关 Coast 文档(使用 `coast docs` 和 `coast search-docs`)以理解卷策略、assign 行为以及适用于该项目技术栈的配置选项。\n5. 向用户询问任何不明确的配置选择(参见上面的权衡)。不要猜测——解释选项并让他们决定。\n6. 基于项目分析与用户输入,在项目根目录生成一个 Coastfile。\n7. 如果项目没有 docker-compose.yml,使用 [services.*] 定义裸进程,或使用 [coast.setup] 安装依赖。\n8. 运行 `coast build`。如果失败,检查错误并查阅文档(`coast search-docs \"\"`)进行排障。\n9. 运行 `coast run dev-1`。如果失败,检查错误并查阅文档。\n10. 运行 `coast ui` 打开 Coastguard 仪表盘(这是在你完成后供用户使用的)。\n", + "skills_prompt.txt": "# Coast Runtime\n\n此项目使用 Coasts——用于运行服务、测试和其他运行时命令的容器化运行时。主机与容器之间共享文件系统,因此任一侧的文件编辑都会立即对双方可见。\n\n## Discovery\n\n在会话中的第一个运行时命令之前,运行:\n\n coast lookup\n\n这会打印实例名称、端口和示例命令。对所有后续命令,都使用输出中的实例名称。\n\n## What runs where\n\n文件系统是共享的,因此只有在需要容器运行时的情况下才使用 `coast exec`(数据库、服务、集成测试)。其他所有内容都直接在主机上运行。\n\n在以下情况下使用 `coast exec`:\n- 需要运行中服务的测试(与服务或数据库集成的单元测试、集成测试、API 测试)\n- 服务重启或 compose 操作\n- 任何与数据库、缓存或其他容器服务交互的内容\n\n直接在主机上运行:\n- Lint、类型检查、格式化\n- Git 操作\n- Playwright 和浏览器测试\n- 安装主机侧依赖(npm install、pip install)\n- 文件搜索、代码生成、静态分析\n\n示例:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n coast exec --service # service shell\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\n如果 `coast lookup` 没有返回匹配项,运行 `coast ls` 查看已有内容。\n\n如果此项目已有一个未分配的 Coast 正在运行,优先将你的 worktree 分配给它,而不是创建新的:\n\n coast assign -w \n\n已被占用的 Coast 也可以使用 `coast assign` 重新分配,但要先与用户确认,因为这会扰乱当前槽位。\n\n如果当前没有运行中的 Coast,请在创建前先询问用户——Coasts 可能会占用大量内存:\n\n coast run -w \n\n项目必须先构建,才能创建实例。如果 `coast run` 因为没有现有构建而失败,先运行 `coast build`。\n\n## Coastfile setup\n\n如果项目还没有 Coastfile,或者你需要修改 Coastfile,请先阅读 Coastfile 文档:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\n在猜测 Coast 行为之前,先查看文档:\n\n coast docs # 列出所有文档页面\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # 语义搜索\n\n## Rules\n\n- 在会话中的第一个运行时命令之前,始终运行 `coast lookup`。\n- 仅对需要容器运行时的内容使用 `coast exec`。\n- 当你需要在应用/服务容器内运行时,使用 `coast exec --service `。\n- 直接在主机上运行 lint、类型检查、格式化和 git。\n- 在猜测 Coast 行为之前,使用 `coast docs` 或 `coast search-docs`。\n- 当项目要求使用 Coast 时,不要直接在主机上运行服务。\n\n---\nname: coasts\ndescription: Inspect and control Coast instances for the current checkout. Use\n when the user says \"/coasts\", asks to assign or reassign a Coast, wants to\n run commands or read logs in the matching Coast, wants to create a new Coast,\n or explicitly asks to open Coast UI.\n---\n\n# Coasts\n\n直接使用 Coast CLI。不要添加包装器。\n\n## Orient Yourself\n\n先浏览 CLI 和文档:\n\n coast # 查看所有可用命令\n coast docs # 列出所有文档页面\n coast search-docs \"your question\" # 语义搜索\n\n如果对 Coast 的行为有任何不清楚之处,请先阅读文档,不要猜测:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\n将请求路由到以下模式之一:\n\n1. **Use Coast** —— 运行 `coast lookup`,然后对匹配的实例使用 `coast exec`、`coast ps` 或 `coast logs`。\n2. **Create or Assign** —— 运行 `coast ls`,然后使用 `coast run` 创建新的 Coast,或使用 `coast assign` 重新指向现有 Coast。\n3. **Open UI** —— 运行 `coast ui`。\n\n## What Runs Where\n\n主机与 Coast 共享文件系统。仅在需要容器内运行中的服务时才使用 `coast exec`。\n\n**在以下情况下使用 `coast exec`:**\n- 集成测试、API 测试,以及任何需要数据库或服务的内容\n- 服务重启、compose 操作\n- 与仅存在于容器中的进程交互的命令\n\n**在主机上运行:**\n- Lint (`eslint`, `rubocop`, `golangci-lint`)\n- 类型检查 (`tsc --noEmit`, `go vet`)\n- 格式化 (`prettier`, `gofmt`)\n- Git 操作\n- Playwright 和浏览器测试\n- 静态分析、代码生成\n- 安装包 (`npm install`, `pip install`)\n\n## Create and Assign\n\n当 `coast lookup` 没有返回匹配项时:\n\n1. 运行 `coast ls` 查看可用槽位。\n2. 优先使用 `coast run -w `,一步完成创建和分配。\n3. 如果还没有构建,先运行 `coast build`。\n4. 创建后,重新运行 `coast lookup` 进行确认。\n\n当你想将现有 Coast 切换到不同的 worktree 时:\n\n coast assign -w \n\n这也适用于已经分配或已 checkout 的 Coast,但在重新分配已占用槽位前,先询问用户。\n\n## Coastfile Setup\n\n如果项目需要新的或修改后的 Coastfile,请先阅读文档:\n\n coast docs --path coastfiles/README.md\n\nCoastfile 文档涵盖 compose 配置、端口、卷、密钥、共享服务、裸服务和继承。\n\n## Safety Rules\n\n- 在采取行动前运行 `coast lookup`,并在任何拓扑变更后再次运行。\n- 如果 `coast assign`、`coast unassign` 或 `coast checkout` 会扰乱现有槽位,先征求同意。\n- 除非用户明确希望重新分配现有槽位,否则优先创建新的 Coast,而不是复用已 checkout 或已分配的 Coast。\n- 在猜测之前,使用 `coast docs` 或 `coast search-docs`。\n", "coastfiles/README.md": "# Coastfile\n\nCoastfile 是一个 TOML 配置文件,位于你的项目根目录。它会告诉 Coast 构建和运行该项目的隔离开发环境所需了解的一切——运行哪些服务、转发哪些端口、如何处理数据,以及如何管理密钥。\n\n每个 Coast 项目都至少需要一个 Coastfile。该文件的名称始终为 `Coastfile`(大写 C,无扩展名)。如果你需要针对不同工作流的变体,可以创建带类型的 Coastfile,例如 `Coastfile.light` 或 `Coastfile.snap`,它们会[继承基础配置](INHERITANCE.md)。\n\n若要更深入地理解 Coastfile 与 Coast 其他部分之间的关系,请参阅 [Coasts](../concepts_and_terminology/COASTS.md) 和 [Builds](../concepts_and_terminology/BUILDS.md)。\n\n## 快速开始\n\n最小可用的 Coastfile:\n\n```toml\n[coast]\nname = \"my-app\"\n```\n\n这会为你提供一个可以通过 `coast exec` 进入的 DinD 容器。大多数项目通常会需要一个 `compose` 引用或[裸服务](SERVICES.md):\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\napi = 8080\n```\n\n或者不使用 compose,而是使用裸服务:\n\n```toml\n[coast]\nname = \"my-app\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\nrestart = \"on-failure\"\n\n[ports]\nweb = 3000\n```\n\n运行 `coast build`,然后运行 `coast run dev-1`,你就拥有了一个隔离环境。\n\n## Coastfile 示例\n\n### 简单的裸服务项目\n\n一个没有 compose 文件的 Next.js 应用。Coast 会安装 Node,运行 `npm install`,并直接启动开发服务器。\n\n```toml\n[coast]\nname = \"my-crm\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --turbopack --port 3002 --hostname 0.0.0.0\"\nport = 3002\nrestart = \"on-failure\"\n\n[ports]\nweb = 3002\n```\n\n### 全栈 compose 项目\n\n一个多服务项目,包含共享数据库、密钥、卷策略以及自定义设置。\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./infra/docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"python3\", \"curl\", \"git\", \"bash\", \"ca-certificates\", \"wget\"]\nrun = [\n \"ARCH=$(uname -m | sed 's/aarch64/arm64/' | sed 's/x86_64/amd64/') && wget -qO /tmp/go.tar.gz https://go.dev/dl/go1.24.1.linux-${ARCH}.tar.gz && tar -C /usr/local -xzf /tmp/go.tar.gz && rm /tmp/go.tar.gz\",\n \"GOBIN=/usr/local/bin go install github.com/air-verse/air@v1.61.7\",\n]\n\n[ports]\nweb = 3000\nbackend = 8080\npostgres = 5432\nredis = 6379\n\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\" }\n\n[shared_services.redis]\nimage = \"redis:7\"\nports = [6379]\n\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n\n[secrets.db_password]\nextractor = \"env\"\nvar = \"DB_PASSWORD\"\ninject = \"env:DB_PASSWORD\"\n\n[omit]\nservices = [\"monitoring\", \"admin-panel\", \"nginx-proxy\"]\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### 轻量级测试变体(继承)\n\n扩展基础 Coastfile,但将其精简为仅保留运行后端测试所需的内容。没有端口,没有共享服务,数据库隔离。\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n\n[unset]\nports = [\"web\", \"backend\", \"postgres\", \"redis\"]\nshared_services = [\"postgres\", \"redis\"]\n\n[omit]\nservices = [\"redis\", \"backend\", \"web\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend-test = \"rebuild\"\n```\n\n### 快照播种变体\n\n每个 coast 实例启动时都会复制主机上现有数据库卷的内容,然后各自独立分化。\n\n```toml\n[coast]\nextends = \"Coastfile\"\n\n[unset]\nshared_services = [\"postgres\", \"redis\", \"mongodb\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_mongodb_data\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n\n## 约定\n\n- 文件必须命名为 `Coastfile`(大写 C,无扩展名),并位于项目根目录。\n- 带类型的变体使用 `Coastfile.{type}` 模式——例如 `Coastfile.light`、`Coastfile.snap`。参见 [继承与类型](INHERITANCE.md)。\n- 保留名称 `Coastfile.default` 不允许使用。\n- 全文使用 TOML 语法。所有节标题都使用 `[brackets]`,命名条目使用 `[section.name]`(不是 array-of-tables)。\n- 你不能在同一个 Coastfile 中同时使用 `compose` 和 `[services]`——二选一。\n- 相对路径(用于 `compose`、`root` 等)会相对于 Coastfile 的父目录进行解析。\n\n## 参考\n\n| 页面 | 节 | 覆盖内容 |\n|------|----------|----------------|\n| [项目与设置](PROJECT.md) | `[coast]`, `[coast.setup]` | 名称、compose 路径、运行时、worktree 目录、容器设置 |\n| [Worktree 目录](WORKTREE_DIR.md) | `worktree_dir`, `default_worktree_dir` | 本地和外部 worktree 目录、波浪线路径、Codex/Claude 集成 |\n| [端口](PORTS.md) | `[ports]`, `[egress]` | 端口转发、出口声明、主端口 |\n| [卷](VOLUMES.md) | `[volumes.*]` | 隔离、共享和快照播种的卷策略 |\n| [共享服务](SHARED_SERVICES.md) | `[shared_services.*]` | 主机级数据库和基础设施服务 |\n| [密钥](SECRETS.md) | `[secrets.*]`, `[inject]` | 密钥提取、注入,以及主机环境/文件转发 |\n| [裸服务](SERVICES.md) | `[services.*]` | 无需 Docker Compose 直接运行进程 |\n| [代理 Shell](AGENT_SHELL.md) | `[agent_shell]` | 容器化代理 TUI 运行时 |\n| [MCP 服务器](MCP.md) | `[mcp.*]`, `[mcp_clients.*]` | 内部和主机代理的 MCP 服务器、客户端连接器 |\n| [Assign](ASSIGN.md) | `[assign]` | 按服务划分的分支切换行为 |\n| [继承与类型](INHERITANCE.md) | `extends`, `includes`, `[unset]`, `[omit]` | 带类型的 Coastfile、组合与覆盖 |\n", "coastfiles/AGENT_SHELL.md": "# Agent Shell\n\n> **在大多数工作流中,你不需要将你的编码代理容器化。** 因为 Coast 与你的宿主机共享[文件系统](../concepts_and_terminology/FILESYSTEM.md),最简单的方法是在宿主机上运行代理,并对集成测试等运行时开销较大的任务使用 [`coast exec`](../concepts_and_terminology/EXEC_AND_DOCKER.md)。Agent shell 适用于你特别希望代理在容器内运行的场景——例如,为其提供对内部 Docker 守护进程的直接访问,或完全隔离其环境。\n\n`[agent_shell]` 部分用于配置一个代理 TUI——例如 Claude Code 或 Codex——在 Coast 容器内运行。配置存在时,Coast 会在实例启动时自动生成一个持久化 PTY 会话来运行所配置的命令。\n\n关于 agent shell 如何工作的全貌——活动代理模型、发送输入、生命周期与恢复——请参阅 [Agent Shells](../concepts_and_terminology/AGENT_SHELLS.md)。\n\n## Configuration\n\n该部分只有一个必填字段:`command`。\n\n```toml\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\n### `command` (required)\n\n在代理 PTY 中运行的 shell 命令。这通常是你通过 `[coast.setup]` 安装的编码代理 CLI。\n\n该命令在 DinD 容器内的 `/workspace`(项目根目录)中运行。它不是 compose 服务——它与 compose 堆栈或裸服务并行运行,而不是在它们内部运行。\n\n## Lifecycle\n\n- agent shell 会在 `coast run` 时自动生成。\n- 在 [Coastguard](../concepts_and_terminology/COASTGUARD.md) 中,它会显示为一个无法关闭的持久化 “Agent” 标签页。\n- 如果代理进程退出,Coast 可以将其重新生成。\n- 你可以通过 `coast agent-shell input` 向正在运行的 agent shell 发送输入。\n\n## Examples\n\n### Claude Code\n\n在 `[coast.setup]` 中安装 Claude Code,通过 [secrets](SECRETS.md) 配置凭据,然后设置 agent shell:\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"git\", \"bash\"]\nrun = [\n \"npm install -g @anthropic-ai/claude-code\",\n \"mkdir -p /root/.claude\",\n]\n\n[secrets.claude_credentials]\nextractor = \"keychain\"\nservice = \"Claude Code-credentials\"\ninject = \"file:/root/.claude/.credentials.json\"\n\n[agent_shell]\ncommand = \"cd /workspace; exec claude --dangerously-skip-permissions --effort high\"\n```\n\n### Simple agent shell\n\n一个用于测试该功能是否可用的最小 agent shell:\n\n```toml\n[coast]\nname = \"test-agent\"\n\n[coast.setup]\npackages = [\"bash\"]\n\n[agent_shell]\ncommand = \"exec sh -c 'while true; do echo agent-heartbeat; sleep 5; done'\"\n```\n", "coastfiles/ASSIGN.md": "# Assign\n\n`[assign]` 部分用于控制在你使用 `coast assign` 切换分支时,Coast 实例内的服务会发生什么。每个服务都可以根据其需求配置不同的策略:是否需要完整重建、重启、热重载,或者什么都不做。\n\n关于 `coast assign` 和 `coast unassign` 在运行时如何工作,请参阅 [Assign](../concepts_and_terminology/ASSIGN.md)。\n\n## `[assign]`\n\n### `default`\n\n在分支切换时应用于所有服务的默认动作。如果整个 `[assign]` 部分被省略,则默认值为 `\"restart\"`。\n\n- **`\"none\"`** — 什么都不做。服务保持按原样运行。适用于不依赖代码的数据库和缓存。\n- **`\"hot\"`** — 代码已通过 [filesystem](../concepts_and_terminology/FILESYSTEM.md) 进行实时挂载,因此服务会自动获取变更(例如通过文件监听器或热重载)。无需重启容器。\n- **`\"restart\"`** — 重启服务容器。用于服务在启动时读取代码,但不需要完整镜像重建的场景。\n- **`\"rebuild\"`** — 重建服务的 Docker 镜像并重启。当代码通过 Dockerfile 中的 `COPY` 或 `ADD` 被打包进镜像时必需。\n\n```toml\n[assign]\ndefault = \"none\"\n```\n\n### `[assign.services]`\n\n按服务覆盖。每个键是一个 compose 服务名,值为上述四种动作之一。\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\n这让你可以让数据库和缓存保持不变(通过默认值 `\"none\"`),同时只对依赖发生变更的代码的服务进行重建或重启。\n\n### `[assign.rebuild_triggers]`\n\n用于为特定服务强制触发重建的文件模式,即使它们的默认动作是更轻量的操作。每个键是一个服务名,值是文件路径或模式的列表。\n\n```toml\n[assign]\ndefault = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\", \"package-lock.json\"]\n```\n\n### `exclude_paths`\n\n在执行 `coast assign` 期间,从 worktree 同步中排除的路径列表。适用于大型 monorepo,其中某些目录与 Coast 中运行的服务无关,否则会拖慢 assign 操作。\n\n```toml\n[assign]\ndefault = \"none\"\nexclude_paths = [\"apps/ide\", \"apps/extension\", \"apps/ide-extension\"]\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n## Examples\n\n### 重建 app,其余保持不变\n\n当你的 app 服务将代码打包进其 Docker 镜像,但数据库不受代码变更影响时:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\n### 前端和后端热重载\n\n当两个服务都使用文件监听器(例如 Next.js dev server、Go air、nodemon)且代码为实时挂载时:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### 带触发器的按服务重建\n\nAPI 服务通常只重启,但如果 `Dockerfile` 或 `package.json` 发生变更,则会重建:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napi = \"restart\"\nworker = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\"]\n```\n\n### 全部服务完全重建\n\n当所有服务都将代码打包进其镜像时:\n\n```toml\n[assign]\ndefault = \"rebuild\"\n```\n", @@ -778,19 +783,19 @@ "coastfiles/SERVICES.md": "# 裸服务\n\n> **注意:** 裸服务以普通进程的形式直接在 Coast 容器内运行——它们并未容器化。如果你的服务已经 Docker 化,请改用 `compose`。裸服务最适合简单场景:你希望跳过编写 Dockerfile 和 docker-compose.yml 的开销。\n\n`[services.*]` 部分定义了 Coast 在 DinD 容器内直接运行的进程,而不使用 Docker Compose。这是使用 `compose` 文件的替代方案——你不能在同一个 Coastfile 中同时使用两者。\n\n裸服务由 Coast 进行监管,包含日志捕获以及可选的重启策略。关于裸服务如何工作、其限制,以及何时迁移到 compose 的更深入背景,请参见 [Bare Services](../concepts_and_terminology/BARE_SERVICES.md)。\n\n## 定义服务\n\n每个服务都是 `[services]` 下一个具名的 TOML 部分。`command` 字段是必需的。\n\n```toml\n[services.web]\ncommand = \"node server.js\"\nport = 3000\n```\n\n### `command`(必需)\n\n要运行的 shell 命令。不能为空或仅包含空白字符。\n\n```toml\n[services.web]\ncommand = \"npx next dev --turbopack --port 3000 --hostname 0.0.0.0\"\n```\n\n### `port`\n\n服务监听的端口。用于健康检查以及端口转发集成。如果指定,必须为非零值。\n\n```toml\n[services.web]\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\n```\n\n### `restart`\n\n进程退出时的重启策略。默认值为 `\"no\"`。\n\n- `\"no\"` — 不重启\n- `\"on-failure\"` — 仅当进程以非零退出码退出时重启\n- `\"always\"` — 总是重启\n\n```toml\n[services.web]\ncommand = \"node server.js\"\nport = 3000\nrestart = \"on-failure\"\n```\n\n### `install`\n\n在启动服务之前要运行的命令(例如安装依赖)。可以是单个字符串或字符串数组。\n\n```toml\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\n```\n\n```toml\n[services.web]\ninstall = [\"npm install\", \"npm run build\"]\ncommand = \"npm start\"\nport = 3000\n```\n\n## 与 compose 的互斥\n\n一个 Coastfile 不能同时定义 `compose` 和 `[services]`。如果你在 `[coast]` 中有一个 `compose` 字段,那么添加任何 `[services.*]` 部分都会报错。每个 Coastfile 请选择一种方式。\n\n如果你需要一些服务通过 compose 容器化、另一些以裸服务运行,请对所有服务都使用 compose——如何从裸服务迁移到 compose,请参见 [Bare Services 中的迁移指南](../concepts_and_terminology/BARE_SERVICES.md)。\n\n## 示例\n\n### 单服务 Next.js 应用\n\n```toml\n[coast]\nname = \"my-frontend\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --turbopack --port 3002 --hostname 0.0.0.0\"\nport = 3002\nrestart = \"on-failure\"\n\n[ports]\nweb = 3002\n```\n\n### 带后台 worker 的 Web 服务器\n\n```toml\n[coast]\nname = \"my-app\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"node server.js\"\nport = 3000\nrestart = \"on-failure\"\n\n[services.worker]\ncommand = \"node worker.js\"\nrestart = \"always\"\n\n[ports]\nweb = 3000\n```\n\n### 带多步骤安装的 Python 服务\n\n```toml\n[coast]\nname = \"ml-service\"\n\n[coast.setup]\npackages = [\"python3\", \"py3-pip\"]\n\n[services.api]\ninstall = [\"pip install -r requirements.txt\", \"python manage.py migrate\"]\ncommand = \"python manage.py runserver 0.0.0.0:8000\"\nport = 8000\nrestart = \"on-failure\"\n\n[ports]\napi = 8000\n```\n", "coastfiles/SHARED_SERVICES.md": "# 共享服务\n\n`[shared_services.*]` 部分定义基础设施服务——数据库、缓存、消息代理——这些服务运行在宿主机 Docker 守护进程上,而不是在各个 Coast 容器内部运行。多个 Coast 实例通过桥接网络连接到同一个共享服务。\n\n关于共享服务在运行时如何工作、生命周期管理以及故障排查,请参阅 [共享服务](../concepts_and_terminology/SHARED_SERVICES.md)。\n\n## 定义一个共享服务\n\n每个共享服务都是 `[shared_services]` 下一个具名的 TOML section。`image` 字段是必需的;其他所有字段都是可选的。\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\n```\n\n### `image`(必需)\n\n要在宿主机守护进程上运行的 Docker 镜像。\n\n### `ports`\n\n服务暴露的端口列表。Coast 接受裸容器端口,或 Docker Compose 风格的 `\"HOST:CONTAINER\"` 映射。\n\n```toml\n[shared_services.redis]\nimage = \"redis:7-alpine\"\nports = [6379]\n```\n\n```toml\n[shared_services.postgis]\nimage = \"ghcr.io/baosystems/postgis:12-3.3\"\nports = [\"5433:5432\"]\n```\n\n- 像 `6379` 这样的裸整数是 `\"6379:6379\"`` 的简写。\n- 像 `\"5433:5432\"` 这样的映射字符串会将共享服务发布到宿主机端口 `5433`,同时使其在 Coast 内部仍可通过 `service-name:5432` 访问。\n- 宿主机端口和容器端口都必须为非零。\n\n### `volumes`\n\n用于持久化数据的 Docker volume 绑定字符串。这些是宿主机级别的 Docker volumes,而不是由 Coast 管理的 volumes。\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\n```\n\n### `env`\n\n传递给服务容器的环境变量。\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\", POSTGRES_DB = \"mydb\" }\n```\n\n### `auto_create_db`\n\n当为 `true` 时,Coast 会在共享服务内为每个 Coast 实例自动创建一个按实例划分的数据库。默认为 `false`。\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\nauto_create_db = true\n```\n\n### `inject`\n\n将共享服务的连接信息以环境变量或文件的形式注入到 Coast 实例中。使用与 [secrets](SECRETS.md) 相同的 `env:NAME` 或 `file:/path` 格式。\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\ninject = \"env:DATABASE_URL\"\n```\n\n## 生命周期\n\n当第一个引用某个共享服务的 Coast 实例运行时,共享服务会自动启动。它们会在 `coast stop` 和 `coast rm` 之后继续运行——删除实例不会影响共享服务的数据。只有 `coast shared rm` 才会停止并移除共享服务。\n\n由 `auto_create_db` 创建的按实例数据库也会在实例删除后保留。使用 `coast shared-services rm` 来移除该服务并彻底删除其数据。\n\n## 何时使用共享服务 vs volumes\n\n当多个 Coast 实例需要与同一个数据库服务器通信时(例如共享的 Postgres,每个实例拥有自己的数据库),请使用共享服务。当你希望控制 compose 内部服务的数据如何被共享或隔离时,请使用 [volume strategies](VOLUMES.md)。\n\n## 示例\n\n### Postgres、Redis 和 MongoDB\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\", POSTGRES_MULTIPLE_DATABASES = \"dev_db,test_db\" }\n\n[shared_services.redis]\nimage = \"redis:7\"\nports = [6379]\nvolumes = [\"infra_redis_data:/data\"]\n\n[shared_services.mongodb]\nimage = \"mongo:latest\"\nports = [27017]\nvolumes = [\"infra_mongodb_data:/data/db\"]\nenv = { MONGO_INITDB_ROOT_USERNAME = \"myapp\", MONGO_INITDB_ROOT_PASSWORD = \"myapp_pass\" }\n```\n\n### 最小化共享 Postgres\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16-alpine\"\nports = [5432]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\", POSTGRES_DB = \"coast_demo\" }\n```\n\n### 宿主机/容器端口映射的共享 Postgres\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16-alpine\"\nports = [\"5433:5432\"]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\", POSTGRES_DB = \"coast_demo\" }\n```\n\n### 带有自动创建数据库的共享服务\n\n```toml\n[shared_services.db]\nimage = \"postgres:16-alpine\"\nports = [5432]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\" }\nauto_create_db = true\n```\n", "coastfiles/VOLUMES.md": "# 卷(Volumes)\n\n`[volumes.*]` 部分控制命名的 Docker 卷在各个 Coast 实例之间如何处理。每个卷都使用一种策略进行配置,该策略决定实例之间是共享数据,还是各自拥有独立的副本。\n\n关于 Coast 中数据隔离的更大图景——包括作为替代方案的共享服务——请参见 [Volumes](../concepts_and_terminology/VOLUMES.md)。\n\n## 定义一个卷\n\n每个卷都是 `[volumes]` 下的一个具名 TOML section。需要三个字段:\n\n- **`strategy`** — `\"isolated\"` 或 `\"shared\"`\n- **`service`** — 使用该卷的 compose 服务名称\n- **`mount`** — 该卷在容器中的挂载路径\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## 策略\n\n### `isolated`\n\n每个 Coast 实例都会获得自己独立的卷。数据不会在实例之间共享。卷会在 `coast run` 时创建,并在 `coast rm` 时删除。\n\n```toml\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n```\n\n这通常是大多数数据库卷的正确选择——每个实例都有一块干净的起点,并且可以自由修改数据而不影响其他实例。\n\n### `shared`\n\n所有 Coast 实例使用同一个 Docker 卷。任一实例写入的数据对所有其他实例都可见。\n\n```toml\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n```\n\n共享卷永远不会被 `coast rm` 删除。它们会一直保留,直到你手动移除。\n\n如果你在一个挂载到类似数据库服务的卷上使用 `shared`,Coast 会在构建时打印警告。在多个并发实例之间共享单个数据库卷可能导致损坏。如果你需要共享数据库,请改用 [shared services](SHARED_SERVICES.md)。\n\n共享卷的良好用途:依赖缓存(Go modules、npm cache、pip cache)、构建产物缓存,以及其他并发写入安全或不太可能发生的 data。\n\n## 快照播种(Snapshot seeding)\n\n在实例创建时,隔离卷可以使用 `snapshot_source` 从现有 Docker 卷进行播种。源卷的数据会被复制到新的隔离卷中,随后它们会各自独立地分叉演进。\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n`snapshot_source` 只在 `strategy = \"isolated\"` 时有效。把它设置在共享卷上会报错。\n\n当你希望每个 Coast 实例都以从主机开发数据库复制而来的真实数据集启动,同时又希望实例能自由修改这些数据且不影响源数据或彼此时,这会很有用。\n\n## 示例\n\n### 隔离数据库,共享依赖缓存\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n```\n\n### 通过快照播种的全栈\n\n每个实例都从你主机现有数据库卷的副本开始,然后各自独立地分叉演进。\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_mongodb_data\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n\n### 为每个实例提供干净数据库的测试运行器\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"test-redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n", - "coastfiles/WORKTREE_DIR.md": "# Worktree 目录\n\n`[coast]` 中的 `worktree_dir` 字段控制 git worktree 的存放位置。Coast 使用 git worktree 为每个实例提供代码库在不同分支上的独立副本,而无需复制整个仓库。\n\n## 语法\n\n`worktree_dir` 接受单个字符串或字符串数组:\n\n```toml\n# Single directory (default)\nworktree_dir = \".worktrees\"\n\n# Multiple directories\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\n省略时,默认值为 `\".worktrees\"`。\n\n## 路径类型\n\n### 相对路径\n\n不以 `~/` 或 `/` 开头的路径会相对于项目根目录解析。这是最常见的情况,不需要特殊处理——它们位于项目目录内,并通过标准的 `/host-project` 绑定挂载自动在 Coast 容器内可用。\n\n```toml\nworktree_dir = \".worktrees\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### 波浪线路径(外部)\n\n以 `~/` 开头的路径会展开为用户的主目录,并被视为**外部** worktree 目录。Coast 会添加单独的绑定挂载,以便容器可以访问它们。\n\n```toml\nworktree_dir = [\"~/.codex/worktrees\", \".worktrees\"]\n```\n\n这就是你与那些会在项目根目录之外创建 worktree 的工具集成的方式,例如 OpenAI Codex(它总是在 `$CODEX_HOME/worktrees` 创建 worktree)。\n\n### 绝对路径(外部)\n\n以 `/` 开头的路径也会被视为外部路径,并获得其自己的绑定挂载。\n\n```toml\nworktree_dir = [\"/shared/worktrees\", \".worktrees\"]\n```\n\n## 外部目录的工作方式\n\n当 Coast 遇到外部 worktree 目录(波浪线路径或绝对路径)时,会发生三件事:\n\n1. **容器绑定挂载** —— 在容器创建时(`coast run`),解析后的主机路径会被绑定挂载到容器中的 `/host-external-wt/{index}`,其中 `{index}` 是该路径在 `worktree_dir` 数组中的位置。这使外部文件在容器内可访问。\n\n2. **项目过滤** —— 外部目录可能包含多个项目的 worktree。Coast 使用 `git worktree list --porcelain`(其作用域天然限定在当前仓库)来仅发现属于此项目的 worktree。git watcher 还会通过读取每个 worktree 的 `.git` 文件并检查其 `gitdir:` 指针是否解析回当前仓库来验证归属关系。\n\n3. **工作区重新挂载** —— 当你将 `coast assign` 到外部 worktree 时,Coast 会将 `/workspace` 从外部绑定挂载路径重新挂载,而不是使用通常的 `/host-project/{dir}/{name}`。\n\n## 外部 worktree 的命名\n\n已检出分支的外部 worktree 会显示为其分支名,与本地 worktree 相同。\n\n处于 **detached HEAD** 的外部 worktree(Codex 中很常见)会使用它们在外部目录中的相对路径显示。例如,位于 `~/.codex/worktrees/a0db/coastguard-platform` 的 Codex worktree 会在 UI 和 CLI 中显示为 `a0db/coastguard-platform`。\n\n## `default_worktree_dir`\n\n控制当 Coast 创建**新的** worktree 时使用哪个目录(例如,当你分配一个尚不存在对应 worktree 的分支时)。默认使用 `worktree_dir` 中的第一个条目。\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\ndefault_worktree_dir = \".worktrees\"\n```\n\n外部目录永远不会用于创建新的 worktree——Coast 总是在本地(相对)目录中创建 worktree。只有当你想覆盖默认值(第一个条目)时,才需要 `default_worktree_dir` 字段。\n\n## 示例\n\n### Codex 集成\n\nOpenAI Codex 会在 `~/.codex/worktrees/{hash}/{project-name}` 创建 worktree。要让这些 worktree 在 Coast 中可见并可分配:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\n添加后,Codex 的 worktree 会出现在 checkout 模态框和 `coast ls` 输出中。你可以将一个 Coast 实例分配到某个 Codex worktree,以便在完整开发环境中运行其代码。\n\n注意:添加外部目录后,必须重新创建容器(`coast run`)绑定挂载才会生效。仅重启现有实例是不够的。\n\n### Claude Code 集成\n\nClaude Code 会在项目内部的 `.claude/worktrees/` 创建 worktree。由于这是一个相对路径(位于项目根目录内),它与任何其他本地 worktree 目录一样工作——不需要外部挂载:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### 三者一起使用\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\n## 实时读取 Coastfile\n\n你在 Coastfile 中对 `worktree_dir` 的更改会立即对 worktree **列表显示** 生效(API 和 git watcher 读取的是磁盘上的实时 Coastfile,而不仅仅是缓存的构建产物)。但是,外部**绑定挂载**仅在容器创建时建立,因此如果新增了外部目录,你需要重新创建实例,才能使其可被挂载。\n", + "coastfiles/WORKTREE_DIR.md": "# Worktree 目录\n\n`[coast]` 中的 `worktree_dir` 字段控制 git worktree 的存放位置。Coast 使用 git worktree 为每个实例提供代码库在不同分支上的独立副本,而无需复制整个仓库。\n\n## 语法\n\n`worktree_dir` 接受单个字符串或字符串数组:\n\n```toml\n# Single directory (default)\nworktree_dir = \".worktrees\"\n\n# Multiple directories\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\n省略时,默认值为 `\".worktrees\"`。\n\n## 路径类型\n\n### 相对路径\n\n不以 `~/` 或 `/` 开头的路径会相对于项目根目录解析。这是最常见的情况,不需要特殊处理——它们位于项目目录内,并通过标准的 `/host-project` 绑定挂载自动在 Coast 容器内可用。\n\n```toml\nworktree_dir = \".worktrees\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### 波浪线路径(外部)\n\n以 `~/` 开头的路径会展开为用户的主目录,并被视为**外部** worktree 目录。Coast 会添加单独的绑定挂载,以便容器可以访问它们。\n\n```toml\nworktree_dir = [\"~/.codex/worktrees\", \".worktrees\"]\n```\n\n这就是你与那些会在项目根目录之外创建 worktree 的工具集成的方式,例如 OpenAI Codex(它总是在 `$CODEX_HOME/worktrees` 创建 worktree)。\n\n### 绝对路径(外部)\n\n以 `/` 开头的路径也会被视为外部路径,并获得其自己的绑定挂载。\n\n```toml\nworktree_dir = [\"/shared/worktrees\", \".worktrees\"]\n```\n\n### Glob 模式(外部)\n\n外部路径可以包含 glob 元字符(`*`、`?`、`[...]`)。Coast 会在运行时根据主机文件系统展开它们,并为每个匹配的目录创建一个绑定挂载。\n\n```toml\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n当某个工具把 worktree 生成在一个会因项目而变化的路径组件下(例如哈希值)时,这会非常有用。`*` 可匹配任意单个目录名,因此 `~/.shep/repos/*/wt` 会匹配 `~/.shep/repos/a21f0cda9ab9d456/wt` 以及任何其他包含 `wt` 子目录的哈希目录。\n\n支持的 glob 语法:\n\n- `*` — 匹配单个路径组件内的任意字符序列\n- `?` — 匹配任意单个字符\n- `[abc]` — 匹配集合中的任意字符\n- `[!abc]` — 匹配不在集合中的任意字符\n\n凡是解析 worktree 目录的地方都会进行 glob 展开:容器创建、assign、start、lookup,以及 git watcher。匹配结果会被排序以确保顺序确定。如果某个 glob 没有匹配到任何目录,则会被静默跳过。\n\n与其他外部路径一样,添加 glob 模式后,必须重新创建容器(`coast run`)绑定挂载才会生效。\n\n## 外部目录的工作方式\n\n当 Coast 遇到外部 worktree 目录(波浪线路径或绝对路径)时,会发生三件事:\n\n1. **容器绑定挂载** —— 在容器创建时(`coast run`),解析后的主机路径会被绑定挂载到容器中的 `/host-external-wt/{index}`,其中 `{index}` 是该路径在 `worktree_dir` 数组中的位置。这使外部文件在容器内可访问。\n\n2. **项目过滤** —— 外部目录可能包含多个项目的 worktree。Coast 使用 `git worktree list --porcelain`(其作用域天然限定在当前仓库)来仅发现属于此项目的 worktree。git watcher 还会通过读取每个 worktree 的 `.git` 文件并检查其 `gitdir:` 指针是否解析回当前仓库来验证归属关系。\n\n3. **工作区重新挂载** —— 当你将 `coast assign` 到外部 worktree 时,Coast 会将 `/workspace` 从外部绑定挂载路径重新挂载,而不是使用通常的 `/host-project/{dir}/{name}`。\n\n## 外部 worktree 的命名\n\n已检出分支的外部 worktree 会显示为其分支名,与本地 worktree 相同。\n\n处于 **detached HEAD** 的外部 worktree(Codex 中很常见)会使用它们在外部目录中的相对路径显示。例如,位于 `~/.codex/worktrees/a0db/coastguard-platform` 的 Codex worktree 会在 UI 和 CLI 中显示为 `a0db/coastguard-platform`。\n\n## `default_worktree_dir`\n\n控制当 Coast 创建**新的** worktree 时使用哪个目录(例如,当你分配一个尚不存在对应 worktree 的分支时)。默认使用 `worktree_dir` 中的第一个条目。\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\ndefault_worktree_dir = \".worktrees\"\n```\n\n外部目录永远不会用于创建新的 worktree——Coast 总是在本地(相对)目录中创建 worktree。只有当你想覆盖默认值(第一个条目)时,才需要 `default_worktree_dir` 字段。\n\n## 示例\n\n### Codex 集成\n\nOpenAI Codex 会在 `~/.codex/worktrees/{hash}/{project-name}` 创建 worktree。要让这些 worktree 在 Coast 中可见并可分配:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\n添加后,Codex 的 worktree 会出现在 checkout 模态框和 `coast ls` 输出中。你可以将一个 Coast 实例分配到某个 Codex worktree,以便在完整开发环境中运行其代码。\n\n注意:添加外部目录后,必须重新创建容器(`coast run`)绑定挂载才会生效。仅重启现有实例是不够的。\n\n### Claude Code 集成\n\nClaude Code 会在项目内部的 `.claude/worktrees/` 创建 worktree。由于这是一个相对路径(位于项目根目录内),它与任何其他本地 worktree 目录一样工作——不需要外部挂载:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Shep 集成\n\nShep 会在 `~/.shep/repos/{hash}/wt/{branch-slug}` 创建 worktree,其中哈希值对每个仓库都不同。使用 glob 模式来匹配该哈希目录:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n### 所有 harness 一起使用\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n## 实时读取 Coastfile\n\n你在 Coastfile 中对 `worktree_dir` 的更改会立即对 worktree **列表显示** 生效(API 和 git watcher 读取的是磁盘上的实时 Coastfile,而不仅仅是缓存的构建产物)。但是,外部**绑定挂载**仅在容器创建时建立,因此如果新增了外部目录,你需要重新创建实例,才能使其可被挂载。\n", "concepts_and_terminology/README.md": "# 概念与术语\n\n本节涵盖贯穿 Coasts 的核心概念和词汇。如果你是 Coasts 新手,在深入配置或高级用法之前请先从这里开始。\n\n- [Coasts](COASTS.md) — 你项目的自包含运行时,每个都有自己的端口、卷以及 worktree 分配。\n- [Run](RUN.md) — 基于最新构建创建一个新的 Coast 实例,并可选择分配一个 worktree。\n- [Remove](REMOVE.md) — 拆除一个 Coast 实例及其隔离的运行时状态,适用于你需要干净地重新创建,或想要关闭 Coasts 的情况。\n- [Filesystem](FILESYSTEM.md) — 主机与 Coast 之间的共享挂载、主机侧代理,以及 worktree 切换。\n- [Coast Daemon](DAEMON.md) — 本地的 `coastd` 控制平面,用于执行生命周期操作。\n- [Coast CLI](CLI.md) — 用于命令、脚本和代理工作流的终端界面。\n- [Coastguard](COASTGUARD.md) — 通过 `coast ui` 启动的 Web UI,用于可观测性与控制。\n- [Ports](PORTS.md) — 规范端口与动态端口,以及 checkout 如何在它们之间切换。\n- [Primary Port & DNS](PRIMARY_PORT_AND_DNS.md) — 指向主服务的快速链接、用于 Cookie 隔离的子域路由,以及 URL 模板。\n- [Assign and Unassign](ASSIGN.md) — 在 worktree 之间切换一个 Coast 以及可用的 assign 策略。\n- [Checkout](CHECKOUT.md) — 将规范端口映射到某个 Coast 实例,以及你何时需要它。\n- [Lookup](LOOKUP.md) — 发现哪些 Coast 实例与代理当前的 worktree 匹配。\n- [Volume Topology](VOLUMES.md) — 共享服务、共享卷、隔离卷与快照。\n- [Shared Services](SHARED_SERVICES.md) — 主机管理的基础设施服务与卷消歧。\n- [Secrets and Extractors](SECRETS.md) — 提取主机机密并将其注入到 Coast 容器中。\n- [Builds](BUILDS.md) — coast build 的结构、产物存放位置、自动修剪与类型化构建。\n- [Coastfile Types](COASTFILE_TYPES.md) — 可组合的 Coastfile 变体,支持 extends、unset、omit 与 autostart。\n- [Runtimes and Services](RUNTIMES_AND_SERVICES.md) — DinD 运行时、Docker-in-Docker 架构,以及服务如何在 Coast 内运行。\n- [Bare Services](BARE_SERVICES.md) — 在 Coast 内运行非容器化进程,以及为什么你应该改为容器化。\n- [Logs](LOGS.md) — 从 Coast 内读取服务日志、MCP 的取舍,以及 Coastguard 日志查看器。\n- [Exec & Docker](EXEC_AND_DOCKER.md) — 在 Coast 内运行命令并与内部 Docker 守护进程通信。\n- [Agent Shells](AGENT_SHELLS.md) — 容器化的代理 TUI、OAuth 的取舍,以及为什么你可能应该改为在主机上运行代理。\n- [MCP Servers](MCP_SERVERS.md) — 在 Coast 内为容器化代理配置 MCP 工具,内部服务器与主机代理服务器的区别。\n- [Troubleshooting](TROUBLESHOOTING.md) — doctor、守护进程重启、项目移除,以及“出厂重置”核弹选项。\n", "concepts_and_terminology/AGENT_SHELLS.md": "# Agent Shells\n\nAgent shells 是 Coast 内部的 shell,它们会直接打开到一个 agent TUI 运行时——Claude Code、Codex,或任何 CLI agent。你可以在 Coastfile 中通过一个 `[agent_shell]` 段来配置它们,然后 Coast 会在 DinD 容器内生成(spawn)该 agent 进程。\n\n**对于大多数使用场景,你不应该这样做。** 相反,请在宿主机上运行你的编码 agent。共享的[文件系统](FILESYSTEM.md)意味着宿主机侧的 agent 可以像平常一样编辑代码,同时调用 [`coast logs`](LOGS.md)、[`coast exec`](EXEC_AND_DOCKER.md) 和 [`coast ps`](RUNTIMES_AND_SERVICES.md) 来获取运行时信息。Agent shells 会增加凭据挂载、OAuth 复杂性和生命周期复杂性;除非你有一个必须将 agent 本身容器化的特定理由,否则不需要这些。\n\n## The OAuth Problem\n\n如果你在使用 Claude Code、Codex 或类似通过 OAuth 进行认证的工具,那么该 token 是为你的宿主机签发的。当同一个 token 从 Linux 容器内部使用时——不同的 user agent、不同的环境——提供方可能会标记或吊销它。你会遇到难以调试的间歇性认证失败。\n\n对于容器化的 agents,基于 API key 的认证是更安全的选择。将 key 作为 Coastfile 中的一个[secret](SECRETS.md) 设置,并将其注入到容器环境中。\n\n如果无法使用 API key,你可以将 OAuth 凭据挂载到 Coast 中(见下方的 Configuration 章节),但要预期会有摩擦。在 macOS 上,如果你使用 `keychain` secret extractor 来拉取 OAuth token,那么每次 `coast build` 都会提示输入你的 macOS 钥匙串密码。这会让构建过程变得繁琐,尤其是在频繁重建时。Keychain 弹窗是 macOS 的安全要求,无法绕过。\n\n## Configuration\n\n在你的 Coastfile 中添加一个 `[agent_shell]` 段,并提供要运行的命令:\n\n```toml\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\n该命令会在 DinD 容器内的 `/workspace` 执行。Coast 会在容器内创建一个 `coast` 用户,把凭据从 `/root/.claude/` 复制到 `/home/coast/.claude/`,并以该用户运行命令。如果你的 agent 需要将凭据挂载进容器,请使用带文件注入的 `[secrets]`(见 [Secrets and Extractors](SECRETS.md))以及用 `[coast.setup]` 安装 agent CLI:\n\n```toml\n[coast.setup]\nrun = [\"npm install -g @anthropic-ai/claude-code\"]\n\n[secrets.claude_credentials]\nextractor = \"keychain\"\nservice = \"Claude Code-credentials\"\ninject = \"file:/root/.claude/.credentials.json\"\n\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\n如果配置了 `[agent_shell]`,Coast 会在实例启动时自动生成一个 shell。该配置会通过 `extends` 继承,并且可以按 [Coastfile type](COASTFILE_TYPES.md) 进行覆盖。\n\n## The Active Agent Model\n\n每个 Coast 实例可以有多个 agent shell,但任意时刻只有一个是 **active**。active shell 是未指定 `--shell` ID 的命令的默认目标。\n\n```bash\ncoast agent-shell dev-1 ls\n\n SHELL STATUS ACTIVE\n 1 running ★\n 2 running\n```\n\n切换 active shell:\n\n```bash\ncoast agent-shell dev-1 activate 2\n```\n\n你不能关闭 active shell——必须先激活另一个。这能防止你意外杀掉正在交互的 shell。\n\n在 Coastguard 中,agent shells 会在 Exec 面板里以标签页的形式出现,并带有 active/inactive 徽标。点击标签页可查看其终端;使用下拉菜单来激活、生成或关闭 shells。\n\n![Agent shell in Coastguard](../../assets/coastguard-agent-shell.png)\n*一个在 Coast 实例内运行 Claude Code 的 agent shell,可从 Coastguard 的 Exec 标签访问。*\n\n## Sending Input\n\n以编程方式驱动容器化 agent 的主要方式是 `coast agent-shell input`:\n\n```bash\ncoast agent-shell dev-1 input \"fix the failing test in auth.test.ts\"\n```\n\n这会将文本写入 active agent 的 TUI 并按下 Enter。agent 会像你在终端里输入一样接收它。\n\n选项:\n\n- `--no-send` — 写入文本但不按 Enter。用于构建部分输入或导航 TUI 菜单。\n- `--shell ` — 指定某个 shell,而不是 active shell。\n- `--show-bytes` — 打印发送的精确字节,用于调试。\n\n在底层,输入会直接写入 PTY master 文件描述符。文本和 Enter 按键会作为两次独立写入发送,中间间隔 25ms,以避免某些 TUI 框架在接收快速输入时出现的粘贴模式伪影。\n\n## Other Commands\n\n```bash\ncoast agent-shell dev-1 spawn # create a new shell\ncoast agent-shell dev-1 spawn --activate # create and immediately activate\ncoast agent-shell dev-1 tty # attach interactive TTY to active shell\ncoast agent-shell dev-1 tty --shell 2 # attach to a specific shell\ncoast agent-shell dev-1 read-output # read full scrollback buffer\ncoast agent-shell dev-1 read-last-lines 50 # read last 50 lines of output\ncoast agent-shell dev-1 session-status # check if the shell process is alive\n```\n\n`tty` 会给你一个实时的交互式会话——你可以直接在 agent 的 TUI 中键入。使用标准终端转义序列断开连接。`read-output` 和 `read-last-lines` 是非交互式的,会返回文本,这对脚本与自动化很有用。\n\n## Lifecycle and Recovery\n\n在 Coastguard 中,agent shell 会话在页面导航之间保持持久。滚动缓冲区(最多 512KB)会在你重新连接到某个标签页时回放。\n\n当你用 `coast stop` 停止一个 Coast 实例时,所有 agent shell 的 PTY 进程都会被杀掉,并清理它们的数据库记录。如果配置了 `[agent_shell]`,`coast start` 会自动生成一个新的 agent shell。\n\n在 daemon 重启后,之前运行的 agent shells 会显示为已死亡。系统会自动检测——如果 active shell 已死亡,则第一个仍存活的 shell 会被提升为 active。如果没有任何 shell 存活,请用 `coast agent-shell spawn --activate` 生成一个新的。\n\n## Who This Is For\n\nAgent shells 面向的是 **围绕 Coasts 构建第一方集成的产品**——编排平台、agent 包装器,以及希望通过 `input`、`read-output`、`session-status` API 以编程方式管理容器化编码 agent 的工具。\n\n对于通用的并行 agent 编码,请在宿主机上运行 agents。这样更简单,避免 OAuth 问题,绕开凭据挂载的复杂性,并能充分利用共享文件系统。你可以获得 Coast 的全部收益(隔离运行时、端口管理、worktree 切换),而不需要任何 agent 容器化的额外开销。\n\n比 agent shells 更高一层的复杂度是将 [MCP servers](MCP_SERVERS.md) 挂载到 Coast 中,使容器化 agent 能访问工具。这会进一步扩大集成面,并在其他文档中单独覆盖。如果你需要,这个能力是存在的,但大多数用户不应使用。\n", "concepts_and_terminology/ASSIGN.md": "# 分配与取消分配\n\n分配(assign)与取消分配(unassign)用于控制某个 Coast 实例指向哪个 worktree。关于 worktree 切换在挂载层面如何工作,请参见 [Filesystem](FILESYSTEM.md)。\n\n## 分配\n\n`coast assign` 将某个 Coast 实例切换到指定的 worktree。如果该 worktree 尚不存在,Coast 会创建它,更新 Coast 内部的代码,并根据配置的分配策略重启相关服务。\n\n```bash\ncoast assign dev-1 --worktree feature/oauth\n```\n\n```text\nBefore:\n┌─── dev-1 ──────────────────┐\n│ branch: main │\n│ worktree: - │\n└────────────────────────────┘\n\ncoast assign dev-1 --worktree feature/oauth\n\nAfter:\n┌─── dev-1 ──────────────────┐\n│ branch: feature/oauth │\n│ worktree: feature/oauth │\n│ │\n│ postgres → skipped (none) │\n│ web → hot swapped │\n│ api → restarted │\n│ worker → rebuilt │\n└────────────────────────────┘\n```\n\n分配之后,`dev-1` 将运行 `feature/oauth` 分支,并且其所有服务都会启动。\n\n## 取消分配\n\n`coast unassign` 将某个 Coast 实例切换回项目根目录(你的 main/master 分支)。worktree 关联会被移除,Coast 将恢复为从主仓库运行。\n\n```text\ncoast unassign dev-1\n\n┌─── dev-1 ──────────────────┐\n│ branch: main │\n│ worktree: - │\n└────────────────────────────┘\n```\n\n## 分配策略\n\n当某个 Coast 被分配到新的 worktree 时,每个服务都需要知道如何处理代码变更。你可以在 [Coastfile](COASTFILE_TYPES.md) 中的 `[assign]` 为每个服务配置:\n\n```toml\n[assign]\ndefault = \"restart\"\n\n[assign.services]\npostgres = \"none\"\nredis = \"none\"\nweb = \"hot\"\nworker = \"rebuild\"\n```\n\n```text\ncoast assign dev-1 --worktree feature/billing\n\n postgres (strategy: none) → skipped, unchanged between branches\n redis (strategy: none) → skipped, unchanged between branches\n web (strategy: hot) → filesystem swapped, file watcher picks it up\n api (strategy: restart) → container restarted\n worker (strategy: rebuild) → image rebuilt, container restarted\n```\n\n可用策略包括:\n\n- **none** — 不做任何事。用于在不同分支之间不会变化的服务,例如 Postgres 或 Redis。\n- **hot** — 仅交换文件系统。服务保持运行,并通过挂载传播与文件监视器拾取变更(例如具备热重载的开发服务器)。\n- **restart** — 重启服务容器。用于只需要重启进程的解释型服务。这是默认值。\n- **rebuild** — 重新构建服务镜像并重启。用于分支切换会影响 `Dockerfile` 或构建时依赖的情况。\n\n你也可以指定重建触发器,使服务仅在特定文件发生变化时才重建:\n\n```toml\n[assign.rebuild_triggers]\nworker = [\"Dockerfile\", \"package.json\"]\n```\n\n如果触发文件在分支之间没有变化,即使策略设置为 `rebuild`,该服务也会跳过重建。\n\n## 已删除的 Worktree\n\n如果已分配的 worktree 被删除,`coastd` 守护进程会自动将该实例取消分配并切回主 Git 仓库根目录。\n\n---\n\n> **提示:在大型代码库中降低分配延迟**\n>\n> 在底层,对新 worktree 的首次分配会将选定的被 gitignore 忽略的文件引导(bootstrap)到该 worktree 中,并且带有 `[assign.rebuild_triggers]` 的服务可能会运行 `git diff --name-only` 来决定是否需要重建。在大型代码库中,该引导步骤和不必要的重建往往是分配耗时的主要来源。\n>\n> 在你的 Coastfile 中使用 `exclude_paths` 来缩小被 gitignore 忽略文件的引导范围;对带有文件监视器的服务使用 `\"hot\"`;并让 `[assign.rebuild_triggers]` 聚焦于真正的构建时输入。如果你需要为已有 worktree 手动刷新被忽略文件的引导内容,请运行 `coast assign --force-sync`。完整指南参见 [Performance Optimizations](PERFORMANCE_OPTIMIZATIONS.md)。\n", "concepts_and_terminology/BARE_SERVICES.md": "# 裸服务\n\n如果你能把项目容器化,你就应该这么做。裸服务适用于尚未容器化的项目,以及在短期内添加 `Dockerfile` 和 `docker-compose.yml` 不现实的情况。它们是一个过渡台阶,而不是最终归宿。\n\n裸服务不是用 `docker-compose.yml` 来编排容器化服务,而是让你在 Coastfile 中定义 shell 命令,Coast 会在 Coast 容器内使用一个轻量级监督器将它们作为普通进程运行。\n\n## 为什么应该改用容器化\n\n[Docker Compose](RUNTIMES_AND_SERVICES.md) 服务为你提供:\n\n- 通过 Dockerfile 实现可复现的构建\n- Coast 在启动期间可以等待的健康检查\n- 服务之间的进程隔离\n- 由 Docker 处理卷和网络管理\n- 可移植的定义,可在 CI、预发布和生产环境中工作\n\n裸服务不提供上述任何能力。你的进程共享同一个文件系统,崩溃恢复只是一个 shell 循环,而“在我机器上能跑”在 Coast 里同样可能发生(和在 Coast 外一样)。如果你的项目已经有 `docker-compose.yml`,就用它。\n\n## 何时裸服务有意义\n\n- 你正在为一个从未容器化的项目引入 Coast,并希望立刻从工作树隔离和端口管理中获得价值\n- 你的项目是一个单进程工具或 CLI,写 Dockerfile 显得大材小用\n- 你想逐步推进容器化——先用裸服务,之后再迁移到 compose\n\n## 配置\n\n裸服务在 Coastfile 中通过 `[services.]` 段落定义。一个 Coastfile 可以只定义裸服务,也可以与 `compose` 并存——后者请参阅 [Mixed Service Types](MIXED_SERVICE_TYPES.md)。\n\n```toml\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\nrestart = \"on-failure\"\n\n[services.worker]\ncommand = \"node worker.js\"\nrestart = \"always\"\n\n[ports]\nweb = 3000\n```\n\n每个服务有四个字段:\n\n| Field | Required | Description |\n|---|---|---|\n| `command` | yes | 要运行的 shell 命令(例如 `\"npm run dev\"`) |\n| `port` | no | 服务监听的端口,用于端口映射 |\n| `restart` | no | 重启策略:`\"no\"`(默认)、`\"on-failure\"` 或 `\"always\"` |\n| `install` | no | 启动前要运行的一条或多条命令(例如 `\"npm install\"` 或 `[\"npm install\", \"npm run build\"]`) |\n\n### Setup Packages\n\n由于裸服务以普通进程方式运行,Coast 容器需要安装正确的运行时。使用 `[coast.setup]` 来声明系统包:\n\n```toml\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n```\n\n这些会在任何服务启动之前安装。否则,你的 `npm` 或 `node` 命令会在容器内失败。\n\n### Install Commands\n\n`install` 字段会在服务启动前运行,并且在每次 [`coast assign`](ASSIGN.md)(切换分支)时再次运行。这是放置依赖安装的位置:\n\n```toml\n[services.api]\ninstall = [\"pip install -r requirements.txt\", \"python manage.py migrate\"]\ncommand = \"python manage.py runserver 0.0.0.0:8000\"\nport = 8000\n```\n\n安装命令会按顺序执行。只要有任意一条安装命令失败,服务就不会启动。\n\n### Restart Policies\n\n- **`no`** — 服务只运行一次。若退出,将保持停止状态。用于一次性任务或你想手动管理的服务。\n- **`on-failure`** — 当服务以非零退出码退出时重启。正常退出(退出码 0)不会重启。使用从 1 秒到 30 秒的指数退避,并在连续崩溃 10 次后放弃。\n- **`always`** — 任何退出都会重启,包括正常退出。与 `on-failure` 相同的退避策略。用于不应停止的长运行服务器。\n\n如果服务在崩溃前运行超过 30 秒,则重试计数与退避会重置——假设它曾经健康运行了一段时间,此次崩溃是一个新问题。\n\n## 底层工作原理\n\n```text\n┌─── Coast: dev-1 ──────────────────────────────────────┐\n│ │\n│ /coast-supervisor/ │\n│ ├── web.sh (runs command, tracks PID) │\n│ ├── worker.sh │\n│ ├── start-all.sh (launches all services) │\n│ ├── stop-all.sh (SIGTERM via PID files) │\n│ └── ps.sh (checks PID liveness) │\n│ │\n│ /var/log/coast-services/ │\n│ ├── web.log │\n│ └── worker.log │\n│ │\n│ No inner Docker daemon images are used. │\n│ Processes run directly on the container OS. │\n└───────────────────────────────────────────────────────┘\n```\n\nCoast 会为每个服务生成 shell 脚本包装器,并把它们放到 DinD 容器内的 `/coast-supervisor/`。每个包装器会跟踪其 PID,将输出重定向到日志文件,并以 shell 循环的方式实现重启策略。这里没有 Docker Compose、没有内部 Docker 镜像,也没有服务之间的容器级隔离。\n\n`coast ps` 通过检查 PID 是否存活来判断状态,而不是查询 Docker;`coast logs` 通过 tail 日志文件来输出日志,而不是调用 `docker compose logs`。日志输出格式与 compose 的 `service | line` 格式一致,因此 Coastguard 的 UI 无需改动即可工作。\n\n## 端口\n\n端口配置与基于 compose 的 Coast 完全相同。在 `[ports]` 中定义你的服务监听的端口:\n\n```toml\n[services.web]\ncommand = \"npm start\"\nport = 3000\n\n[ports]\nweb = 3000\n```\n\n[Dynamic ports](PORTS.md) 会在 `coast run` 时分配,[`coast checkout`](CHECKOUT.md) 会照常交换规范端口。唯一的区别是:服务之间没有 Docker 网络——它们都直接绑定到容器的 loopback 或 `0.0.0.0`。\n\n## 分支切换\n\n当你在裸服务的 Coast 上运行 `coast assign` 时,会发生以下过程:\n\n1. 通过 SIGTERM 停止所有正在运行的服务\n2. 工作树切换到新分支\n3. 重新运行 install 命令(例如 `npm install` 会获取新分支的依赖)\n4. 重启所有服务\n\n这等同于使用 compose 时发生的事情——`docker compose down`、切换分支、重建、`docker compose up`——只是这里运行的是 shell 进程而不是容器。\n\n## 限制\n\n- **没有健康检查。** Coast 无法像对定义了健康检查的 compose 服务那样等待裸服务“健康”。它只会启动进程并寄希望于一切正常。\n- **服务之间没有隔离。** 所有进程在 Coast 容器内共享同一文件系统与进程命名空间。行为异常的服务可能影响其他服务。\n- **没有构建缓存。** Docker Compose 构建会按层缓存。裸服务的 `install` 命令会在每次 assign 时从头执行。\n- **崩溃恢复很基础。** 重启策略使用带指数退避的 shell 循环。它不是 systemd 或 supervisord 那样的进程监督器。\n- **服务不支持 `[omit]` 或 `[unset]`。** Coastfile 的类型组合适用于 compose 服务,但裸服务不支持通过带类型的 Coastfile 省略单个服务。\n\n## 迁移到 Compose\n\n当你准备好容器化时,迁移路径很直接:\n\n1. 为每个服务编写一个 `Dockerfile`\n2. 创建一个引用这些 Dockerfile 的 `docker-compose.yml`\n3. 将 Coastfile 中的 `[services.*]` 段落替换为一个指向你的 compose 文件的 `compose` 字段\n4. 移除那些现在由 Dockerfile 处理的 `[coast.setup]` 包\n5. 使用 [`coast build`](BUILDS.md) 重新构建\n\n你的端口映射、[volumes](VOLUMES.md)、[shared services](SHARED_SERVICES.md) 和 [secrets](SECRETS.md) 配置都会原封不动地沿用。唯一变化的是服务本身的运行方式。\n", "concepts_and_terminology/BUILDS.md": "# 构建\n\n可以把 coast 构建理解为一个带有额外辅助能力的 Docker 镜像。构建是一个基于目录的工件,打包了创建 Coast 实例所需的一切:已解析的 [Coastfile](COASTFILE_TYPES.md)、重写后的 compose 文件、预拉取的 OCI 镜像 tar 包,以及注入的主机文件。它本身不是 Docker 镜像,但它包含 Docker 镜像(以 tar 包形式)以及 Coast 将它们连接起来所需的元数据。\n\n## `coast build` 的作用\n\n当你运行 `coast build` 时,守护进程会按顺序执行以下步骤:\n\n1. 解析并验证 Coastfile。\n2. 读取 compose 文件并过滤掉被省略的服务。\n3. 从已配置的提取器中提取 [secrets](SECRETS.md),并将其加密存储到 keystore 中。\n4. 为带有 `build:` 指令的 compose 服务在主机上构建 Docker 镜像。\n5. 为带有 `image:` 指令的 compose 服务拉取 Docker 镜像。\n6. 将所有镜像缓存为 OCI tar 包到 `~/.coast/image-cache/`。\n7. 如果配置了 `[coast.setup]`,则使用指定的软件包、命令和文件构建一个自定义 DinD 基础镜像。\n8. 写入构建工件目录,其中包含清单、已解析的 coastfile、重写后的 compose,以及注入的文件。\n9. 更新 `latest` 符号链接,使其指向新的构建。\n10. 自动清理超出保留上限的旧构建。\n\n## 构建存放位置\n\n```text\n~/.coast/\n images/\n my-project/\n latest -> a3c7d783_20260227143000 (symlink)\n a3c7d783_20260227143000/ (versioned build)\n manifest.json\n coastfile.toml\n compose.yml\n inject/\n b4d8e894_20260226120000/ (older build)\n ...\n image-cache/ (shared tarball cache)\n postgres_16_a1b2c3d4e5f6.tar\n redis_7_f6e5d4c3b2a1.tar\n coast-built_my-project_web_latest_...tar\n```\n\n每个构建都会获得一个唯一的 **build ID**,格式为 `{coastfile_hash}_{YYYYMMDDHHMMSS}`。该哈希包含 Coastfile 内容和已解析配置,因此对 Coastfile 的更改会生成新的 build ID。\n\n`latest` 符号链接始终指向最近的构建,以便快速解析。如果你的项目使用了带类型的 Coastfile(例如 `Coastfile.light`),每种类型都会有自己的符号链接:`latest-light`。\n\n位于 `~/.coast/image-cache/` 的镜像缓存由所有项目共享。如果两个项目使用相同的 Postgres 镜像,那么该 tar 包只会被缓存一次。\n\n## 构建包含的内容\n\n每个构建目录包含:\n\n- **`manifest.json`** -- 完整的构建元数据:项目名称、构建时间戳、coastfile 哈希、缓存/构建的镜像列表、secret 名称、被省略的服务、[volume strategies](VOLUMES.md) 等等。\n- **`coastfile.toml`** -- 已解析的 Coastfile(如果使用了 `extends`,则已与父级合并)。\n- **`compose.yml`** -- 你的 compose 文件的重写版本,其中 `build:` 指令会被替换为预构建的镜像标签,并移除被省略的服务。\n- **`inject/`** -- 来自 `[inject].files` 的主机文件副本(例如 `~/.gitconfig`、`~/.npmrc`)。\n\n## 构建不包含 Secrets\n\nSecrets 会在构建步骤中被提取,但它们存储在单独的加密 keystore `~/.coast/keystore.db` 中,而不是存放在构建工件目录内。清单中只记录被提取的 secret 的**名称**,绝不会记录其值。\n\n这意味着你可以安全地检查构建工件,而不会暴露敏感数据。Secrets 会在之后创建 Coast 实例时,通过 `coast run` 解密并注入。\n\n## 构建与 Docker\n\n一个构建涉及三类 Docker 镜像:\n\n- **Built images** -- 带有 `build:` 指令的 compose 服务会通过主机上的 `docker build` 构建,标签为 `coast-built/{project}/{service}:latest`,并作为 tar 包保存到镜像缓存中。\n- **Pulled images** -- 带有 `image:` 指令的 compose 服务会被拉取并保存为 tar 包。\n- **Coast image** -- 如果配置了 `[coast.setup]`,则会在 `docker:dind` 之上构建一个自定义 Docker 镜像,并包含指定的软件包、命令和文件。其标签为 `coast-image/{project}:{build_id}`。\n\n在运行时([`coast run`](RUN.md)),这些 tar 包会通过 `docker load` 被加载到内部的 [DinD daemon](RUNTIMES_AND_SERVICES.md) 中。这也是 Coast 实例能够快速启动而无需从镜像仓库拉取镜像的原因。\n\n## 构建与实例\n\n当你运行 [`coast run`](RUN.md) 时,Coast 会解析最新构建(或指定的 `--build-id`),并使用其工件来创建实例。该 build ID 会记录在实例上。\n\n你不需要为了创建更多实例而重新构建。一个构建可以服务于多个并行运行的 Coast 实例。\n\n## 何时重新构建\n\n只有当你的 Coastfile、`docker-compose.yml` 或基础设施配置发生变化时,才需要重新构建。重新构建是资源密集型操作——它会重新拉取镜像、重新构建 Docker 镜像,并重新提取 secrets。\n\n代码变更不需要重新构建。Coast 会将你的项目目录直接挂载到每个实例中,因此代码更新会立即生效。\n\n## 自动清理\n\nCoast 对每种 Coastfile 类型最多保留 5 个构建。每次 `coast build` 成功后,超出上限的旧构建会被自动删除。\n\n正在被运行中实例使用的构建永远不会被清理,无论上限是多少。如果你有 7 个构建,但其中 3 个正在支撑活动实例,那么这 3 个都会受到保护。\n\n## 手动删除\n\n你可以通过 `coast rm-build` 或 Coastguard 的 Builds 标签页手动删除构建。\n\n- **完整项目删除**(`coast rm-build `)要求先停止并删除所有实例。它会移除整个构建目录、相关的 Docker 镜像、卷和容器。\n- **选择性删除**(按 build ID,在 Coastguard UI 中可用)会跳过那些正在被运行中实例使用的构建。\n\n## 类型化构建\n\n如果你的项目使用多个 Coastfile(例如默认配置使用 `Coastfile`,而快照种子卷使用 `Coastfile.snap`),那么每种类型都会维护自己的 `latest-{type}` 符号链接,以及各自独立的 5 个构建清理池。\n\n```bash\ncoast build # uses Coastfile, updates \"latest\"\ncoast build --type snap # uses Coastfile.snap, updates \"latest-snap\"\n```\n\n清理 `snap` 构建永远不会影响 `default` 构建,反之亦然。\n", - "concepts_and_terminology/CHECKOUT.md": "# Checkout\n\nCheckout 控制哪个 Coast 实例拥有你项目的[规范端口](PORTS.md)。当你 checkout 一个 Coast 时,`localhost:3000`、`localhost:5432` 以及其他所有规范端口都会直接映射到该实例。\n\n```bash\ncoast checkout dev-1\n```\n\n```text\nBefore checkout:\n localhost:3000 ──→ (nothing)\n localhost:5432 ──→ (nothing)\n\nAfter checkout:\n localhost:3000 ──→ dev-1 web\n localhost:5432 ──→ dev-1 db\n```\n\n切换 checkout 是即时完成的——Coast 会终止并重新生成轻量级的 `socat` 转发器。不会重启任何容器。\n\n```bash\ncoast checkout dev-2 # instant swap\n\n# localhost:3000 ──→ dev-2 web\n# localhost:5432 ──→ dev-2 db\n```\n\n## Linux Note\n\nLinux 说明\n\n动态端口在 Linux 上始终可用,不需要特殊权限。\n\n低于 `1024` 的规范端口则不同。如果你的 Coastfile 声明了像 `80` 或 `443` 这样的端口,在你配置主机之前,Linux 可能会阻止 `coast checkout` 绑定这些端口。常见的修复方式有:\n\n- 提高 `net.ipv4.ip_unprivileged_port_start`\n- 向转发二进制文件或进程授予绑定能力\n\n当主机拒绝绑定时,Coast 会明确报告这一点。\n\n在 WSL 上,Coast 使用 Docker 发布的 checkout bridge,因此 Windows 浏览器和工具可以通过 `127.0.0.1` 访问已 checkout 的规范端口,这类似于 Docker Desktop 工作流(如 Sail)。\n\n## Do You Need to Check Out?\n\n你需要执行 Check Out 吗?\n\n不一定。每个正在运行的 Coast 始终都有自己的动态端口,而且你随时都可以通过这些端口访问任意 Coast,而无需 checkout 任何内容。\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\n你可以在浏览器中打开 `localhost:62217` 来访问 dev-1 的 Web 服务器,而无需 checkout。这对于许多工作流来说完全没问题,而且你可以运行任意数量的 Coast,而完全不使用 `coast checkout`。\n\n## When Checkout Is Useful\n\n什么时候 Checkout 有用\n\n在某些情况下,动态端口并不够用,你需要规范端口:\n\n- **硬编码为规范端口的客户端应用。** 如果你有一个运行在 Coast 外部的客户端——比如主机上的前端开发服务器、手机上的移动应用,或者桌面应用——它期望使用 `localhost:3000` 或 `localhost:8080`,那么到处修改端口号会很不现实。checkout 该 Coast 后,你就可以在不更改任何配置的情况下使用真实端口。\n\n- **Webhook 和回调 URL。** 像 Stripe、GitHub 或 OAuth 提供商这样的服务会将回调发送到你已注册的 URL——通常类似于 `https://your-ngrok-tunnel.io`,并转发到 `localhost:3000`。如果你切换到动态端口,这些回调就不会再到达。checkout 可确保你正在测试的 Coast 使用的是活动的规范端口。\n\n- **数据库工具、调试器和 IDE 集成。** 许多 GUI 客户端(pgAdmin、DataGrip、TablePlus)、调试器和 IDE 运行配置都会以特定端口保存连接配置。Checkout 让你可以保留这些已保存的配置,只需切换其背后的 Coast——无需在每次切换上下文时重新配置调试器附加目标或数据库连接。\n\n## Releasing Checkout\n\n释放 Checkout\n\n如果你想释放规范端口,而不是 checkout 到另一个 Coast:\n\n```bash\ncoast checkout --none\n```\n\n执行后,将不会有任何 Coast 拥有这些规范端口。所有 Coast 仍然可以通过它们各自的动态端口访问。\n\n## Only One at a Time\n\n一次只能有一个\n\n任意时刻只能有一个 Coast 被 checkout。如果 `dev-1` 已被 checkout,而你运行 `coast checkout dev-2`,规范端口会立即切换到 `dev-2`。中间不会有空档——旧的转发器会被终止,新的转发器会在同一次操作中生成。\n\n```text\n┌──────────────────────────────────────────────────┐\n│ Your machine │\n│ │\n│ Canonical (checked-out Coast only): │\n│ localhost:3000 ──→ dev-2 web │\n│ localhost:5432 ──→ dev-2 db │\n│ │\n│ Dynamic (always available): │\n│ localhost:62217 ──→ dev-1 web │\n│ localhost:55681 ──→ dev-1 db │\n│ localhost:63104 ──→ dev-2 web │\n│ localhost:57220 ──→ dev-2 db │\n└──────────────────────────────────────────────────┘\n```\n\n动态端口不受 checkout 影响。唯一发生变化的是规范端口所指向的位置。\n", + "concepts_and_terminology/CHECKOUT.md": "# Checkout\n\nCheckout 控制哪个 Coast 实例拥有你项目的[规范端口](PORTS.md)。当你 checkout 一个 Coast 时,`localhost:3000`、`localhost:5432` 以及其他所有规范端口都会直接映射到该实例。\n\n```bash\ncoast checkout dev-1\n```\n\n```text\nBefore checkout:\n localhost:3000 ──→ (nothing)\n localhost:5432 ──→ (nothing)\n\nAfter checkout:\n localhost:3000 ──→ dev-1 web\n localhost:5432 ──→ dev-1 db\n```\n\n切换 checkout 是即时完成的——Coast 会终止并重新生成轻量级的 `socat` 转发器。不会重启任何容器。\n\n```bash\ncoast checkout dev-2 # instant swap\n\n# localhost:3000 ──→ dev-2 web\n# localhost:5432 ──→ dev-2 db\n```\n\n## Linux Note\n\n动态端口在 Linux 上始终可用,不需要特殊权限。\n\n低于 `1024` 的规范端口则不同。如果你的 Coastfile 声明了像 `80` 或 `443` 这样的端口,在你配置主机之前,Linux 可能会阻止 `coast checkout` 绑定这些端口。常见的修复方式有:\n\n- 提高 `net.ipv4.ip_unprivileged_port_start`\n- 向转发二进制文件或进程授予绑定能力\n\n当主机拒绝绑定时,Coast 会明确报告这一点。\n\n在 WSL 上,Coast 使用 Docker 发布的 checkout bridge,因此 Windows 浏览器和工具可以通过 `127.0.0.1` 访问已 checkout 的规范端口,这类似于 Docker Desktop 工作流(如 Sail)。\n\n对于使用 Caddy 的本地 HTTPS 项目,Coast 会为每个 Coast 安装复用同一个 Caddy 本地 CA。你只需信任一次该根证书,在同一安装下重新创建的工作区就会继续使用它。\n\n根证书位于:\n\n- 常规安装为 `~/.coast/caddy/pki/authorities/local/root.crt`\n- `coast-dev` 为 `~/.coast-dev/caddy/pki/authorities/local/root.crt`\n\n它们是有意分开的,因此信任 `coast-dev` 不会同时信任常规的 `coast` 安装,反之亦然。\n\n要查看或导出当前安装的根证书:\n\n```bash\ncoast cert info\ncoast cert path\ncoast cert fingerprint\ncoast cert export --to ~/Downloads/coast-root.crt\n```\n\nCoast 将信任安装交由你自己处理。导出证书后,再按需将其导入你的操作系统或浏览器信任存储中。\n\n## Do You Need to Check Out?\n\n不一定。每个正在运行的 Coast 始终都有自己的动态端口,而且你随时都可以通过这些端口访问任意 Coast,而无需 checkout 任何内容。\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\n你可以在浏览器中打开 `localhost:62217` 来访问 dev-1 的 Web 服务器,而无需 checkout。这对于许多工作流来说完全没问题,而且你可以运行任意数量的 Coast,而完全不使用 `coast checkout`。\n\n## When Checkout Is Useful\n\n在某些情况下,动态端口并不够用,你需要规范端口:\n\n- **硬编码为规范端口的客户端应用。** 如果你有一个运行在 Coast 外部的客户端——比如主机上的前端开发服务器、手机上的移动应用,或者桌面应用——它期望使用 `localhost:3000` 或 `localhost:8080`,那么到处修改端口号会很不现实。checkout 该 Coast 后,你就可以在不更改任何配置的情况下使用真实端口。\n\n- **Webhook 和回调 URL。** 像 Stripe、GitHub 或 OAuth 提供商这样的服务会将回调发送到你已注册的 URL——通常类似于 `https://your-ngrok-tunnel.io`,并转发到 `localhost:3000`。如果你切换到动态端口,这些回调就不会再到达。checkout 可确保你正在测试的 Coast 使用的是活动的规范端口。\n\n- **数据库工具、调试器和 IDE 集成。** 许多 GUI 客户端(pgAdmin、DataGrip、TablePlus)、调试器和 IDE 运行配置都会以特定端口保存连接配置。Checkout 让你可以保留这些已保存的配置,只需切换其背后的 Coast——无需在每次切换上下文时重新配置调试器附加目标或数据库连接。\n\n## Releasing Checkout\n\n如果你想释放规范端口,而不是 checkout 到另一个 Coast:\n\n```bash\ncoast checkout --none\n```\n\n执行后,将不会有任何 Coast 拥有这些规范端口。所有 Coast 仍然可以通过它们各自的动态端口访问。\n\n## Only One at a Time\n\n任意时刻只能有一个 Coast 被 checkout。如果 `dev-1` 已被 checkout,而你运行 `coast checkout dev-2`,规范端口会立即切换到 `dev-2`。中间不会有空档——旧的转发器会被终止,新的转发器会在同一次操作中生成。\n\n```text\n┌──────────────────────────────────────────────────┐\n│ Your machine │\n│ │\n│ Canonical (checked-out Coast only): │\n│ localhost:3000 ──→ dev-2 web │\n│ localhost:5432 ──→ dev-2 db │\n│ │\n│ Dynamic (always available): │\n│ localhost:62217 ──→ dev-1 web │\n│ localhost:55681 ──→ dev-1 db │\n│ localhost:63104 ──→ dev-2 web │\n│ localhost:57220 ──→ dev-2 db │\n└──────────────────────────────────────────────────┘\n```\n\n动态端口不受 checkout 影响。唯一发生变化的是规范端口所指向的位置。\n", "concepts_and_terminology/CLI.md": "# Coast CLI\n\nCoast CLI(`coast`)是用于操作 Coast 的主要命令行界面。它被有意设计得很轻量:它会解析你的命令,将请求发送给 [`coastd`](DAEMON.md),并将结构化输出打印回你的终端。\n\n## 其用途\n\n典型工作流都通过 CLI 驱动:\n\n```bash\ncoast build # see Builds\ncoast run dev-1 # see Run\ncoast assign dev-1 --worktree feature/oauth # see Assign\ncoast ports dev-1 # see Ports\ncoast checkout dev-1 # see Checkout\ncoast ui # see Coastguard\n```\n\nCLI 还包含对人类和代理都很有用的文档命令:\n\n```bash\ncoast docs\ncoast docs --path concepts_and_terminology/CHECKOUT.md\ncoast search-docs \"canonical vs dynamic ports\"\n```\n\n## 为什么它与守护进程分离存在\n\n将 CLI 与守护进程分离会带来一些重要好处:\n\n- 守护进程负责保存状态和长生命周期进程。\n- CLI 保持快速、可组合且易于编写脚本。\n- 你可以运行一次性命令,而无需保持终端状态存活。\n- 代理工具可以以可预测、适合自动化的方式调用 CLI 命令。\n\n## CLI 与 Coastguard\n\n使用最适合当前场景的界面:\n\n- CLI 旨在提供完整的操作覆盖:你在 Coastguard 中能做的任何事情,也都应该可以通过 CLI 完成。\n- 将 CLI 视为自动化接口——脚本、代理工作流、CI 作业以及自定义开发者工具。\n- 将 [Coastguard](COASTGUARD.md) 视为人类界面——可视化检查、交互式调试和运行可见性。\n\n两者都与同一个守护进程通信,因此它们基于相同的底层项目状态运行。\n", "concepts_and_terminology/COASTFILE_TYPES.md": "# Coastfile 类型\n\n一个项目可以针对不同的使用场景拥有多个 Coastfile。每个变体称为一种“类型(type)”。类型让你可以组合共享同一基础配置但在运行哪些服务、如何处理卷、或服务是否自动启动方面有所不同的配置。\n\n## 类型如何工作\n\n命名约定为:默认使用 `Coastfile`,变体使用 `Coastfile.{type}`。点号后面的后缀就是类型名称:\n\n- `Coastfile` -- 默认类型\n- `Coastfile.test` -- 测试类型\n- `Coastfile.snap` -- 快照类型\n- `Coastfile.light` -- 轻量类型\n\n你可以使用 `--type` 来构建并运行带类型的 Coast:\n\n```bash\ncoast build --type test\ncoast run test-1 --type test\ncoast exec test-1 -- go test ./...\n```\n\n## extends\n\n带类型的 Coastfile 通过 `extends` 从父级继承。父级中的所有内容都会被合并进来。子级只需要指定它要覆盖或新增的内容。\n\n```toml\n[coast]\nextends = \"Coastfile\"\n```\n\n这避免了为每个变体重复整套配置。子级会从父级继承所有 [ports](PORTS.md)、[secrets](SECRETS.md)、[volumes](VOLUMES.md)、[shared services](SHARED_SERVICES.md)、[assign strategies](ASSIGN.md)、setup 命令以及 [MCP](MCP_SERVERS.md) 配置。子级定义的任何内容都会优先于父级。\n\n## [unset]\n\n按名称移除从父级继承的特定条目。你可以 unset `ports`、`shared_services`、`secrets` 和 `volumes`。\n\n```toml\n[unset]\nports = [\"web\", \"redis\", \"backend\"]\nshared_services = [\"postgres\", \"redis\"]\n```\n\n这就是测试变体如何移除 shared services(让数据库在 Coast 内部运行并使用隔离卷),以及移除它不需要的端口。\n\n## [omit]\n\n从构建中彻底剔除 compose 服务。被 omit 的服务会从 compose 文件中移除,并且根本不会在 Coast 内运行。\n\n```toml\n[omit]\nservices = [\"redis\", \"backend\", \"mailhog\", \"web\"]\n```\n\n用它来排除与该变体目的无关的服务。测试变体可能只保留数据库、迁移以及测试运行器。\n\n## autostart\n\n控制 Coast 启动时是否自动运行 `docker compose up`。默认值为 `true`。\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n```\n\n对于你希望手动运行特定命令、而不是拉起完整堆栈的变体,请设置 `autostart = false`。这在测试运行器中很常见——你先创建 Coast,然后使用 [`coast exec`](EXEC_AND_DOCKER.md) 运行单独的测试套件。\n\n## 常见模式\n\n### 测试变体\n\n一个 `Coastfile.test`,只保留运行测试所需内容:\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n\n[unset]\nports = [\"web\", \"redis\", \"backend\"]\nshared_services = [\"postgres\", \"redis\"]\n\n[omit]\nservices = [\"redis\", \"backend\", \"mailhog\", \"web\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[assign]\ndefault = \"none\"\n[assign.services]\ntest-runner = \"rebuild\"\nmigrations = \"rebuild\"\n```\n\n每个测试 Coast 都会拥有自己干净的数据库。不会暴露任何端口,因为测试通过内部 compose 网络与服务通信。`autostart = false` 表示你使用 `coast exec` 手动触发测试运行。\n\n### 快照变体\n\n一个 `Coastfile.snap`,在创建每个 Coast 时,用主机上现有数据库卷的副本进行初始化:\n\n```toml\n[coast]\nextends = \"Coastfile\"\n\n[unset]\nshared_services = [\"postgres\", \"redis\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"my_project_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"my_project_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n```\n\n通过 unset shared services,让数据库在每个 Coast 内部运行。`snapshot_source` 会在构建时从现有主机卷为隔离卷提供初始数据。创建后,每个实例的数据都会各自独立地分化。\n\n### 轻量变体\n\n一个 `Coastfile.light`,将项目裁剪到特定工作流的最小集合——例如只保留一个后端服务及其数据库,以便快速迭代。\n\n## 独立的构建池\n\n每种类型都有自己的 `latest-{type}` 符号链接,以及各自 5 个构建的自动清理池:\n\n```bash\ncoast build # 更新 latest,清理默认构建\ncoast build --type test # 更新 latest-test,清理 test 构建\ncoast build --type snap # 更新 latest-snap,清理 snap 构建\n```\n\n构建 `test` 类型不会影响 `default` 或 `snap` 的构建。清理对每种类型而言完全独立。\n\n## 运行带类型的 Coasts\n\n使用 `--type` 创建的实例会被标记为对应类型。你可以让同一项目的不同类型实例同时运行:\n\n```bash\ncoast run dev-1 # 默认类型\ncoast run test-1 --type test # 测试类型\ncoast run snapshot-1 --type snap # 快照类型\n\ncoast ls\n# 三者都会出现,每个都有自己的类型、端口和卷策略\n```\n\n这样你就可以让完整的开发环境与隔离的测试运行器和基于快照初始化的实例并行运行——同一个项目、同一时间、同时存在。\n", "concepts_and_terminology/COASTGUARD.md": "# Coastguard\n\nCoastguard 是 Coast 的本地 Web UI(可理解为:Coast 的 Docker Desktop 风格界面),运行在端口 `31415`。它从 CLI 启动:\n\n```bash\ncoast ui\n```\n\n![Coastguard project overview](../../assets/coastguard-overview.png)\n*项目仪表板,显示正在运行的 Coast 实例、它们的分支/工作树,以及检出状态。*\n\n![Coastguard port mappings](../../assets/coastguard-ports.png)\n*特定 Coast 实例的端口页面,显示每个服务的规范端口与动态端口映射。*\n\n## What Coastguard Is Good For\n\nCoastguard 为你的项目提供可视化的控制与可观测性界面:\n\n- 查看项目、实例、状态、分支,以及检出状态。\n- 检查[端口映射](PORTS.md)并直接跳转到服务。\n- 查看[日志](LOGS.md)、运行时统计,并检查数据。\n- 浏览[构建](BUILDS.md)、镜像制品、[卷](VOLUMES.md)以及[密钥](SECRETS.md)元数据。\n- 在工作时于应用内浏览文档。\n\n## Relationship to CLI and Daemon\n\nCoastguard 不会取代 CLI。它作为面向人的界面对 CLI 进行补充。\n\n- [`coast` CLI](CLI.md) 是用于脚本、代理工作流以及工具集成的自动化接口。\n- Coastguard 是用于可视化检查、交互式调试与日常运维可见性的面向人的界面。\n- 二者都是 [`coastd`](DAEMON.md) 的客户端,因此始终保持同步。\n", "concepts_and_terminology/COASTS.md": "# Coast\n\nCoast 是你项目的一个自包含运行时。它运行在一个 [Docker-in-Docker 容器](RUNTIMES_AND_SERVICES.md) 内,并且多个服务(你的 Web 服务器、数据库、缓存等)都可以在单个 Coast 实例中运行。\n\n```text\n┌─── Coast: dev-1 (branch: feature/oauth) ──────────────┐\n│ │\n│ ┌─────────┐ ┌──────────┐ ┌─────────┐ │\n│ │ web │ │ postgres │ │ redis │ │\n│ │ :3000 │ │ :5432 │ │ :6379 │ │\n│ └─────────┘ └──────────┘ └─────────┘ │\n│ │\n│ dynamic ports: 62217, 55681, 56905 │\n└───────────────────────────────────────────────────────┘\n\n┌─── Coast: dev-2 (branch: feature/billing) ────────────┐\n│ │\n│ ┌─────────┐ ┌──────────┐ ┌─────────┐ │\n│ │ web │ │ postgres │ │ redis │ │\n│ │ :3000 │ │ :5432 │ │ :6379 │ │\n│ └─────────┘ └──────────┘ └─────────┘ │\n│ │\n│ dynamic ports: 63104, 57220, 58412 │\n└───────────────────────────────────────────────────────┘\n```\n\n每个 Coast 都会向主机暴露自己的一组 [动态端口](PORTS.md),这意味着无论还有什么在运行,你都可以随时访问任何正在运行的 Coast。\n\n当你 [签出](CHECKOUT.md) 一个 Coast 时,项目的规范端口会被映射到它——因此 `localhost:3000` 会命中已签出的 Coast,而不是某个动态端口。\n\n```text\ncoast checkout dev-1\n\nlocalhost:3000 ──→ dev-1 web\nlocalhost:5432 ──→ dev-1 postgres\nlocalhost:6379 ──→ dev-1 redis\n\ncoast checkout dev-2 (instant swap)\n\nlocalhost:3000 ──→ dev-2 web\nlocalhost:5432 ──→ dev-2 postgres\nlocalhost:6379 ──→ dev-2 redis\n```\n\n通常,一个 Coast 会[分配给特定的工作树](ASSIGN.md)。这就是你如何并行运行同一项目的多个工作树,而不会发生端口冲突或卷冲突。\n\n你可以使用 [`coast run`](RUN.md) 创建 Coast 实例。至于何时启动或关闭 Coast,则由你自行决定。你大概不会想让一个内存密集型项目的 20 个 Coast 同时运行,不过各人有各人的选择。\n", "concepts_and_terminology/DAEMON.md": "# Coast 守护进程\n\nCoast 守护进程(`coastd`)是一个长期运行的本地进程,负责实际的编排工作。[CLI](CLI.md) 和 [Coastguard](COASTGUARD.md) 是客户端;`coastd` 是它们背后的控制平面。\n\n## 架构概览\n\n```text\ncoast CLI (automation) -----+\n +--> coastd daemon\nCoastguard UI (human) ------+ |\n +--> Coasts\n +--> Ports\n +--> State\n```\n\nCLI 通过本地 Unix 套接字向 `coastd` 发送请求;Coastguard 通过 WebSocket 连接。守护进程将变更应用到运行时状态。\n\n## 它做什么\n\n`coastd` 处理那些需要持久化状态和后台协调的操作:\n\n- 跟踪 Coast 实例、构建以及共享服务。\n- 创建、启动、停止并移除 Coast 运行时。\n- 应用 assign/unassign/checkout 操作。\n- 管理规范与动态的[端口转发](PORTS.md)。\n- 向 CLI 和 UI 客户端流式传输[日志](LOGS.md)、状态以及运行时事件。\n\n简而言之:如果你运行 `coast run`、`coast assign`、`coast checkout` 或 `coast ls`,做实际工作的组件就是该守护进程。\n\n## 它如何运行\n\n你可以通过两种常见方式运行守护进程:\n\n```bash\n# Register daemon auto-start at login (recommended)\ncoast daemon install\n\n# Manual start mode\ncoast daemon start\n```\n\n如果你跳过守护进程安装,则每次会话在使用 Coast 命令之前都需要自己启动它。\n\n## 报告 Bug\n\n如果你遇到问题,在提交 bug 报告时请包含 `coastd` 守护进程日志。日志包含诊断大多数问题所需的上下文:\n\n```bash\ncoast daemon logs\n```\n", - "concepts_and_terminology/EXEC_AND_DOCKER.md": "# Exec & Docker\n\n`coast exec` 会将你带入 Coast 的 DinD 容器内的一个 shell。你的工作目录是 `/workspace` —— [绑定挂载的项目根目录](FILESYSTEM.md),也就是你的 Coastfile 所在的位置。这是在主机上运行命令、检查文件或调试 Coast 内服务的主要方式。\n\n`coast docker` 是用于直接与内部 Docker 守护进程通信的配套命令。\n\n## `coast exec`\n\n在某个 Coast 实例内打开一个 shell:\n\n```bash\ncoast exec dev-1\n```\n\n这会在 `/workspace` 启动一个 `sh` 会话。Coast 容器基于 Alpine,因此默认 shell 是 `sh`,而不是 `bash`。\n\n你也可以在不进入交互式 shell 的情况下运行特定命令:\n\n```bash\ncoast exec dev-1 ls -la\ncoast exec dev-1 -- npm install\ncoast exec dev-1 -- go test ./...\n```\n\n实例名称之后的所有内容都会作为命令传递。使用 `--` 将属于你的命令的标志与属于 `coast exec` 的标志分开。\n\n### Working Directory\n\nshell 从 `/workspace` 启动,它是你主机项目根目录绑定挂载到容器中的位置。这意味着你的源代码、Coastfile 以及所有项目文件都在那里:\n\n```text\n/workspace $ ls\nCoastfile README.md apps/ packages/\nCoastfile.light go.work infra/ scripts/\nCoastfile.snap go.work.sum package-lock.json\n```\n\n你在 `/workspace` 下对文件所做的任何更改都会立即反映到主机上——这是绑定挂载,而不是拷贝。\n\n### Interactive vs Non-Interactive\n\n当 stdin 是 TTY(你在终端里输入)时,`coast exec` 会完全绕过守护进程,直接运行 `docker exec -it` 以获得完整的 TTY 透传。这意味着颜色、光标移动、Tab 补全以及交互式程序都能按预期工作。\n\n当 stdin 是通过管道传入或脚本化(CI、agent 工作流、`coast exec dev-1 -- some-command | grep foo`)时,请求会经过守护进程,并返回结构化的 stdout、stderr 和退出码。\n\n### File Permissions\n\nexec 以你主机用户的 UID:GID 运行,因此在 Coast 内创建的文件在主机上拥有正确的所有权。主机与容器之间不会出现权限不匹配。\n\n## `coast docker`\n\n`coast exec` 让你进入 DinD 容器本身的 shell,而 `coast docker` 让你针对 **内部** Docker 守护进程运行 Docker CLI 命令——也就是管理你的 compose 服务的那个守护进程。\n\n```bash\ncoast docker dev-1 # defaults to: docker ps\ncoast docker dev-1 ps # same as above\ncoast docker dev-1 compose ps # docker compose ps (inner services)\ncoast docker dev-1 images # list images in the inner daemon\ncoast docker dev-1 compose logs web # docker compose logs for a service\n```\n\n你传入的每条命令都会自动加上 `docker` 前缀。因此 `coast docker dev-1 compose ps` 会在 Coast 容器内运行 `docker compose ps`,并与内部守护进程通信。\n\n### `coast exec` vs `coast docker`\n\n区别在于你要操作的目标:\n\n| Command | Runs as | Target |\n|---|---|---|\n| `coast exec dev-1 ls /workspace` | `sh -c \"ls /workspace\"` in DinD container | Coast 容器本身(你的项目文件、已安装的工具) |\n| `coast docker dev-1 ps` | `docker ps` in DinD container | 内部 Docker 守护进程(你的 compose 服务容器) |\n| `coast docker dev-1 compose logs web` | `docker compose logs web` in DinD container | 通过内部守护进程获取特定 compose 服务的日志 |\n\n将 `coast exec` 用于项目级工作——运行测试、安装依赖、检查文件。需要查看内部 Docker 守护进程在做什么时——容器状态、镜像、网络、compose 操作——使用 `coast docker`。\n\n## Coastguard Exec Tab\n\nCoastguard Web UI 提供了一个通过 WebSocket 连接的持久交互式终端。\n\n![Exec tab in Coastguard](../../assets/coastguard-exec.png)\n*Coastguard 的 Exec 标签页,展示了在某个 Coast 实例内 /workspace 目录的 shell 会话。*\n\n该终端由 xterm.js 驱动,并提供:\n\n- **持久会话** — 终端会话在页面导航和浏览器刷新后仍然保留。重新连接会回放滚动缓冲区,因此你可以从离开的地方继续。\n- **多个标签页** — 同时打开多个 shell。每个标签页都是独立会话。\n- **[Agent shell](AGENT_SHELLS.md) 标签页** — 为 AI 编码 agent 生成专用的 agent shell,并跟踪活跃/非活跃状态。\n- **全屏模式** — 将终端扩展为全屏(按 Escape 退出)。\n\n除了实例级的 exec 标签页之外,Coastguard 还在其他层级提供终端访问:\n\n- **服务 exec** — 从 Services 标签页进入某个单独服务,以在该特定内部容器中获得一个 shell(这会执行双重 `docker exec`——先进入 DinD 容器,再进入服务容器)。\n- **[共享服务](SHARED_SERVICES.md) exec** — 在主机级共享服务容器内获得一个 shell。\n- **主机终端** — 在你的主机机器上、项目根目录处的 shell,无需进入任何 Coast。\n\n## When to Use Which\n\n- **`coast exec`** — 在 DinD 容器内运行项目级命令(npm install、go test、文件检查、调试)。\n- **`coast docker`** — 检查或管理内部 Docker 守护进程(容器状态、镜像、网络、compose 操作)。\n- **Coastguard Exec tab** — 通过持久会话、多标签页和 agent shell 支持进行交互式调试。当你希望在浏览 UI 其他部分时保持多个终端打开,这是最佳选择。\n- **`coast logs`** — 读取服务输出时,使用 `coast logs` 而不是 `coast docker compose logs`。参见 [Logs](LOGS.md)。\n- **`coast ps`** — 检查服务状态时,使用 `coast ps` 而不是 `coast docker compose ps`。参见 [Runtimes and Services](RUNTIMES_AND_SERVICES.md)。\n", + "concepts_and_terminology/EXEC_AND_DOCKER.md": "# Exec 与 Docker\n\n`coast exec` 会让你进入 Coast 的 DinD 容器内的一个 shell。你的工作目录是 `/workspace` —— 即 [bind-mounted project root](FILESYSTEM.md),也就是你的 Coastfile 所在的位置。这是在宿主机上进入 Coast 内部运行命令、检查文件或调试服务的主要方式。\n\n`coast docker` 是一个配套命令,用于直接与内部 Docker 守护进程通信。\n\n## `coast exec`\n\n在 Coast 实例内打开一个 shell:\n\n```bash\ncoast exec dev-1\n```\n\n这会在 `/workspace` 启动一个 `sh` 会话。Coast 容器基于 Alpine,因此默认 shell 是 `sh`,而不是 `bash`。\n\n你也可以不进入交互式 shell,直接运行指定命令:\n\n```bash\ncoast exec dev-1 ls -la\ncoast exec dev-1 -- npm install\ncoast exec dev-1 -- go test ./...\ncoast exec dev-1 --service web\ncoast exec dev-1 --service web -- php artisan test\n```\n\n实例名后面的所有内容都会作为命令传递。使用 `--` 来分隔属于你命令的参数和属于 `coast exec` 的参数。\n\n传入 `--service ` 可将目标指定为某个特定的 compose 服务容器,而不是外层的 Coast 容器。当你需要原始的容器 root 权限,而不是 Coast 默认的宿主机 UID:GID 映射时,传入 `--root`。\n\n### 工作目录\n\nshell 会从 `/workspace` 启动,它是绑定挂载到容器中的宿主机项目根目录。这意味着你的源代码、Coastfile 和所有项目文件都在那里:\n\n```text\n/workspace $ ls\nCoastfile README.md apps/ packages/\nCoastfile.light go.work infra/ scripts/\nCoastfile.snap go.work.sum package-lock.json\n```\n\n你对 `/workspace` 下文件所做的任何更改都会立即反映到宿主机上 —— 它是一个 bind mount,而不是副本。\n\n### 交互式与非交互式\n\n当 stdin 是 TTY(你正在终端中输入)时,`coast exec` 会完全绕过守护进程,直接运行 `docker exec -it` 以获得完整的 TTY 透传。这意味着颜色、光标移动、tab 补全以及交互式程序都能按预期工作。\n\n当 stdin 通过管道传入或由脚本驱动时(CI、代理工作流、`coast exec dev-1 -- some-command | grep foo`),请求会通过守护进程处理,并返回结构化的 stdout、stderr 和退出码。\n\n### 文件权限\n\nexec 会以你的宿主机用户 UID:GID 运行,因此在 Coast 内创建的文件在宿主机上会拥有正确的所有权。宿主机与容器之间不会出现权限不匹配。\n\n## `coast docker`\n\n`coast exec` 会让你进入 DinD 容器本身的 shell,而 `coast docker` 则允许你针对**内部** Docker 守护进程运行 Docker CLI 命令 —— 也就是管理你的 compose 服务的那个守护进程。\n\n```bash\ncoast docker dev-1 # 默认等同于: docker ps\ncoast docker dev-1 ps # 与上面相同\ncoast docker dev-1 compose ps # 对当前由 Coast 管理的栈执行 docker compose ps\ncoast docker dev-1 images # 列出内部守护进程中的镜像\ncoast docker dev-1 compose logs web # 某个服务的 docker compose logs\n```\n\n你传入的每条命令都会自动加上 `docker` 前缀。因此,`coast docker dev-1 compose ps` 会在 Coast 容器内运行 `docker compose ps`,并与内部守护进程通信。\n\n### `coast exec` 与 `coast docker`\n\n区别在于你要操作的目标是什么:\n\n| Command | Runs as | Target |\n|---|---|---|\n| `coast exec dev-1 ls /workspace` | 在 DinD 容器中运行 `sh -c \"ls /workspace\"` | Coast 容器本身(你的项目文件、已安装工具) |\n| `coast exec dev-1 --service web` | 在解析后的内部服务容器中运行 `docker exec ... sh` | 某个特定的 compose 服务容器 |\n| `coast docker dev-1 ps` | 在 DinD 容器中运行 `docker ps` | 内部 Docker 守护进程(你的 compose 服务容器) |\n| `coast docker dev-1 compose logs web` | 在 DinD 容器中运行 `docker compose logs web` | 通过内部守护进程查看特定 compose 服务的日志 |\n\n项目级工作请使用 `coast exec` —— 例如运行测试、安装依赖、检查文件。当你需要查看内部 Docker 守护进程正在做什么时,请使用 `coast docker` —— 例如容器状态、镜像、网络、compose 操作。\n\n## Coastguard Exec 标签页\n\nCoastguard Web UI 提供了一个通过 WebSocket 连接的持久交互式终端。\n\n![Exec tab in Coastguard](../../assets/coastguard-exec.png)\n*Coastguard 的 Exec 标签页,显示了 Coast 实例内 `/workspace` 下的一个 shell 会话。*\n\n该终端基于 xterm.js,并提供:\n\n- **持久会话** —— 终端会话在页面跳转和浏览器刷新后依然保留。重新连接时会重放滚动缓冲区,因此你可以从上次离开的地方继续。\n- **多个标签页** —— 可同时打开多个 shell。每个标签页都是独立会话。\n- **[Agent shell](AGENT_SHELLS.md) 标签页** —— 为 AI 编码代理启动专用代理 shell,并跟踪其活动/非活动状态。\n- **全屏模式** —— 将终端扩展为全屏显示(按 Escape 退出)。\n\n除了实例级别的 exec 标签页外,Coastguard 还在其他层级提供终端访问:\n\n- **服务 exec** —— 在 Services 标签页中点击某个单独服务,即可进入该特定内部容器中的 shell(这会执行双重 `docker exec` —— 先进入 DinD 容器,再进入服务容器)。\n- **[共享服务](SHARED_SERVICES.md) exec** —— 进入宿主机级别共享服务容器中的 shell。\n- **宿主机终端** —— 直接在项目根目录打开宿主机 shell,完全无需进入 Coast。\n\n## 何时使用哪一个\n\n- **`coast exec`** —— 在 DinD 容器内运行项目级命令,或传入 `--service` 以在特定 compose 服务容器内打开 shell 或运行命令。\n- **`coast docker`** —— 检查或管理内部 Docker 守护进程(容器状态、镜像、网络、compose 操作)。\n- **Coastguard Exec 标签页** —— 适用于带持久会话、多标签页和 agent shell 支持的交互式调试。当你希望在浏览 UI 其余部分时保持多个终端开启,这通常是最佳选择。\n- **`coast logs`** —— 读取服务输出时,使用 `coast logs` 而不是 `coast docker compose logs`。参见 [Logs](LOGS.md)。\n- **`coast ps`** —— 检查服务状态时,使用 `coast ps` 而不是 `coast docker compose ps`。参见 [Runtimes and Services](RUNTIMES_AND_SERVICES.md)。\n", "concepts_and_terminology/FILESYSTEM.md": "# 文件系统\n\n你的主机与每个 Coast 实例共享同一份项目文件。主机项目根目录以读写方式挂载到 DinD 容器内的 `/host-project`,并且 Coast 将当前激活的工作树以 bind-mount 的方式挂载到 `/workspace`。这使得在主机上运行的代理可以编辑代码,而 Coast 内部的服务能够实时拾取变更。\n\n## 共享挂载\n\n```text\nHost machine\n│\n├── ~/dev/my-app/ (project root)\n│ ├── src/\n│ ├── Coastfile\n│ ├── docker-compose.yml\n│ └── .worktrees/ (worktrees, gitignored)\n│ ├── feature-auth/\n│ └── feature-billing/\n│\n└── Docker daemon (host)\n │\n └── Coast: dev-1 (docker:dind)\n │\n ├── /host-project ← Docker bind mount of project root (RW, fixed)\n │\n ├── /workspace ← mount --bind /host-project (switchable)\n │ ├── src/ same files, same bytes, instant sync\n │ ├── Coastfile\n │ └── docker-compose.yml\n │\n └── Inner Docker daemon\n └── web service\n └── /app ← compose bind mount from /workspace/src\n```\n\n当容器创建时,主机项目根目录会以读写方式挂载到 [DinD 容器](RUNTIMES_AND_SERVICES.md) 内的 `/host-project`。容器启动后,容器内会执行 `mount --bind /host-project /workspace` 来创建工作用的 `/workspace` 路径,并启用共享挂载传播(`mount --make-rshared`),因此将 `/workspace` 的子目录以 bind-mount 方式挂载的内部 compose 服务能够看到正确的内容。\n\n这种两阶段方案是有原因的:Docker 在 `/host-project` 的 bind mount 是在容器创建时固定的,不重建容器就无法更改。但容器内 Linux 的 `/workspace` bind mount 可以被卸载并重新绑定到不同的子目录——某个 worktree——而无需影响容器生命周期。这就是 `coast assign` 很快的原因。\n\n`/workspace` 是读写的。文件变更会立即双向同步。在主机上保存文件,Coast 内部的开发服务器会立刻拾取变更。在 Coast 内创建文件,它也会出现在主机上。\n\n## 主机代理与 Coast\n\n```text\n┌─── Host machine ──────────────────────────────────────────┐\n│ │\n│ AI Agent (Cursor, Claude Code, etc.) │\n│ │ │\n│ ├── reads/writes files at /src/ │\n│ │ ↕ (instant, same filesystem) │\n│ ├── coast logs dev-1 --service web --tail 50 │\n│ ├── coast ps dev-1 │\n│ └── coast exec dev-1 -- npm test │\n│ │\n├───────────────────────────────────────────────────────────┤\n│ │\n│ Coast: dev-1 │\n│ └── /workspace/src/ ← same bytes as host project/src │\n│ └── web service picks up changes on save │\n│ │\n└───────────────────────────────────────────────────────────┘\n```\n\n由于文件系统是共享的,在主机上运行的 AI 编码代理可以自由编辑文件,而 Coast 内运行的服务会立即看到变更。代理不需要在 Coast 容器内运行——它像平常一样在主机上操作即可。\n\n当代理需要运行时信息——日志、服务状态、测试输出——它会在主机上调用 Coast CLI 命令:\n\n- `coast logs dev-1 --service web --tail 50` 查看服务输出(参见 [日志](LOGS.md))\n- `coast ps dev-1` 查看服务状态(参见 [运行时与服务](RUNTIMES_AND_SERVICES.md))\n- `coast exec dev-1 -- npm test` 在 Coast 内运行命令(参见 [Exec & Docker](EXEC_AND_DOCKER.md))\n\n这就是根本性的架构优势:**代码编辑发生在主机上,运行时发生在 Coast 中,共享文件系统把两者桥接起来。** 主机代理从不需要“进入” Coast 就能完成工作。\n\n## Worktree 切换\n\n当 `coast assign` 将某个 Coast 切换到不同的 worktree 时,它会重新挂载 `/workspace`,使其指向该 git worktree,而不是项目根目录:\n\n```text\ncoast assign dev-1 --worktree feature-auth\n\nBefore: /workspace ←──mount── /host-project (project root)\nAfter: /workspace ←──mount── /host-project/.worktrees/feature-auth (worktree)\n```\n\nworktree 会在主机的 `{project_root}/.worktrees/{worktree_name}` 创建。`.worktrees` 目录名可通过 Coastfile 中的 `worktree_dir` 配置,并且应当加入你的 `.gitignore`。\n\n如果 worktree 是新的,Coast 会在重新挂载之前从项目根目录引导(bootstrap)所选的 gitignored 文件。它使用 `git ls-files --others --ignored --exclude-standard` 枚举被忽略的文件,过滤掉常见的大型目录以及任何已配置的 `exclude_paths`,然后使用带 `--link-dest` 的 `rsync --files-from` 将选中的文件以硬链接方式导入到 worktree。Coast 会在内部 worktree 元数据中记录这次引导,并在之后对同一 worktree 的 assign 中跳过该步骤,除非你显式使用 `coast assign --force-sync` 刷新它。\n\n在容器内,`/workspace` 会被 lazy-unmount,然后重新绑定到 `/host-project/.worktrees/{branch_name}` 下的 worktree 子目录。这个重新挂载很快——不会重建 DinD 容器,也不会重启内部 Docker daemon。在重新挂载之后,Compose 和裸服务仍可能被重建或重启,以便它们的 bind mount 能通过新的 `/workspace` 解析。\n\n像 `node_modules` 这样的大型依赖目录不属于这条通用的引导路径。它们通常会通过服务特定的缓存或卷来处理。\n\n如果你使用 `[assign.rebuild_triggers]`,Coast 还会在主机上运行 `git diff --name-only ..`,以决定标记为 `rebuild` 的服务是否可以降级为 `restart`。关于影响 assign 延迟的细节,参见 [Assign 与 Unassign](ASSIGN.md) 和 [性能优化](PERFORMANCE_OPTIMIZATIONS.md)。\n\n`coast unassign` 会将 `/workspace` 还原回 `/host-project`(项目根目录)。停止后执行 `coast start` 会根据实例是否已分配 worktree 来重新应用正确的挂载。\n\n## 所有挂载\n\n每个 Coast 容器都有这些挂载:\n\n| Path | Type | Access | Purpose |\n|---|---|---|---|\n| `/workspace` | bind mount (in-container) | RW | 项目根目录或 worktree。assign 时可切换。 |\n| `/host-project` | Docker bind mount | RW | 原始项目根目录。容器创建时固定。 |\n| `/image-cache` | Docker bind mount | RO | 来自 `~/.coast/image-cache/` 的预拉取 OCI tarball。 |\n| `/coast-artifact` | Docker bind mount | RO | 带有重写后的 compose 文件的构建产物。 |\n| `/coast-override` | Docker bind mount | RO | 为[共享服务](SHARED_SERVICES.md)生成的 compose override。 |\n| `/var/lib/docker` | Named volume | RW | 内部 Docker daemon 状态。跨容器移除持久化。 |\n\n只读挂载属于基础设施——它们承载 Coast 生成的构建产物、缓存镜像以及 compose override。你会通过 `coast build` 和 Coastfile 间接与它们交互。读写挂载则是你的代码所在之处,也是内部 daemon 存储其状态的位置。\n", "concepts_and_terminology/LOGS.md": "# 日志\n\nCoast 内部的服务运行在嵌套容器中——你的 compose 服务由一个 DinD 容器里的内部 Docker 守护进程管理。这意味着主机级的日志工具无法看到它们。如果你的工作流包含一个读取主机上 Docker 日志的日志 MCP,那么它只能看到外层的 DinD 容器,而看不到在其内部运行的 Web 服务器、数据库或 worker。\n\n解决方案是 `coast logs`。任何需要从 Coast 实例读取服务输出的 agent 或工具,都必须使用 Coast CLI,而不是主机级的 Docker 日志访问。\n\n## MCP 的取舍\n\n如果你正在使用带有日志 MCP 的 AI agent(一种从你的主机捕获 Docker 容器日志的工具——见 [MCP Servers](MCP_SERVERS.md)),那么该 MCP 对运行在 Coast 内部的服务将不起作用。主机 Docker 守护进程对每个 Coast 实例只看到一个容器——DinD 容器——其日志只是内部 Docker 守护进程的启动输出。\n\n要捕获真实的服务日志,请指示你的 agent 使用:\n\n```bash\ncoast logs --service --tail \n```\n\n例如,如果你的 agent 需要检查某个后端服务为何失败:\n\n```bash\ncoast logs dev-1 --service backend --tail 100\n```\n\n这等价于 `docker compose logs`,但会通过 Coast 守护进程路由到内部的 DinD 容器中。如果你有引用日志 MCP 的 agent 规则或系统提示词,那么在 Coast 内工作时,你需要添加一条指令来覆盖这种行为。\n\n## `coast logs`\n\nCLI 提供了多种方式来读取 Coast 实例的日志:\n\n```bash\ncoast logs dev-1 # last 200 lines, all services\ncoast logs dev-1 --service web # last 200 lines, web only\ncoast logs dev-1 --tail 50 # last 50 lines, then follow\ncoast logs dev-1 --tail # all lines, then follow\ncoast logs dev-1 --service backend -f # follow mode (stream new entries)\ncoast logs dev-1 --service web --tail 100 # last 100 lines + follow\n```\n\n在不使用 `--tail` 或 `-f` 的情况下,该命令返回最后 200 行并退出。使用 `--tail` 时,它会流式输出请求数量的行,然后继续实时跟随新的输出。`-f` / `--follow` 则单独启用跟随模式。\n\n输出使用 compose 的日志格式,每行带有服务前缀:\n\n```text\nweb | 2026/02/28 01:49:34 Listening on :3000\nbackend | 2026/02/28 01:49:34 [INFO] Server started on :8080\nbackend | 2026/02/28 01:49:34 [ProcessCreditsJob] starting at 2026-02-28T01:49:34Z\nredis | 1:M 28 Feb 2026 01:49:30.123 * Ready to accept connections\n```\n\n你也可以使用旧的按位置语法按服务过滤(`coast logs dev-1 web`),但更推荐使用 `--service` 标志。\n\n## Coastguard 日志选项卡\n\nCoastguard Web UI 通过 WebSocket 提供更丰富的日志查看体验,并支持实时流式输出。\n\n![Logs tab in Coastguard](../../assets/coastguard-logs.png)\n*Coastguard 日志选项卡正在流式显示后端服务输出,并支持服务过滤与搜索。*\n\n日志选项卡提供:\n\n- **实时流** — 日志通过 WebSocket 连接在产生时即到达,并带有状态指示器显示连接状态。\n- **服务过滤器** — 下拉列表由日志流的服务前缀填充。选择单个服务以聚焦其输出。\n- **搜索** — 按文本或正则过滤显示的行(切换星号按钮以启用正则模式)。匹配项会被高亮。\n- **行数统计** — 显示过滤后的行数与总行数(例如 “200 / 971 lines”)。\n- **清空** — 截断内部容器日志文件并重置查看器。\n- **全屏** — 将日志查看器扩展为全屏。\n\n日志行支持 ANSI 颜色渲染、日志级别高亮(ERROR 为红色、WARN 为琥珀色、INFO 为蓝色、DEBUG 为灰色)、时间戳淡化,以及用于区分服务的彩色服务徽标。\n\n在主机守护进程上运行的共享服务有其独立的日志查看器,可从 Shared Services 选项卡访问。详情见 [Shared Services](SHARED_SERVICES.md)。\n\n## 工作原理\n\n当你运行 `coast logs` 时,守护进程会通过 `docker exec` 在 DinD 容器内执行 `docker compose logs`,并将输出流式返回到你的终端(或通过 WebSocket 返回到 Coastguard UI)。\n\n```text\ncoast logs dev-1 --service web --tail 50\n │\n ├── CLI sends LogsRequest to daemon (Unix socket)\n │\n ├── Daemon resolves instance → container ID\n │\n ├── Daemon exec's into DinD container:\n │ docker compose logs --tail 50 --follow web\n │\n └── Output streams back chunk by chunk\n └── CLI prints to stdout / Coastguard renders in UI\n```\n\n对于 [bare services](BARE_SERVICES.md),守护进程会 tail `/var/log/coast-services/` 下的日志文件,而不是调用 `docker compose logs`。输出格式相同(`service | line`),因此在两种情况下服务过滤的工作方式完全一致。\n\n## 相关命令\n\n- `coast ps ` — 检查哪些服务正在运行及其状态。参见 [Runtimes and Services](RUNTIMES_AND_SERVICES.md)。\n- [`coast exec `](EXEC_AND_DOCKER.md) — 在 Coast 容器内打开一个 shell 以进行手动调试。\n", "concepts_and_terminology/LOOKUP.md": "# Lookup\n\n`coast lookup` 用于发现针对调用者当前工作目录正在运行的 Coast 实例。它是主机侧代理应当运行的第一条命令,用来完成定位——“我正在这里编辑代码,我应该与哪个/哪些 Coast 交互?”\n\n```bash\ncoast lookup\n```\n\nLookup 会检测你是否位于 [worktree](ASSIGN.md) 内或处于项目根目录,向守护进程查询匹配的实例,并打印包含端口、URL 以及示例命令的结果。\n\n## Why This Exists\n\n在主机上运行的 AI 编码代理(Cursor、Claude Code、Codex 等)通过 [shared filesystem](FILESYSTEM.md) 编辑文件,并调用 Coast CLI 命令来执行运行时操作。但代理首先需要回答一个基本问题:**与我正在工作的目录对应的是哪个 Coast 实例?**\n\n如果没有 `coast lookup`,代理就必须运行 `coast ls`,解析完整的实例表,弄清自己位于哪个 worktree 中,并进行交叉比对。`coast lookup` 将这些步骤一次完成,并返回代理可以直接消费的结构化输出。\n\n对于使用 Coast 的代理工作流,任何顶层的 SKILL.md、AGENTS.md 或规则文件都应当包含此命令。它是代理用于发现其运行时上下文的入口。\n\n## Output Modes\n\n### Default (human-readable)\n\n```bash\ncoast lookup\n```\n\n```text\nCoast instances for worktree feature/oauth (my-app):\n\n dev-1 running ★ checked out\n\n Primary URL: http://dev-1.localhost:62217\n\n SERVICE CANONICAL DYNAMIC\n ★ web 3000 62217\n api 8080 63889\n postgres 5432 55681\n\n Examples (exec starts at the workspace root where your Coastfile is, cd to your target directory first):\n coast exec dev-1 -- sh -c \"cd && \"\n coast logs dev-1 --service \n coast ps dev-1\n```\n\n示例部分会提醒代理(以及人类)`coast exec` 会从工作区根目录开始——也就是 Coastfile 所在的目录。要在子目录中运行命令,需要在 exec 内部先 `cd` 到该目录。\n\n### Compact (`--compact`)\n\n返回实例名称的 JSON 数组。为脚本和代理工具设计,它们只需要知道应当将哪些实例作为目标。\n\n```bash\ncoast lookup --compact\n```\n\n```text\n[\"dev-1\"]\n```\n\n同一 worktree 上的多个实例:\n\n```text\n[\"dev-1\",\"dev-2\"]\n```\n\n无匹配:\n\n```text\n[]\n```\n\n### JSON (`--json`)\n\n以美化打印的 JSON 形式返回完整的结构化响应。为需要以机器可读格式获取端口、URL 和状态的代理而设计。\n\n```bash\ncoast lookup --json\n```\n\n```json\n{\n \"project\": \"my-app\",\n \"worktree\": \"feature/oauth\",\n \"project_root\": \"/Users/dev/my-app\",\n \"instances\": [\n {\n \"name\": \"dev-1\",\n \"status\": \"Running\",\n \"checked_out\": true,\n \"branch\": \"feature/oauth\",\n \"primary_url\": \"http://dev-1.localhost:62217\",\n \"ports\": [\n { \"logical_name\": \"web\", \"canonical_port\": 3000, \"dynamic_port\": 62217, \"is_primary\": true },\n { \"logical_name\": \"api\", \"canonical_port\": 8080, \"dynamic_port\": 63889, \"is_primary\": false }\n ]\n }\n ]\n}\n```\n\n## How It Resolves\n\nLookup 会从当前工作目录向上查找最近的 Coastfile,然后确定你所在的 worktree:\n\n1. 如果你的 cwd 位于 `{project_root}/{worktree_dir}/{name}/...` 之下,lookup 会查找分配给该 worktree 的实例。\n2. 如果你的 cwd 是项目根目录(或任何不在 worktree 内的目录),lookup 会查找 **未分配 worktree** 的实例——也就是仍然指向项目根目录的那些实例。\n\n这意味着 lookup 也能从子目录正常工作。如果你在 `my-app/.worktrees/feature-oauth/src/api/` 中,lookup 仍会将 `feature-oauth` 解析为 worktree。\n\n## Exit Codes\n\n| Code | Meaning |\n|------|---------|\n| 0 | 找到一个或多个匹配实例 |\n| 1 | 没有匹配实例(结果为空) |\n\n这使得 lookup 可用于 shell 条件判断:\n\n```bash\nif coast lookup > /dev/null 2>&1; then\n coast exec dev-1 -- sh -c \"cd src && npm test\"\nfi\n```\n\n## For Agent Workflows\n\n典型的代理集成模式:\n\n1. 代理开始在某个 worktree 目录中工作。\n2. 代理运行 `coast lookup` 来发现实例名称、端口、URL 和示例命令。\n3. 代理在后续所有 Coast 命令中使用该实例名称:`coast exec`、`coast logs`、`coast ps`。\n\n```text\n┌─── Agent (host machine) ────────────────────────────┐\n│ │\n│ 1. coast lookup │\n│ → instance names, ports, URLs, examples │\n│ 2. coast exec dev-1 -- sh -c \"cd src && npm test\" │\n│ 3. coast logs dev-1 --service web --tail 50 │\n│ 4. coast ps dev-1 │\n│ │\n└──────────────────────────────────────────────────────┘\n```\n\n如果代理跨多个 worktree 工作,它会从每个 worktree 目录运行 `coast lookup`,以便为每种上下文解析正确的实例。\n\n另请参阅 [Filesystem](FILESYSTEM.md) 了解主机代理如何与 Coast 交互,参阅 [Assign and Unassign](ASSIGN.md) 了解 worktree 概念,并参阅 [Exec & Docker](EXEC_AND_DOCKER.md) 了解如何在 Coast 内部运行命令。\n", @@ -806,13 +811,20 @@ "concepts_and_terminology/SHARED_SERVICES.md": "# 共享服务\n\n共享服务是在你的主机 Docker 守护进程上运行的数据库和基础设施容器(Postgres、Redis、MongoDB 等),而不是在 Coast 内部运行。Coast 实例通过桥接网络连接到它们,因此每个 Coast 都会与同一主机卷上的同一服务通信。\n\n![Coastguard 中的共享服务](../../assets/coastguard-shared-services.png)\n*Coastguard 共享服务标签页,显示由主机管理的 Postgres、Redis 和 MongoDB。*\n\n## 工作原理\n\n当你在 Coastfile 中声明共享服务时,Coast 会在主机守护进程上启动它,并将其从每个 Coast 容器内部运行的 compose 栈中移除。随后会将 Coasts 配置为把服务名流量路由回共享容器,同时在 Coast 内保留该服务的容器侧端口。\n\n```text\nHost Docker daemon\n |\n +--> postgres (host volume: infra_postgres_data)\n +--> redis (host volume: infra_redis_data)\n +--> mongodb (host volume: infra_mongodb_data)\n |\n +--> Coast: dev-1 --bridge network--> host postgres, redis, mongodb\n +--> Coast: dev-2 --bridge network--> host postgres, redis, mongodb\n```\n\n由于共享服务会重用你现有的主机卷,因此你通过本地运行 `docker-compose up` 已经拥有的任何数据都可以立即供你的 Coasts 使用。\n\n当你使用映射端口时,这一区别尤为重要:\n\n```toml\n[shared_services.postgis]\nimage = \"ghcr.io/baosystems/postgis:12-3.3\"\nports = [\"5433:5432\"]\n```\n\n- 在主机上,共享服务发布在 `localhost:5433`。\n- 在每个 Coast 内部,应用容器仍然连接到 `postgis:5432`。\n- 像 `5432` 这样的裸整数是恒等映射 `\"5432:5432\"` 的简写。\n\n## 何时使用共享服务\n\n- 你的项目具有连接到本地数据库的 MCP 集成 —— 共享服务可让它们继续工作,而无需动态端口发现。如果你在主机上用工具已在使用的相同端口发布共享服务(例如 `ports = [5432]`),这些工具无需修改即可继续工作。如果你将其发布到不同的主机端口(例如 `\"5433:5432\"`),则主机侧工具应使用该主机端口,而 Coasts 继续使用容器端口。\n- 你希望 Coast 实例更轻量,因为它们不需要运行自己的数据库容器。\n- 你不需要 Coast 实例之间的数据隔离(每个实例看到的都是相同的数据)。\n- 你正在主机上运行编码代理(见 [Filesystem](FILESYSTEM.md)),并希望它们无需通过 [`coast exec`](EXEC_AND_DOCKER.md) 路由即可访问数据库状态。使用共享服务时,代理现有的数据库工具和 MCP 可保持不变地工作。\n\n如果你确实需要隔离,请参阅 [卷拓扑](VOLUMES.md) 页面了解替代方案。\n\n## 卷歧义警告\n\nDocker 卷名称并不总是在全局范围内唯一。如果你从多个不同项目运行 `docker-compose up`,Coast 附加到共享服务的主机卷可能不是你期望的那些。\n\n在使用共享服务启动 Coasts 之前,请确保你上一次运行的 `docker-compose up` 来自你打算与 Coasts 一起使用的项目。这样可以确保主机卷与你的 Coastfile 期望一致。\n\n## 故障排除\n\n如果你的共享服务似乎指向了错误的主机卷:\n\n1. 打开 [Coastguard](COASTGUARD.md) UI(`coast ui`)。\n2. 导航到 **Shared Services** 标签页。\n3. 选择受影响的服务并点击 **Remove**。\n4. 点击 **Refresh Shared Services** 以根据你当前的 Coastfile 配置重新创建它们。\n\n这会拆除并重新创建共享服务容器,并将它们重新附加到正确的主机卷。\n", "concepts_and_terminology/TROUBLESHOOTING.md": "# 故障排除\n\nCoasts 的大多数问题源于陈旧的状态、孤立的 Docker 资源,或守护进程不同步。本页涵盖从温和到核选项的升级处理路径。\n\n## Doctor\n\n如果感觉不对劲——实例显示为运行中但没有任何响应、端口似乎卡住、或 UI 显示过期数据——先从 `coast doctor` 开始:\n\n```bash\ncoast doctor\n```\n\nDoctor 会扫描状态数据库和 Docker 以查找不一致:容器缺失的孤立实例记录、没有状态记录的悬挂容器,以及被标记为运行但实际上已挂掉的共享服务。它会自动修复发现的问题。\n\n如需预览将执行的操作而不做任何更改:\n\n```bash\ncoast doctor --dry-run\n```\n\n## Daemon Restart\n\n如果守护进程本身似乎无响应,或你怀疑它处于不良状态,请重启它:\n\n```bash\ncoast daemon restart\n```\n\n这会发送优雅关闭信号,等待守护进程退出,并启动一个全新的进程。你的实例和状态会被保留。\n\n## Removing a Single Project\n\n如果问题仅限于某一个项目,你可以删除其构建产物及关联的 Docker 资源,而不影响其他任何内容:\n\n```bash\ncoast rm-build my-project\n```\n\n这会删除该项目的产物目录、Docker 镜像、卷以及容器。它会先请求确认。传入 `--force` 可跳过提示。\n\n## Missing Shared Service Images\n\n如果 `coast run` 在创建共享服务时失败,并出现类似 `No such image: postgres:15` 的错误,那么该镜像在你的宿主机 Docker 守护进程中缺失。\n\n这最常发生在你的 `Coastfile` 定义了诸如 Postgres 或 Redis 的 `shared_services`,但 Docker 尚未拉取这些镜像时。\n\n拉取缺失的镜像,然后再次运行该实例:\n\n```bash\ndocker pull postgres:15\ndocker pull redis:7\ncoast run my-instance\n```\n\n如果你不确定缺的是哪个镜像,失败的 `coast run` 输出会在 Docker 错误中包含镜像名称。一次失败的置备尝试之后,Coasts 会自动清理部分创建的实例,因此看到实例回到 `stopped` 属于预期行为。\n\n## Factory Reset with Nuke\n\n当其他方法都无效——或者你只是想要一个完全干净的环境——`coast nuke` 会执行完整的出厂重置:\n\n```bash\ncoast nuke\n```\n\n这将会:\n\n1. 停止 `coastd` 守护进程。\n2. 移除 **所有** 由 coast 管理的 Docker 容器。\n3. 移除 **所有** 由 coast 管理的 Docker 卷。\n4. 移除 **所有** 由 coast 管理的 Docker 网络。\n5. 移除 **所有** coast Docker 镜像。\n6. 删除整个 `~/.coast/` 目录(状态数据库、构建、日志、密钥、镜像缓存)。\n7. 重新创建 `~/.coast/` 并重启守护进程,使 coast 能立即再次使用。\n\n由于这会销毁一切,你必须在确认提示中输入 `nuke`:\n\n```text\n$ coast nuke\nWARNING: This will permanently destroy ALL coast data:\n\n - Stop the coastd daemon\n - Remove all coast-managed Docker containers\n - Remove all coast-managed Docker volumes\n - Remove all coast-managed Docker networks\n - Remove all coast Docker images\n - Delete ~/.coast/ (state DB, builds, logs, secrets, image cache)\n\nType \"nuke\" to confirm:\n```\n\n传入 `--force` 可跳过提示(在脚本中很有用):\n\n```bash\ncoast nuke --force\n```\n\nnuke 之后,coast 已准备好使用——守护进程在运行,且主目录已存在。你只需要再次对项目执行 `coast build` 和 `coast run`。\n\n## Reporting Bugs\n\n如果你遇到的问题无法通过以上任何方法解决,请在报告时附上守护进程日志:\n\n```bash\ncoast daemon logs\n```\n", "concepts_and_terminology/VOLUMES.md": "# 卷拓扑\n\nCoast 提供三种卷策略,用于控制数据密集型服务(数据库、缓存等)如何在各个 Coast 实例之间存储和共享其数据。选择合适的策略取决于你需要多少隔离性,以及你能容忍多少开销。\n\n## 共享服务\n\n[共享服务](SHARED_SERVICES.md) 运行在你的主机 Docker 守护进程上,在任何 Coast 容器之外。像 Postgres、MongoDB 和 Redis 这样的服务会留在主机上,Coast 实例通过桥接网络将调用路由回主机。\n\n```text\nHost machine\n |\n +--> Postgres (host daemon, existing volume)\n +--> Redis (host daemon, existing volume)\n |\n +--> Coast: dev-1 --connects to--> host Postgres, host Redis\n +--> Coast: dev-2 --connects to--> host Postgres, host Redis\n```\n\n实例之间没有数据隔离——每个 Coast 都在与同一个数据库通信。作为回报,你将获得:\n\n- 更轻量的 Coast 实例,因为它们不运行自己的数据库容器。\n- 直接复用你现有的主机卷,因此你已有的任何数据都能立即可用。\n- 连接到本地数据库的 MCP 集成开箱即用,继续正常工作。\n\n这在你的 [Coastfile](COASTFILE_TYPES.md) 中通过 `[shared_services]` 配置。\n\n## 共享卷\n\n共享卷会挂载一个在所有 Coast 实例之间共享的单个 Docker 卷。服务本身(Postgres、Redis 等)在每个 Coast 容器内运行,但它们都会对同一个底层卷进行读写。\n\n```text\nCoast: dev-1 --mounts--> shared volume \"my-project-postgres\"\nCoast: dev-2 --mounts--> shared volume \"my-project-postgres\"\n```\n\n这会将你的 Coast 数据与主机上的内容隔离开来,但实例之间仍然共享数据。当你希望与主机开发环境彻底分离,同时又不想承担为每个实例创建独立卷的开销时,这会很有用。\n\n```toml\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## 隔离卷\n\n隔离卷会为每个 Coast 实例提供其各自独立的卷。实例之间以及与主机之间都不共享任何数据。每个实例都从空开始(或从快照开始——见下文),并各自独立地演进。\n\n```text\nCoast: dev-1 --mounts--> volume \"dev-1-postgres\"\nCoast: dev-2 --mounts--> volume \"dev-2-postgres\"\n```\n\n对于集成测试密集、需要在并行环境之间实现真正卷隔离的项目来说,这是最佳选择。代价是启动更慢、Coast 构建更大,因为每个实例都维护自己的一份数据副本。\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## 快照\n\n共享与隔离两种策略默认都从空卷开始。如果你希望实例以现有主机卷的副本作为起点,将 `snapshot_source` 设置为要从中复制的 Docker 卷名称:\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n快照会在[构建时](BUILDS.md)获取。创建之后,每个实例的卷会各自独立地分叉——更改不会回传到源卷,也不会传播到其他实例。\n\nCoast 尚不支持运行时快照(例如,从正在运行的实例对卷进行快照)。这计划在未来版本中提供。\n", - "harnesses/README.md": "# Harnesses\n\n每种 harness 都会在不同的位置创建 git worktree。在 Coasts 中,\n[`worktree_dir`](../coastfiles/WORKTREE_DIR.md) 数组会告诉它去哪里查找——\n包括像 `~/.codex/worktrees` 这样需要额外 bind mount 的外部路径。\n\n每种 harness 对项目级说明、skills 和 commands 也都有各自的约定。下方矩阵展示了每种 harness 支持哪些内容,以便你知道应将 Coasts 的指引放在哪里。每个页面都会介绍该 harness 的 Coastfile 配置、推荐的文件布局,以及任何特定注意事项。\n\n如果同一个仓库会被多个 harness 使用,请参阅 [Multiple Harnesses](MULTIPLE_HARNESSES.md)。\n\n| Harness | Worktree location | Project instructions | Skills | Commands | Page |\n|---------|-------------------|----------------------|--------|----------|------|\n| OpenAI Codex | `~/.codex/worktrees` | `AGENTS.md` | `.agents/skills/` | Skills 会显示为 `/` commands | [Codex](CODEX.md) |\n| Claude Code | `.claude/worktrees` | `CLAUDE.md` | `.claude/skills/` | `.claude/commands/` | [Claude Code](CLAUDE_CODE.md) |\n| Cursor | `~/.cursor/worktrees/` | `AGENTS.md` 或 `.cursor/rules/` | `.cursor/skills/` 或 `.agents/skills/` | `.cursor/commands/` | [Cursor](CURSOR.md) |\n| Conductor | `~/conductor/workspaces/` | `CLAUDE.md` | -- | -- | [Conductor](CONDUCTOR.md) |\n| T3 Code | `~/.t3/worktrees/` | `AGENTS.md` | `.agents/skills/` | -- | [T3 Code](T3_CODE.md) |\n\n## Skills vs Commands\n\nSkills 和 commands 都可以让你定义可复用的 `/coasts` 工作流。你可以根据 harness 的支持情况使用其中一种,或者两者都用。\n\n如果你的 harness 支持 commands,并且你想要一个明确的 `/coasts`\n入口,一个简单的做法是添加一个复用该 skill 的 command。\nCommands 需要通过名称显式调用,因此你可以准确知道\n`/coasts` 工作流会在什么时候运行。Skills 也可以由代理根据上下文自动加载,\n这很有用,但也意味着你对这些说明何时被引入的控制会更少。\n\n你也可以两者一起使用。如果这样做,应让 command 复用 skill,而不是\n单独维护一份工作流副本。\n\n如果该 harness 只支持 skills(T3 Code),就使用 skill。如果它两者都不支持\n(Conductor),就把 `/coasts` 工作流直接放进项目说明文件中。\n", - "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) 会在项目内的 `.claude/worktrees/` 中创建\nworktree。由于该目录位于仓库内部,Coasts 可以发现并分配 Claude Code worktree,\n而无需任何外部绑定挂载。\n\nClaude Code 也是这里的 harness,并且对 Coasts 的三层结构划分最清晰:\n\n- `CLAUDE.md` 用于与 Coasts 配合工作的简短、始终启用的规则\n- `.claude/skills/coasts/SKILL.md` 用于可复用的 `/coasts` 工作流\n- `.claude/commands/coasts.md` 仅在你希望将命令文件作为额外入口点时使用\n\n## Setup\n\n将 `.claude/worktrees` 添加到 `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n由于 `.claude/worktrees` 是相对于项目的路径,因此不需要外部绑定挂载。\n\n## Where Coasts guidance goes\n\n### `CLAUDE.md`\n\n将应在每个任务中生效的 Coasts 规则放在这里。保持简短且可操作:\n\n- 在会话中第一次运行时命令之前先运行 `coast lookup`\n- 对测试、构建和服务命令使用 `coast exec`\n- 使用 `coast ps` 和 `coast logs` 获取运行时反馈\n- 当没有匹配项时,在创建或重新分配 Coast 之前先询问\n\n### `.claude/skills/coasts/SKILL.md`\n\n将可复用的 `/coasts` 工作流放在这里。这是以下流程的正确归属位置:\n\n1. 运行 `coast lookup` 并复用匹配的 Coast\n2. 在没有匹配项时回退到 `coast ls`\n3. 提供 `coast run`、`coast assign`、`coast unassign`、`coast checkout` 和\n `coast ui`\n4. 直接使用 Coast CLI 作为约定,而不是对其进行包装\n\n如果此仓库也使用 Codex、T3 Code 或 Cursor,请参见\n[Multiple Harnesses](MULTIPLE_HARNESSES.md),并将规范技能保存在\n`.agents/skills/coasts/` 中,然后将其暴露给 Claude Code。\n\n### `.claude/commands/coasts.md`\n\nClaude Code 还支持项目命令文件。对于 Coasts 文档,请将其视为可选项:\n\n- 仅当你明确希望使用命令文件时才使用它\n- 一个简单的做法是让命令复用同一个技能\n- 如果你为该命令提供自己独立的说明,就等于要维护第二份工作流副本\n\n## Example layout\n\n### Claude Code only\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\n如果此仓库也使用 Codex、T3 Code 或 Cursor,请改用\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) 中的共享模式,而不是在这里重复,\n因为每增加一个 harness,重复的特定提供方指导就会更难保持同步。\n\n## What Coasts does\n\n- **Run** — `coast run ` 从最新构建创建一个新的 Coast 实例。使用 `coast run -w ` 可一步创建并分配 Claude Code worktree。参见 [Run](../concepts_and_terminology/RUN.md)。\n- **Discovery** — Coasts 会像读取任何其他本地 worktree 目录一样读取 `.claude/worktrees`。\n- **Naming** — Claude Code worktree 在 Coasts UI 和 CLI 中遵循与其他仓库内 worktree 相同的本地 worktree 命名行为。\n- **Assign** — `coast assign` 可以将 `/workspace` 切换到 Claude Code worktree,而无需任何外部绑定挂载间接层。\n- **Gitignored sync** — 由于 worktree 位于仓库树内,因此可正常工作。\n- **Orphan detection** — 如果 Claude Code 删除了某个 worktree,Coasts 可以检测到缺失的 gitdir,并在需要时取消其分配。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code worktree\n- `~/.codex/worktrees/` — 如果你也在此仓库中使用 Codex,则为 Codex worktree\n\n## Limitations\n\n- 如果你在 `CLAUDE.md`、`.claude/skills` 和 `.claude/commands` 中重复相同的 `/coasts` 工作流,\n 这些副本会逐渐偏离。请保持 `CLAUDE.md` 简短,并将可复用工作流保留在一个技能中。\n- 如果你希望一个仓库能在多个 harness 中良好工作,请优先采用\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) 中的共享模式。\n", - "harnesses/CODEX.md": "# Codex\n\n[Codex](https://developers.openai.com/codex/app/worktrees/) 会在 `$CODEX_HOME/worktrees`(通常是 `~/.codex/worktrees`)创建 worktree。每个 worktree 都位于一个不透明的哈希目录下,例如 `~/.codex/worktrees/a0db/project-name`,以 detached HEAD 状态开始,并会根据 Codex 的保留策略自动清理。\n\n摘自 [Codex docs](https://developers.openai.com/codex/app/worktrees/):\n\n> 我可以控制 worktree 的创建位置吗?\n> 目前不可以。Codex 会在 `$CODEX_HOME/worktrees` 下创建 worktree,以便能够一致地管理它们。\n\n由于这些 worktree 位于项目根目录之外,Coasts 需要显式\n配置才能发现并挂载它们。\n\n## Setup\n\n将 `~/.codex/worktrees` 添加到 `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nCoasts 会在运行时展开 `~`,并将任何以 `~/` 或 `/` 开头的路径视为\n外部路径。详情请参见 [Worktree Directories](../coastfiles/WORKTREE_DIR.md)。\n\n更改 `worktree_dir` 后,必须**重新创建**现有实例,才能使 bind mount 生效:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree 列表会立即更新(Coasts 会读取新的 Coastfile),但\n要分配到 Codex worktree,则需要容器内存在 bind mount。\n\n## Where Coasts guidance goes\n\n在使用 Coasts 时,请使用 Codex 的项目说明文件和共享 skill 布局:\n\n- 将简短的 Coast Runtime 规则放在 `AGENTS.md` 中\n- 将可复用的 `/coasts` 工作流放在 `.agents/skills/coasts/SKILL.md` 中\n- Codex 会将该 skill 暴露为 `/coasts` 命令\n- 如果你使用 Codex 专用元数据,请将其与 skill 一起放在\n `.agents/skills/coasts/agents/openai.yaml`\n- 不要仅仅为了编写关于 Coasts 的文档而创建单独的项目命令文件;该\n skill 就是可复用的入口\n- 如果此仓库也使用 Cursor 或 Claude Code,请将规范的 skill 保存在\n `.agents/skills/` 中,并从那里进行暴露。参见\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) 和\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)。\n\n例如,一个最小化的 `.agents/skills/coasts/agents/openai.yaml` 可以\n像这样:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\n这样可以让该 skill 在 Codex 中以更友好的标签显示,并使 `/coasts` 成为\n显式命令。只有当该 skill 还需要 MCP 服务器或其他由 OpenAI 管理的工具\n接线时,才添加 `dependencies.tools`。\n\n## What Coasts does\n\n- **Run** -- `coast run ` 会基于最新构建创建一个新的 Coast 实例。使用 `coast run -w ` 可以一步完成 Codex worktree 的创建和分配。参见 [Run](../concepts_and_terminology/RUN.md)。\n- **Bind mount** -- 在创建容器时,Coasts 会将\n `~/.codex/worktrees` 挂载到容器中的 `/host-external-wt/{index}`。\n- **Discovery** -- `git worktree list --porcelain` 的作用域是仓库级别,因此即使该目录包含许多项目的 worktree,也只会显示属于当前项目的 Codex worktree。\n- **Naming** -- detached HEAD worktree 会显示为其在外部目录中的相对路径(`a0db/my-app`、`eca7/my-app`)。基于分支的 worktree 会显示分支名称。\n- **Assign** -- `coast assign` 会从外部 bind mount 路径重新挂载 `/workspace`。\n- **Gitignored sync** -- 在主机文件系统上使用绝对路径运行,无需 bind mount 也可工作。\n- **Orphan detection** -- git watcher 会递归扫描外部目录,\n 并通过 `.git` gitdir 指针进行过滤。如果 Codex 删除了某个\n worktree,Coasts 会自动取消该实例的分配。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code(本地,无需特殊处理)\n- `~/.codex/worktrees/` -- Codex(外部,使用 bind mount 挂载)\n\n## Limitations\n\n- Codex 可能随时清理 worktree。Coasts 中的 orphan detection\n 可以妥善处理这种情况。\n", - "harnesses/CONDUCTOR.md": "# Conductor\n\n[Conductor](https://conductor.build/) 运行并行的 Claude Code 代理,每个代理都在其各自隔离的工作区中。工作区是存储在 `~/conductor/workspaces//` 的 git worktree。每个工作区都会检出到一个命名分支上。\n\n由于这些 worktree 位于项目根目录之外,Coasts 需要显式配置才能发现并挂载它们。\n\n## 设置\n\n将 `~/conductor/workspaces/` 添加到 `worktree_dir`。与 Codex(它将所有项目存储在一个扁平目录下)不同,Conductor 将 worktree 嵌套在按项目划分的子目录中,因此路径必须包含项目名称。在下面的示例中,`my-app` 必须与你的仓库在 `~/conductor/workspaces/` 下的实际文件夹名称一致。\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nConductor 允许你为每个仓库配置工作区路径,因此默认的 `~/conductor/workspaces` 可能与你的设置不一致。请检查你的 Conductor 仓库设置以找到实际路径,并相应调整——无论目录位于何处,原理都是一样的。\n\nCoasts 在运行时展开 `~`,并将任何以 `~/` 或 `/` 开头的路径视为外部路径。详见 [Worktree Directories](../coastfiles/WORKTREE_DIR.md)。\n\n更改 `worktree_dir` 后,必须**重新创建**现有实例,绑定挂载才能生效:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree 列表会立即更新(Coasts 会读取新的 Coastfile),但分配到 Conductor worktree 需要容器内存在绑定挂载。\n\n## Coasts 指南应放在哪里\n\n将 Conductor 视为一个使用 Coasts 的独立 harness:\n\n- 将简短的 Coast Runtime 规则放在 `CLAUDE.md`\n- 对于实际上特定于 Conductor 的设置或运行行为,使用 Conductor Repository Settings 脚本\n- 不要在这里假定存在完整的 Claude Code 项目命令或项目 skill 行为\n- 如果你添加了一个命令但它没有出现,请在再次测试前彻底关闭并重新打开 Conductor\n- 如果此仓库还使用其他 harness,请参见\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) 和\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md),了解如何将共享的\n `/coasts` 工作流保存在一个地方\n\n## Coasts 会做什么\n\n- **运行** — `coast run ` 会基于最新构建创建一个新的 Coast 实例。使用 `coast run -w ` 可一步完成 Conductor worktree 的创建和分配。详见 [Run](../concepts_and_terminology/RUN.md)。\n- **绑定挂载** — 在容器创建时,Coasts 会将\n `~/conductor/workspaces/` 挂载到容器中的\n `/host-external-wt/{index}`。\n- **发现** — `git worktree list --porcelain` 的作用域是仓库级别,因此只会显示属于当前项目的 worktree。\n- **命名** — Conductor worktree 使用命名分支,因此它们会在 Coasts UI 和 CLI 中以分支名显示(例如,`scroll-to-bottom-btn`)。一个分支在同一时间只能在一个 Conductor 工作区中被检出。\n- **分配** — `coast assign` 会从外部绑定挂载路径重新挂载 `/workspace`。\n- **Gitignored 同步** — 在主机文件系统上使用绝对路径运行,无需绑定挂载即可工作。\n- **孤儿检测** — git 监视器会递归扫描外部目录,并通过 `.git` gitdir 指针进行过滤。如果 Conductor 归档或删除某个工作区,Coasts 会自动取消该实例的分配。\n\n## 示例\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor(外部,绑定挂载;将 `my-app` 替换为你的仓库文件夹名称)\n\n## Conductor Env Vars\n\n- 避免依赖 Conductor 特有的环境变量(例如,\n `CONDUCTOR_PORT`、`CONDUCTOR_WORKSPACE_PATH`)来进行 Coasts 内部的运行时配置。Coasts 会独立管理端口、工作区路径和服务发现——请改用 Coastfile `[ports]` 和 `coast exec`。\n", - "harnesses/CURSOR.md": "# Cursor\n\n[Cursor](https://cursor.com/docs/agent/overview) 可以直接在你当前的 checkout 中工作,它的 Parallel Agents 功能也可以在 `~/.cursor/worktrees//` 下创建 git worktree。\n\n对于 Coasts 的文档来说,这意味着有两种设置情况:\n\n- 如果你只是在当前 checkout 中使用 Cursor,则不需要特定于 Cursor 的 `worktree_dir` 条目\n- 如果你使用 Cursor Parallel Agents,请将 Cursor 的 worktree 目录添加到 `worktree_dir`,以便 Coasts 可以发现并分配这些 worktree\n\n## 设置\n\n### 仅当前 checkout\n\n如果 Cursor 只是在编辑你已经打开的 checkout,Coasts 不需要任何特定于 Cursor 的特殊 worktree 路径。Coasts 会像对待任何其他本地仓库根目录一样对待该 checkout。\n\n### Cursor Parallel Agents\n\n如果你使用 Parallel Agents,请将 `~/.cursor/worktrees/` 添加到 `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nCursor 会将每个 agent 的 worktree 存储在该项目专属目录下。Coasts 会在运行时展开 `~` 并将该路径视为外部路径,因此必须重新创建现有实例,才能使 bind mount 生效:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\n在修改 Coastfile 后,worktree 列表会立即更新,但要分配到 Cursor Parallel Agent worktree,则需要容器内的外部 bind mount。\n\n## Coasts 指南应放置的位置\n\n### `AGENTS.md` 或 `.cursor/rules/coast.md`\n\n将简短、始终启用的 Coast Runtime 规则放在这里:\n\n- 如果你希望项目说明具有最高可移植性,请使用 `AGENTS.md`\n- 如果你希望使用 Cursor 原生项目规则和 settings UI 支持,请使用 `.cursor/rules/coast.md`\n- 除非你有明确的理由,否则不要在两者中重复相同的 Coast Runtime 区块\n\n### `.cursor/skills/coasts/SKILL.md` 或共享的 `.agents/skills/coasts/SKILL.md`\n\n将可复用的 `/coasts` 工作流放在这里:\n\n- 对于仅使用 Cursor 的仓库,`.cursor/skills/coasts/SKILL.md` 是一个自然的放置位置\n- 对于多 harness 仓库,请将规范技能保存在 `.agents/skills/coasts/SKILL.md` 中;Cursor 可以直接加载它\n- 该 skill 应该拥有真实的 `/coasts` 工作流:`coast lookup`、`coast ls`、`coast run`、`coast assign`、`coast unassign`、`coast checkout` 和 `coast ui`\n\n### `.cursor/commands/coasts.md`\n\nCursor 也支持项目命令。对于 Coasts 的文档,请将命令视为可选项:\n\n- 仅当你想要一个显式的 `/coasts` 入口点时才添加命令\n- 一个简单的选择是让该命令复用同一个 skill\n- 如果你给该命令提供它自己独立的说明,那么你就需要维护第二份工作流副本\n\n### `.cursor/worktrees.json`\n\n将 `.cursor/worktrees.json` 用于 Cursor 自身的 worktree 引导,而不是用于 Coasts 策略:\n\n- 安装依赖\n- 复制或创建 `.env` 文件的符号链接\n- 运行数据库迁移或其他一次性引导步骤\n\n不要将 Coast Runtime 规则或 Coast CLI 工作流移入 `.cursor/worktrees.json`。\n\n## 示例布局\n\n### 仅 Cursor\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # 可选\n.cursor/rules/coast.md # AGENTS.md 的可选替代方案\n.cursor/worktrees.json # 可选,用于 Parallel Agents 引导\n```\n\n### Cursor 加其他 harness\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # 可选\n```\n\n## Coasts 的作用\n\n- **运行** — `coast run ` 从最新构建创建一个新的 Coast 实例。使用 `coast run -w ` 可以一步完成创建并分配一个 Cursor worktree。参见 [Run](../concepts_and_terminology/RUN.md)。\n- **当前 checkout** — 当 Cursor 直接在你打开的仓库中工作时,不需要任何特殊的 Cursor 处理。\n- **Bind mount** — 对于 Parallel Agents,Coasts 会将 `~/.cursor/worktrees/` 挂载到容器中的 `/host-external-wt/{index}`。\n- **发现** — `git worktree list --porcelain` 仍然是仓库作用域的,因此 Coasts 只会显示属于当前项目的 Cursor worktree。\n- **命名** — Cursor Parallel Agent worktree 会以它们的分支名称显示在 Coasts 的 CLI 和 UI 中。\n- **分配** — 当选择 Cursor worktree 时,`coast assign` 会从外部 bind mount 路径重新挂载 `/workspace`。\n- **Gitignored 同步** — 继续在主机文件系统上通过绝对路径工作。\n- **孤儿检测** — 如果 Cursor 清理了旧 worktree,Coasts 可以检测到缺失的 gitdir,并在需要时取消分配它们。\n\n## 示例\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code worktree\n- `~/.codex/worktrees/` — Codex worktree\n- `~/.cursor/worktrees/my-app/` — Cursor Parallel Agent worktree\n\n## 限制\n\n- 如果你没有使用 Cursor Parallel Agents,请不要仅仅因为你恰好在 Cursor 中编辑,就添加 `~/.cursor/worktrees/`。\n- 将 Coast Runtime 规则保存在一个始终启用的位置:`AGENTS.md` 或 `.cursor/rules/coast.md`。同时重复两者会导致内容漂移。\n- 将可复用的 `/coasts` 工作流保存在 skill 中。`.cursor/worktrees.json` 用于 Cursor 引导,而不是 Coasts 策略。\n- 如果一个仓库会在 Cursor、Codex、Claude Code 或 T3 Code 之间共享,优先使用 [Multiple Harnesses](MULTIPLE_HARNESSES.md) 中的共享布局。\n", + "harnesses/README.md": "# Harnesses\n\n每种 harness 都会在不同的位置创建 git worktree。在 Coasts 中,\n[`worktree_dir`](../coastfiles/WORKTREE_DIR.md) 数组会告诉它去哪里查找——\n包括像 `~/.codex/worktrees` 这样需要额外 bind mount 的外部路径。\n\n每种 harness 对项目级说明、skills 和 commands 也都有各自的约定。下方矩阵展示了每种 harness 支持哪些内容,以便你知道应将 Coasts 的指引放在哪里。每个页面都会介绍该 harness 的 Coastfile 配置、推荐的文件布局,以及任何特定注意事项。\n\n如果同一个仓库会被多个 harness 使用,请参阅 [Multiple Harnesses](MULTIPLE_HARNESSES.md)。\n\n| Harness | Worktree location | Project instructions | Skills | Commands | Page |\n|---------|-------------------|----------------------|--------|----------|------|\n| OpenAI Codex | `~/.codex/worktrees` | `AGENTS.md` | `.agents/skills/` | Skills 会显示为 `/` commands | [Codex](CODEX.md) |\n| Claude Code | `.claude/worktrees` | `CLAUDE.md` | `.claude/skills/` | `.claude/commands/` | [Claude Code](CLAUDE_CODE.md) |\n| Cursor | `~/.cursor/worktrees/` | `AGENTS.md` 或 `.cursor/rules/` | `.cursor/skills/` 或 `.agents/skills/` | `.cursor/commands/` | [Cursor](CURSOR.md) |\n| Conductor | `~/conductor/workspaces/` | `CLAUDE.md` | -- | -- | [Conductor](CONDUCTOR.md) |\n| T3 Code | `~/.t3/worktrees/` | `AGENTS.md` | `.agents/skills/` | -- | [T3 Code](T3_CODE.md) |\n| Shep | `~/.shep/repos/*/wt` | `CLAUDE.md` | `.agents/skills/` 或 `.claude/skills/` | -- | [Shep](SHEP.md) |\n\n## Skills vs Commands\n\nSkills 和 commands 都可以让你定义可复用的 `/coasts` 工作流。你可以根据 harness 的支持情况使用其中一种,或者两者都用。\n\n如果你的 harness 支持 commands,并且你想要一个明确的 `/coasts`\n入口,一个简单的做法是添加一个复用该 skill 的 command。\nCommands 需要通过名称显式调用,因此你可以准确知道\n`/coasts` 工作流会在什么时候运行。Skills 也可以由代理根据上下文自动加载,\n这很有用,但也意味着你对这些说明何时被引入的控制会更少。\n\n你也可以两者一起使用。如果这样做,应让 command 复用 skill,而不是\n单独维护一份工作流副本。\n\n如果该 harness 只支持 skills(T3 Code),就使用 skill。如果它两者都不支持\n(Conductor),就把 `/coasts` 工作流直接放进项目说明文件中。\n", + "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n## Quick setup\n\n需要 [Coast CLI](../GETTING_STARTED.md)。将此提示复制到你的\nagent 聊天中,以自动设置 Coasts:\n\n```prompt-copy\nclaude_code_setup_prompt.txt\n```\n\n你也可以从 CLI 获取技能内容:`coast skills-prompt`。\n\n设置完成后,**启动一个新的 Claude Code 会话** —— 技能和 `CLAUDE.md` 的更改\n会在会话开始时加载。\n\n---\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) 会在项目内的 `.claude/worktrees/` 中创建\nworktree。由于该目录位于仓库内部,Coasts 可以发现并分配 Claude Code worktree,\n而无需任何外部绑定挂载。\n\nClaude Code 也是这里的 harness,并且对 Coasts 的三层结构划分最清晰:\n\n- `CLAUDE.md` 用于与 Coasts 配合工作的简短、始终启用的规则\n- `.claude/skills/coasts/SKILL.md` 用于可复用的 `/coasts` 工作流\n- `.claude/commands/coasts.md` 仅在你希望将命令文件作为额外入口点时使用\n\n## Setup\n\n将 `.claude/worktrees` 添加到 `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n由于 `.claude/worktrees` 是相对于项目的路径,因此不需要外部绑定挂载。\n\n## Where Coasts guidance goes\n\n### `CLAUDE.md`\n\n将应在每个任务中生效的 Coasts 规则放在这里。保持简短且可操作:\n\n- 在会话中第一次运行时命令之前先运行 `coast lookup`\n- 对测试、构建和服务命令使用 `coast exec`\n- 使用 `coast ps` 和 `coast logs` 获取运行时反馈\n- 当没有匹配项时,在创建或重新分配 Coast 之前先询问\n\n### `.claude/skills/coasts/SKILL.md`\n\n将可复用的 `/coasts` 工作流放在这里。这是以下流程的正确归属位置:\n\n1. 运行 `coast lookup` 并复用匹配的 Coast\n2. 在没有匹配项时回退到 `coast ls`\n3. 提供 `coast run`、`coast assign`、`coast unassign`、`coast checkout` 和\n `coast ui`\n4. 直接使用 Coast CLI 作为约定,而不是对其进行包装\n\n如果此仓库也使用 Codex、T3 Code 或 Cursor,请参见\n[Multiple Harnesses](MULTIPLE_HARNESSES.md),并将规范技能保存在\n`.agents/skills/coasts/` 中,然后将其暴露给 Claude Code。\n\n### `.claude/commands/coasts.md`\n\nClaude Code 还支持项目命令文件。对于 Coasts 文档,请将其视为可选项:\n\n- 仅当你明确希望使用命令文件时才使用它\n- 一个简单的做法是让命令复用同一个技能\n- 如果你为该命令提供自己独立的说明,就等于要维护第二份工作流副本\n\n## Example layout\n\n### Claude Code only\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\n如果此仓库也使用 Codex、T3 Code 或 Cursor,请改用\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) 中的共享模式,而不是在这里重复,\n因为每增加一个 harness,重复的特定提供方指导就会更难保持同步。\n\n## What Coasts does\n\n- **Run** — `coast run ` 从最新构建创建一个新的 Coast 实例。使用 `coast run -w ` 可一步创建并分配 Claude Code worktree。参见 [Run](../concepts_and_terminology/RUN.md)。\n- **Discovery** — Coasts 会像读取任何其他本地 worktree 目录一样读取 `.claude/worktrees`。\n- **Naming** — Claude Code worktree 在 Coasts UI 和 CLI 中遵循与其他仓库内 worktree 相同的本地 worktree 命名行为。\n- **Assign** — `coast assign` 可以将 `/workspace` 切换到 Claude Code worktree,而无需任何外部 bind-mount 间接层。\n- **Gitignored sync** — 由于 worktree 位于仓库树内,因此可正常工作。\n- **Orphan detection** — 如果 Claude Code 删除了某个 worktree,Coasts 可以检测到缺失的 gitdir,并在需要时取消其分配。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code worktree\n- `~/.codex/worktrees/` — 如果你也在此仓库中使用 Codex,则为 Codex worktree\n\n## Limitations\n\n- 如果你在 `CLAUDE.md`、`.claude/skills` 和 `.claude/commands` 中重复相同的 `/coasts` 工作流,\n 这些副本会逐渐偏离。请保持 `CLAUDE.md` 简短,并将可复用工作流保留在一个技能中。\n- 如果你希望一个仓库能在多个 harness 中良好工作,请优先采用\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) 中的共享模式。\n", + "harnesses/CODEX.md": "# Codex\n\n## Quick setup\n\n需要 [Coast CLI](../GETTING_STARTED.md)。将此提示复制到你的\nagent 聊天中,以自动设置 Coasts:\n\n```prompt-copy\ncodex_setup_prompt.txt\n```\n\n你也可以从 CLI 获取 skill 内容:`coast skills-prompt`。\n\n设置完成后,**退出并重新打开 Codex**,以使新的 skill 和 `AGENTS.md`\n生效。\n\n---\n\n[Codex](https://developers.openai.com/codex/app/worktrees/) 会在 `$CODEX_HOME/worktrees`(通常是 `~/.codex/worktrees`)创建 worktree。每个 worktree 都位于一个不透明的哈希目录下,例如 `~/.codex/worktrees/a0db/project-name`,以 detached HEAD 状态开始,并会根据 Codex 的保留策略自动清理。\n\n摘自 [Codex docs](https://developers.openai.com/codex/app/worktrees/):\n\n> 我可以控制 worktree 的创建位置吗?\n> 目前不可以。Codex 会在 `$CODEX_HOME/worktrees` 下创建 worktree,以便能够一致地管理它们。\n\n由于这些 worktree 位于项目根目录之外,Coasts 需要显式\n配置才能发现并挂载它们。\n\n## Setup\n\n将 `~/.codex/worktrees` 添加到 `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nCoasts 会在运行时展开 `~`,并将任何以 `~/` 或 `/` 开头的路径视为\n外部路径。详情请参见 [Worktree Directories](../coastfiles/WORKTREE_DIR.md)。\n\n更改 `worktree_dir` 后,必须**重新创建**现有实例,才能使 bind mount 生效:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree 列表会立即更新(Coasts 会读取新的 Coastfile),但\n要分配到 Codex worktree,则需要容器内存在 bind mount。\n\n## Where Coasts guidance goes\n\n在使用 Coasts 时,请使用 Codex 的项目说明文件和共享 skill 布局:\n\n- 将简短的 Coast Runtime 规则放在 `AGENTS.md` 中\n- 将可复用的 `/coasts` 工作流放在 `.agents/skills/coasts/SKILL.md` 中\n- Codex 会将该 skill 暴露为 `/coasts` 命令\n- 如果你使用 Codex 专用元数据,请将其与 skill 一起放在\n `.agents/skills/coasts/agents/openai.yaml`\n- 不要仅仅为了编写关于 Coasts 的文档而创建单独的项目命令文件;该\n skill 就是可复用的入口\n- 如果此仓库也使用 Cursor 或 Claude Code,请将规范的 skill 保存在\n `.agents/skills/` 中,并从那里进行暴露。参见\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) 和\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)。\n\n例如,一个最小化的 `.agents/skills/coasts/agents/openai.yaml` 可以\n像这样:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\n这样可以让该 skill 在 Codex 中以更友好的标签显示,并使 `/coasts` 成为\n显式命令。只有当该 skill 还需要 MCP 服务器或其他由 OpenAI 管理的工具\n接线时,才添加 `dependencies.tools`。\n\n## What Coasts does\n\n- **Run** -- `coast run ` 会基于最新构建创建一个新的 Coast 实例。使用 `coast run -w ` 可以一步完成 Codex worktree 的创建和分配。参见 [Run](../concepts_and_terminology/RUN.md)。\n- **Bind mount** -- 在创建容器时,Coasts 会将\n `~/.codex/worktrees` 挂载到容器中的 `/host-external-wt/{index}`。\n- **Discovery** -- `git worktree list --porcelain` 的作用域是仓库级别,因此即使该目录包含许多项目的 worktree,也只会显示属于当前项目的 Codex worktree。\n- **Naming** -- detached HEAD worktree 会显示为其在外部目录中的相对路径(`a0db/my-app`、`eca7/my-app`)。基于分支的 worktree 会显示分支名称。\n- **Assign** -- `coast assign` 会从外部 bind mount 路径重新挂载 `/workspace`。\n- **Gitignored sync** -- 在主机文件系统上使用绝对路径运行,无需 bind mount 也可工作。\n- **Orphan detection** -- git watcher 会递归扫描外部目录,\n 并通过 `.git` gitdir 指针进行过滤。如果 Codex 删除了某个\n worktree,Coasts 会自动取消该实例的分配。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code(本地,无需特殊处理)\n- `~/.codex/worktrees/` -- Codex(外部,使用 bind mount 挂载)\n\n## Limitations\n\n- Codex 可能随时清理 worktree。Coasts 中的 orphan detection\n 可以妥善处理这种情况。\n", + "harnesses/CONDUCTOR.md": "# Conductor\n\n## 快速设置\n\n需要 [Coast CLI](../GETTING_STARTED.md)。将此提示复制到你的\n代理聊天中,以自动设置 Coasts:\n\n```prompt-copy\nconductor_setup_prompt.txt\n```\n\n你也可以通过 CLI 获取 skill 内容:`coast skills-prompt`。\n\n> **重要:** Conductor 会在隔离的 git worktree 中运行每个会话。该\n> 设置提示会创建仅存在于当前工作区中的文件——请将它们提交并合并到你的主分支,\n> 否则它们在新会话中将不可用。\n\n设置完成后,**彻底关闭并重新打开 Conductor** 以使更改生效。如果\n`/coasts` 命令没有出现,请再次关闭并重新打开。\n\n## 设置\n\n将 `~/conductor/workspaces/` 添加到 `worktree_dir`。与 Codex(它将所有项目存储在一个扁平目录下)不同,Conductor 将 worktree 嵌套在按项目划分的子目录中,因此路径必须包含项目名称。在下面的示例中,`my-app` 必须与你的仓库在 `~/conductor/workspaces/` 下的实际文件夹名称一致。\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nConductor 允许你为每个仓库配置工作区路径,因此默认的 `~/conductor/workspaces` 可能与你的设置不一致。请检查你的 Conductor 仓库设置以找到实际路径,并相应调整——无论目录位于何处,原理都是一样的。\n\nCoasts 在运行时展开 `~`,并将任何以 `~/` 或 `/` 开头的路径视为外部路径。详见 [Worktree Directories](../coastfiles/WORKTREE_DIR.md)。\n\n更改 `worktree_dir` 后,必须**重新创建**现有实例,绑定挂载才能生效:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree 列表会立即更新(Coasts 会读取新的 Coastfile),但分配到 Conductor worktree 需要容器内存在绑定挂载。\n\n## Coasts 指南应放在哪里\n\n将 Conductor 视为一个使用 Coasts 的独立 harness:\n\n- 将简短的 Coast Runtime 规则放在 `CLAUDE.md`\n- 对于实际上特定于 Conductor 的设置或运行行为,使用 Conductor Repository Settings 脚本\n- 不要在这里假定存在完整的 Claude Code 项目命令或项目 skill 行为\n- 如果你添加了一个命令但它没有出现,请在再次测试前彻底关闭并重新打开 Conductor\n- 如果此仓库还使用其他 harness,请参见\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) 和\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md),了解如何将共享的\n `/coasts` 工作流保存在一个地方\n\n## Coasts 会做什么\n\n- **运行** — `coast run ` 会基于最新构建创建一个新的 Coast 实例。使用 `coast run -w ` 可一步完成 Conductor worktree 的创建和分配。详见 [Run](../concepts_and_terminology/RUN.md)。\n- **绑定挂载** — 在容器创建时,Coasts 会将\n `~/conductor/workspaces/` 挂载到容器中的\n `/host-external-wt/{index}`。\n- **发现** — `git worktree list --porcelain` 的作用域是仓库级别,因此只会显示属于当前项目的 worktree。\n- **命名** — Conductor worktree 使用命名分支,因此它们会在 Coasts UI 和 CLI 中以分支名显示(例如,`scroll-to-bottom-btn`)。一个分支在同一时间只能在一个 Conductor 工作区中被检出。\n- **分配** — `coast assign` 会从外部绑定挂载路径重新挂载 `/workspace`。\n- **Gitignored 同步** — 在主机文件系统上使用绝对路径运行,无需绑定挂载即可工作。\n- **孤儿检测** — git 监视器会递归扫描外部目录,并通过 `.git` gitdir 指针进行过滤。如果 Conductor 归档或删除某个工作区,Coasts 会自动取消该实例的分配。\n\n## 示例\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor(外部,绑定挂载;将 `my-app` 替换为你的仓库文件夹名称)\n\n## Conductor Env Vars\n\n- 避免依赖 Conductor 特有的环境变量(例如,\n `CONDUCTOR_PORT`、`CONDUCTOR_WORKSPACE_PATH`)来进行 Coasts 内部的运行时配置。Coasts 会独立管理端口、工作区路径和服务发现——请改用 Coastfile `[ports]` 和 `coast exec`。\n", + "harnesses/CURSOR.md": "# Cursor\n\n## 快速设置\n\n需要 [Coast CLI](../GETTING_STARTED.md)。将此提示复制到你的\nagent 聊天中,以自动设置 Coasts:\n\n```prompt-copy\ncursor_setup_prompt.txt\n```\n\n你也可以从 CLI 获取 skill 内容:`coast skills-prompt`。\n\n设置完成后,**重启 Cursor** 以使 skill 和规则更改生效。\n\n---\n\n[Cursor](https://cursor.com/docs/agent/overview) 可以直接在你当前的\ncheckout 中工作,它的 Parallel Agents 功能也可以在 `~/.cursor/worktrees//` 下创建 git\nworktree。\n\n对于 Coasts 的文档来说,这意味着有两种设置情况:\n\n- 如果你只是在当前 checkout 中使用 Cursor,则不需要特定于 Cursor 的\n `worktree_dir` 条目\n- 如果你使用 Cursor Parallel Agents,请将 Cursor 的 worktree 目录添加到\n `worktree_dir`,以便 Coasts 可以发现并分配这些 worktree\n\n## 设置\n\n### 仅当前 checkout\n\n如果 Cursor 只是在编辑你已经打开的 checkout,Coasts 不需要任何特殊的、\n特定于 Cursor 的 worktree 路径。Coasts 会像对待任何其他本地仓库根目录一样对待该 checkout。\n\n### Cursor Parallel Agents\n\n如果你使用 Parallel Agents,请将 `~/.cursor/worktrees/` 添加到\n`worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nCursor 会将每个 agent 的 worktree 存储在该项目专属目录下。Coasts 会在运行时展开 `~` 并将该路径视为外部路径,因此必须重新创建现有实例,才能使 bind mount 生效:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\n在修改 Coastfile 后,worktree 列表会立即更新,但要分配到 Cursor Parallel Agent worktree,则需要容器内的外部 bind mount。\n\n## Coasts 指南应放置的位置\n\n### `AGENTS.md` 或 `.cursor/rules/coast.md`\n\n将简短、始终启用的 Coast Runtime 规则放在这里:\n\n- 如果你希望项目说明具有最高可移植性,请使用 `AGENTS.md`\n- 如果你希望使用 Cursor 原生项目规则和 settings UI 支持,请使用 `.cursor/rules/coast.md`\n- 除非你有明确的理由,否则不要在两者中重复相同的 Coast Runtime 区块\n\n### `.cursor/skills/coasts/SKILL.md` 或共享的 `.agents/skills/coasts/SKILL.md`\n\n将可复用的 `/coasts` 工作流放在这里:\n\n- 对于仅使用 Cursor 的仓库,`.cursor/skills/coasts/SKILL.md` 是一个自然的放置位置\n- 对于多 harness 仓库,请将规范 skill 保存在\n `.agents/skills/coasts/SKILL.md` 中;Cursor 可以直接加载它\n- 该 skill 应该拥有真实的 `/coasts` 工作流:`coast lookup`、\n `coast ls`、`coast run`、`coast assign`、`coast unassign`、\n `coast checkout` 和 `coast ui`\n\n### `.cursor/commands/coasts.md`\n\nCursor 也支持项目命令。对于 Coasts 的文档,请将命令视为可选项:\n\n- 仅当你想要一个显式的 `/coasts` 入口点时才添加命令\n- 一个简单的选择是让该命令复用同一个 skill\n- 如果你给该命令提供它自己独立的说明,那么你就需要维护第二份工作流副本\n\n### `.cursor/worktrees.json`\n\n将 `.cursor/worktrees.json` 用于 Cursor 自身的 worktree 引导,而不是用于 Coasts\n策略:\n\n- 安装依赖\n- 复制或创建 `.env` 文件的符号链接\n- 运行数据库迁移或其他一次性引导步骤\n\n不要将 Coast Runtime 规则或 Coast CLI 工作流移入\n`.cursor/worktrees.json`。\n\n## 示例布局\n\n### 仅 Cursor\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # 可选\n.cursor/rules/coast.md # AGENTS.md 的可选替代方案\n.cursor/worktrees.json # 可选,用于 Parallel Agents 引导\n```\n\n### Cursor 加其他 harness\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # 可选\n```\n\n## Coasts 的作用\n\n- **运行** — `coast run ` 从最新构建创建一个新的 Coast 实例。使用 `coast run -w ` 可以一步完成创建并分配一个 Cursor worktree。参见 [Run](../concepts_and_terminology/RUN.md)。\n- **当前 checkout** — 当 Cursor 直接在你打开的仓库中工作时,不需要任何特殊的 Cursor 处理。\n- **Bind mount** — 对于 Parallel Agents,Coasts 会将\n `~/.cursor/worktrees/` 挂载到容器中的\n `/host-external-wt/{index}`。\n- **发现** — `git worktree list --porcelain` 仍然是仓库作用域的,因此 Coasts\n 只会显示属于当前项目的 Cursor worktree。\n- **命名** — Cursor Parallel Agent worktree 会以它们的分支名称显示在\n Coasts 的 CLI 和 UI 中。\n- **分配** — 当选择 Cursor worktree 时,`coast assign` 会从外部 bind\n mount 路径重新挂载 `/workspace`。\n- **Gitignored 同步** — 继续在主机文件系统上通过绝对路径工作。\n- **孤儿检测** — 如果 Cursor 清理了旧 worktree,Coasts 可以检测到缺失的 gitdir,并在需要时取消分配它们。\n\n## 示例\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code worktree\n- `~/.codex/worktrees/` — Codex worktree\n- `~/.cursor/worktrees/my-app/` — Cursor Parallel Agent worktree\n\n## 限制\n\n- 如果你没有使用 Cursor Parallel Agents,请不要仅仅因为你恰好在 Cursor 中编辑,就添加 `~/.cursor/worktrees/`。\n- 将 Coast Runtime 规则保存在一个始终启用的位置:`AGENTS.md` 或\n `.cursor/rules/coast.md`。同时重复两者会导致内容漂移。\n- 将可复用的 `/coasts` 工作流保存在 skill 中。`.cursor/worktrees.json` 用于 Cursor 引导,而不是 Coasts 策略。\n- 如果一个仓库会在 Cursor、Codex、Claude Code 或 T3 Code 之间共享,优先使用 [Multiple Harnesses](MULTIPLE_HARNESSES.md) 中的共享布局。\n", "harnesses/MULTIPLE_HARNESSES.md": "# 多个 Harness\n\n如果一个仓库会被多个 harness 使用,整合 Coasts 设置的一种方式是将共享的 `/coasts` 工作流保存在一个位置,并将各个 harness 特定的常驻规则保存在对应 harness 的文件中。\n\n## 推荐布局\n\n```text\nAGENTS.md\nCLAUDE.md\n.cursor/rules/coast.md # optional Cursor-native always-on rules\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional, thin, harness-specific\n.claude/commands/coasts.md # optional, thin, harness-specific\n```\n\n按如下方式使用此布局:\n\n- `AGENTS.md` — 在 Codex 和 T3\n Code 中使用 Coasts 的简短常驻规则\n- `.cursor/rules/coast.md` — 可选的 Cursor 原生常驻规则\n- `CLAUDE.md` — 在 Claude Code\n 和 Conductor 中使用 Coasts 的简短常驻规则\n- `.agents/skills/coasts/SKILL.md` — 规范的可复用 `/coasts` 工作流\n- `.agents/skills/coasts/agents/openai.yaml` — 可选的 Codex/OpenAI 元数据\n- `.claude/skills/coasts` — 面向 Claude 的镜像或符号链接,当 Claude Code\n 也需要相同 skill 时使用\n- `.cursor/commands/coasts.md` — 可选的 Cursor 命令文件;一个简单的\n 选项是让它复用同一个 skill\n- `.claude/commands/coasts.md` — 可选的显式命令文件;一个简单的\n 选项是让它复用同一个 skill\n\n## 分步说明\n\n1. 将 Coast Runtime 规则放入常驻指令文件中。\n - `AGENTS.md`、`CLAUDE.md` 或 `.cursor/rules/coast.md` 应回答\n “每个任务”规则:先运行 `coast lookup`,使用 `coast exec`,通过 `coast logs`\n 读取日志,在没有匹配项时于执行 `coast assign` 或 `coast run` 前先询问。\n2. 为 Coasts 创建一个规范 skill。\n - 将可复用的 `/coasts` 工作流放入 `.agents/skills/coasts/SKILL.md`。\n - 在该 skill 中直接使用 Coast CLI:`coast lookup`,\n `coast ls`、`coast run`、`coast assign`、`coast unassign`、\n `coast checkout` 和 `coast ui`。\n3. 仅在 harness 需要不同路径时暴露该 skill。\n - Codex、T3 Code 和 Cursor 都可以直接使用 `.agents/skills/`。\n - Claude Code 需要 `.claude/skills/`,因此请将该规范\n skill 镜像或符号链接到该位置。\n4. 仅当你想要一个显式的 `/coasts` 入口点时才添加命令文件。\n - 如果你创建 `.claude/commands/coasts.md` 或\n `.cursor/commands/coasts.md`,一个简单的选项是让该命令\n 复用同一个 skill。\n - 如果你给该命令提供自己独立的说明,那么你就需要维护\n 该工作流的第二份副本。\n5. 将 Conductor 特定设置保留在 Conductor 中,而不是放在 skill 中。\n - 对于属于 Conductor 本身的引导或运行行为,请使用 Conductor Repository Settings 脚本。\n - 将 Coasts 策略以及 `coast` CLI 的使用保留在 `CLAUDE.md` 和共享 skill 中。\n\n## 具体的 `/coasts` 示例\n\n一个好的共享 `coasts` skill 应完成三项工作:\n\n1. `Use Existing Coast`\n - 运行 `coast lookup`\n - 如果存在匹配项,则使用 `coast exec`、`coast ps` 和 `coast logs`\n2. `Manage Assignment`\n - 运行 `coast ls`\n - 提供 `coast run`、`coast assign`、`coast unassign` 或\n `coast checkout`\n - 在复用或干扰现有槽位之前先询问\n3. `Open UI`\n - 运行 `coast ui`\n\n这才是 `/coasts` 工作流应放置的正确位置。常驻文件应\n只保存那些即使从未调用该 skill 也必须适用的简短规则。\n\n## 符号链接模式\n\n如果你希望 Claude Code 复用与 Codex、T3 Code 或 Cursor 相同的 skill,\n一种选择是使用符号链接:\n\n```bash\nmkdir -p .claude/skills\nln -s ../../.agents/skills/coasts .claude/skills/coasts\n```\n\n如果你的团队不想使用符号链接,提交一个镜像副本也完全可以。主要目标只是避免副本之间出现不必要的偏差。\n\n## 各 harness 的注意事项\n\n- Claude Code:项目 skills 和可选项目命令都有效,但\n 请将逻辑保留在 skill 中。\n- Cursor:使用 `AGENTS.md` 或 `.cursor/rules/coast.md` 放置简短的 Coast\n Runtime 规则,使用 skill 存放可复用工作流,并将\n `.cursor/commands` 保持为可选。\n- Conductor:首先将其视为 `CLAUDE.md` 加 Conductor 脚本和设置。\n 如果你添加了命令但它没有出现,请先完全关闭并重新打开应用,\n 然后再检查一次。\n- T3 Code:这是这里最轻量的 harness 表面。使用 Codex 风格的\n `AGENTS.md` 加 `.agents/skills` 模式,不要为关于 Coasts 的文档\n 另行发明单独的 T3 专用命令布局。\n- Codex:保持 `AGENTS.md` 简短,并将可复用工作流放入\n `.agents/skills`。\n", - "harnesses/T3_CODE.md": "# T3 Code\n\n[T3 Code](https://github.com/pingdotgg/t3code) 会在\n`~/.t3/worktrees//` 创建 git worktree,并检出到命名分支上。\n\n在 T3 Code 中,将始终开启的 Coast Runtime 规则放在 `AGENTS.md` 中,并将可复用的 `/coasts` 工作流放在 `.agents/skills/coasts/SKILL.md` 中。\n\n由于这些 worktree 位于项目根目录之外,Coasts 需要显式配置才能发现并挂载它们。\n\n## Setup\n\n将 `~/.t3/worktrees/` 添加到 `worktree_dir`。T3 Code 会将 worktree 嵌套在每个项目对应的子目录下,因此该路径必须包含项目名称。在下面的示例中,`my-app` 必须与您的仓库在 `~/.t3/worktrees/` 下的实际文件夹名称一致。\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nCoasts 会在运行时展开 `~`,并将任何以 `~/` 或 `/` 开头的路径视为外部路径。详情请参见 [Worktree Directories](../coastfiles/WORKTREE_DIR.md)。\n\n更改 `worktree_dir` 后,现有实例必须被**重新创建**,绑定挂载才能生效:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree 列表会立即更新(Coasts 会读取新的 Coastfile),但分配到 T3 Code worktree 需要容器内存在该绑定挂载。\n\n## Where Coasts guidance goes\n\n对于 T3 Code,请使用以下布局:\n\n- 将简短的 Coast Runtime 规则放在 `AGENTS.md` 中\n- 将可复用的 `/coasts` 工作流放在 `.agents/skills/coasts/SKILL.md` 中\n- 不要为 Coasts 额外添加单独的 T3 专用项目命令或斜杠命令层\n- 如果此仓库使用多个 harness,请参阅\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) 和\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)。\n\n## What Coasts does\n\n- **Run** — `coast run ` 会基于最新构建创建一个新的 Coast 实例。使用 `coast run -w ` 可一步完成创建并分配 T3 Code worktree。参见 [Run](../concepts_and_terminology/RUN.md)。\n- **Bind mount** — 在容器创建时,Coasts 会将\n `~/.t3/worktrees/` 挂载到容器中的\n `/host-external-wt/{index}`。\n- **Discovery** — `git worktree list --porcelain` 的作用域是仓库级别,因此只会显示属于当前项目的 worktree。\n- **Naming** — T3 Code worktree 使用命名分支,因此它们会在 Coasts UI 和 CLI 中以分支名显示。\n- **Assign** — `coast assign` 会从外部绑定挂载路径重新挂载 `/workspace`。\n- **Gitignored sync** — 在主机文件系统上使用绝对路径运行,无需绑定挂载即可工作。\n- **Orphan detection** — git watcher 会递归扫描外部目录,并通过 `.git` gitdir 指针进行过滤。如果 T3 Code 删除了某个工作区,Coasts 会自动取消该实例的分配。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code(本地,无需特殊处理)\n- `~/.codex/worktrees/` — Codex(外部,绑定挂载)\n- `~/.t3/worktrees/my-app/` — T3 Code(外部,绑定挂载;请将 `my-app` 替换为您的仓库文件夹名称)\n\n## Limitations\n\n- 避免依赖 T3 Code 特定的环境变量来进行 Coasts 内部的运行时配置。Coasts 会独立管理端口、工作区路径和服务发现——请改用 Coastfile `[ports]` 和 `coast exec`。\n", + "harnesses/SHEP.md": "# Shep\n\n## 快速设置\n\n需要 [Coast CLI](../GETTING_STARTED.md)。将此提示复制到你的\n代理聊天中,以自动设置 Coasts:\n\n```prompt-copy\nshep_setup_prompt.txt\n```\n\n你也可以从 CLI 获取技能内容:`coast skills-prompt`。\n\n设置完成后,**退出并重新打开你的编辑器**,以使新技能和项目\n说明生效。\n\n---\n\n[Shep](https://shep-ai.github.io/cli/) 会在 `~/.shep/repos/{hash}/wt/{branch-slug}` 创建工作树。该 hash 是仓库绝对路径的 SHA-256 的前 16 个十六进制字符,因此它对每个仓库都是确定的,但不透明。给定仓库的所有工作树共享相同的 hash,并通过 `wt/{branch-slug}` 子目录进行区分。\n\n在 Shep CLI 中,`shep feat show ` 会打印工作树路径,或者\n`ls ~/.shep/repos` 会列出每个仓库对应的 hash 目录。\n\n由于每个仓库的 hash 都不同,Coasts 使用 **glob 模式** 来发现\nshep 工作树,而不需要用户将 hash 硬编码。\n\n## 设置\n\n将 `~/.shep/repos/*/wt` 添加到 `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n`*` 匹配每个仓库对应的 hash 目录。运行时 Coasts 会展开该 glob,\n找到匹配的目录(例如 `~/.shep/repos/a21f0cda9ab9d456/wt`),并\n将其绑定挂载到容器中。有关 glob\n模式的完整细节,请参阅\n[工作树目录](../coastfiles/WORKTREE_DIR.md)。\n\n更改 `worktree_dir` 后,必须**重新创建**现有实例,绑定挂载才会生效:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\n工作树列表会立即更新(Coasts 会读取新的 Coastfile),但\n分配到 Shep 工作树需要容器内存在该绑定挂载。\n\n## Coasts 指导内容放在哪里\n\nShep 底层封装了 Claude Code,因此请遵循 Claude Code 的约定:\n\n- 将简短的 Coast Runtime 规则放在 `CLAUDE.md`\n- 将可复用的 `/coasts` 工作流放在 `.claude/skills/coasts/SKILL.md` 或\n 共享的 `.agents/skills/coasts/SKILL.md`\n- 如果此仓库还使用其他 harness,请参阅\n [多个 Harness](MULTIPLE_HARNESSES.md) 和\n [宿主代理的 Skills](../SKILLS_FOR_HOST_AGENTS.md)\n\n## Coasts 的作用\n\n- **运行** -- `coast run ` 从最新构建创建一个新的 Coast 实例。使用 `coast run -w ` 可一步创建并分配一个 Shep 工作树。参见 [运行](../concepts_and_terminology/RUN.md)。\n- **绑定挂载** -- 在容器创建时,Coasts 会解析 glob\n `~/.shep/repos/*/wt`,并将每个匹配的目录挂载到容器中的\n `/host-external-wt/{index}`。\n- **发现** -- `git worktree list --porcelain` 的作用域是仓库级别,因此只有\n 属于当前项目的工作树会显示出来。\n- **命名** -- Shep 工作树使用命名分支,因此它们会在 Coasts UI 和 CLI 中按分支\n 名显示(例如,`feat-green-background`)。\n- **分配** -- `coast assign` 会从外部绑定挂载路径重新挂载 `/workspace`。\n- **Gitignored 同步** -- 在宿主文件系统上使用绝对路径运行,无需绑定挂载即可工作。\n- **孤儿检测** -- git 监视器会递归扫描外部目录,\n 并通过 `.git` gitdir 指针进行过滤。如果 Shep 删除了某个\n 工作树,Coasts 会自动取消分配该实例。\n\n## 示例\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/.shep/repos/*/wt` -- Shep(外部,通过 glob 展开进行绑定挂载)\n\n## Shep 路径结构\n\n```\n~/.shep/repos/\n {sha256-of-repo-path-first-16-chars}/\n wt/\n {branch-slug}/ <-- git worktree\n {branch-slug}/\n```\n\n关键点:\n- 相同仓库 = 每次都是相同的 hash(确定性,不是随机)\n- 不同仓库 = 不同的 hashes\n- 路径分隔符在哈希之前会规范化为 `/`\n- 可通过 `shep feat show ` 或 `ls ~/.shep/repos` 找到该 hash\n", + "harnesses/T3_CODE.md": "# T3 Code\n\n## Quick setup\n\n需要 [Coast CLI](../GETTING_STARTED.md)。将以下提示复制到你的\nagent 聊天中,以自动设置 Coasts:\n\n```prompt-copy\nt3_code_setup_prompt.txt\n```\n\n你也可以通过 CLI 获取技能内容:`coast skills-prompt`。\n\n设置完成后,**重启 T3 Code** 以使技能和规则更改生效。\n\n**注意:** T3 Code 可能尚未从 `.agents/skills/` 或\n`.claude/skills/` 加载项目级技能。该设置提示还会将技能放置到\n`~/.codex/skills/coasts/` 中,以便它可供 Codex provider 全局使用。\n`AGENTS.md` 和 `CLAUDE.md` 中的 Coast Runtime 规则仍会在每个\n任务中照常生效。\n\n---\n\n[T3 Code](https://github.com/pingdotgg/t3code) 会在\n`~/.t3/worktrees//` 创建 git worktree,并检出到命名分支上。\n\nT3 Code 封装了 Codex,因此它使用 `AGENTS.md` 存放始终启用的规则,并使用\n`.agents/skills/coasts/SKILL.md` 存放可复用的 `/coasts` 工作流。\n\n由于这些 worktree 位于项目根目录之外,Coasts 需要显式配置才能发现并挂载它们。\n\n## Setup\n\n将 `~/.t3/worktrees/` 添加到 `worktree_dir`。T3 Code 会将 worktree 嵌套在每个项目对应的子目录下,因此该路径必须包含项目名称。在下面的示例中,`my-app` 必须与您的仓库在 `~/.t3/worktrees/` 下的实际文件夹名称一致。\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nCoasts 会在运行时展开 `~`,并将任何以 `~/` 或 `/` 开头的路径视为外部路径。详情请参见 [Worktree Directories](../coastfiles/WORKTREE_DIR.md)。\n\n更改 `worktree_dir` 后,现有实例必须被**重新创建**,绑定挂载才能生效:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree 列表会立即更新(Coasts 会读取新的 Coastfile),但分配到 T3 Code worktree 需要容器内存在该绑定挂载。\n\n## Where Coasts guidance goes\n\n对于 T3 Code,请使用以下布局:\n\n- 将简短的 Coast Runtime 规则放在 `AGENTS.md` 中\n- 将可复用的 `/coasts` 工作流放在 `.agents/skills/coasts/SKILL.md` 中\n- 不要为 Coasts 额外添加单独的 T3 专用项目命令或斜杠命令层\n- 如果此仓库使用多个 harness,请参阅\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) 和\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)。\n\n## What Coasts does\n\n- **Run** — `coast run ` 会基于最新构建创建一个新的 Coast 实例。使用 `coast run -w ` 可一步完成创建并分配 T3 Code worktree。参见 [Run](../concepts_and_terminology/RUN.md)。\n- **Bind mount** — 在容器创建时,Coasts 会将\n `~/.t3/worktrees/` 挂载到容器中的\n `/host-external-wt/{index}`。\n- **Discovery** — `git worktree list --porcelain` 的作用域是仓库级别,因此只会显示属于当前项目的 worktree。\n- **Naming** — T3 Code worktree 使用命名分支,因此它们会在 Coasts UI 和 CLI 中以分支名显示。\n- **Assign** — `coast assign` 会从外部绑定挂载路径重新挂载 `/workspace`。\n- **Gitignored sync** — 在主机文件系统上使用绝对路径运行,无需绑定挂载即可工作。\n- **Orphan detection** — git watcher 会递归扫描外部目录,并通过 `.git` gitdir 指针进行过滤。如果 T3 Code 删除了某个工作区,Coasts 会自动取消该实例的分配。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code(本地,无需特殊处理)\n- `~/.codex/worktrees/` — Codex(外部,绑定挂载)\n- `~/.t3/worktrees/my-app/` — T3 Code(外部,绑定挂载;请将 `my-app` 替换为您的仓库文件夹名称)\n\n## Limitations\n\n- 避免依赖 T3 Code 特定的环境变量来进行 Coasts 内部的运行时配置。Coasts 会独立管理端口、工作区路径和服务发现——请改用 Coastfile `[ports]` 和 `coast exec`。\n", + "harnesses/claude_code_setup_prompt.txt": "你正在为此项目中的 Claude Code 设置 Coasts 技能。从项目根目录运行所有\n命令。\n\n## 步骤 1:检查 Coast CLI\n\n运行此命令:\n\n coast --version\n\n如果找不到 `coast` 命令,请在此停止并告诉用户:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\n在 CLI 可用之前,不要继续。\n\n## 步骤 2:获取技能内容\n\n运行此命令:\n\n coast skills-prompt\n\n输出包含两部分:\n\n- **Coast Runtime 规则** — 从开始到以 `---` 开头的那一行之前(但不包括该行)的所有内容\n- **Coasts 技能** — 从 `---` frontmatter 块开始的所有内容(包括 `---` 行及其后的所有内容)\n\n保存这两部分内容,以供下面的步骤使用。\n\n## 步骤 3:询问用户\n\n询问用户:我应该将其设置为**全局**(此机器上的每个项目都可用)还是**仅用于此项目**?\n\n## 步骤 4:放置文件\n\n如果目标文件已存在,请追加 Coast Runtime 部分而不是覆盖——但首先检查是否已存在 `# Coast Runtime` 部分,如果存在则跳过。\n\n**全局设置:**\n- 将 Coast Runtime 规则追加到 `~/.claude/CLAUDE.md`\n- 将 Coasts 技能写入 `~/.claude/skills/coasts/SKILL.md`\n\n**项目设置:**\n- 将 Coast Runtime 规则追加到项目根目录下的 `CLAUDE.md`\n- 将 Coasts 技能写入 `.claude/skills/coasts/SKILL.md`\n\n## 步骤 5:更新 Coastfile\n\n读取项目根目录下的 `Coastfile`。查看\n`[coast]` 部分中的 `worktree_dir` 字段。\n\n如果 `.claude/worktrees` **尚未**列在 `worktree_dir` 中:\n\n- 如果 `worktree_dir` 是单个字符串,将其转换为数组并追加\n `.claude/worktrees`。例如,`worktree_dir = \".worktrees\"` 变为\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]`。\n- 如果 `worktree_dir` 已经是数组,则向其中追加 `.claude/worktrees`。\n- 如果根本不存在 `worktree_dir`,则添加\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]`。\n\n这是一个相对路径(位于项目根目录内),因此不需要重建容器——对于 worktree 列表,\n更改会立即生效。\n\n## 步骤 6:确认\n\n放置文件后,向用户显示创建了什么以及创建位置的摘要。\n\n告诉用户:**启动一个新的 Claude Code 会话**,以使技能和 CLAUDE.md\n更改生效。\n", + "harnesses/codex_setup_prompt.txt": "你正在为此项目中的 OpenAI Codex 设置 Coasts 技能。请从项目根目录运行所有命令。\n\n## 第 1 步:检查 Coast CLI\n\n运行此命令:\n\n coast --version\n\n如果找不到 `coast` 命令,请在此停止并告知用户:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\n在 CLI 可用之前,不要继续。\n\n## 第 2 步:获取技能内容\n\n运行此命令:\n\n coast skills-prompt\n\n输出包含两部分:\n\n- **Coast Runtime 规则** — 从开头直到(但不包括)以 `---` 开头的那一行之间的所有内容\n- **Coasts 技能** — 从 `---` frontmatter 块开始的所有内容(包括 `---` 行以及其后的所有内容)\n\n将这两部分都保存下来,以供下面的步骤使用。\n\n## 第 3 步:放置文件\n\nCodex 设置始终是项目级别的。如果目标文件已存在,请追加 Coast Runtime 部分而不是覆盖——但首先检查是否已存在 `# Coast Runtime` 部分,如果存在则跳过。\n\n- 将 Coast Runtime 规则追加到项目根目录下的 `AGENTS.md`\n- 将 Coasts 技能写入 `.agents/skills/coasts/SKILL.md`\n- 使用以下内容创建 `.agents/skills/coasts/agents/openai.yaml`:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## 第 4 步:更新 Coastfile\n\n读取项目根目录下的 `Coastfile`。查看\n`[coast]` 部分中的 `worktree_dir` 字段。\n\n如果 `~/.codex/worktrees` **尚未** 列在 `worktree_dir` 中:\n\n- 如果 `worktree_dir` 是单个字符串,将其转换为数组并追加\n `~/.codex/worktrees`。例如,`worktree_dir = \".worktrees\"` 变为\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]`。\n- 如果 `worktree_dir` 已经是数组,则向其中追加 `~/.codex/worktrees`。\n- 如果根本不存在 `worktree_dir`,则添加\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]`。\n\n这是一个外部路径,因此如果此项目的 Coast 实例已经在运行,则必须使用 `coast run` 重新创建它,新绑定挂载才会生效。请将此事告知用户。\n\n## 第 5 步:确认\n\n放置文件后,向用户显示已创建内容及其位置的摘要。\n\n告知用户:**退出并重新打开 Codex**,以使技能和 AGENTS.md 的更改生效。\n", + "harnesses/conductor_setup_prompt.txt": "你正在为此项目中的 Conductor 设置 Coasts 技能。请从项目根目录运行所有\n命令。\n\n## 步骤 1:检查 Coast CLI\n\n运行此命令:\n\n coast --version\n\n如果找不到 `coast` 命令,请在此停止并告知用户:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\n在 CLI 可用之前,不要继续。\n\n## 步骤 2:获取技能内容\n\n运行此命令:\n\n coast skills-prompt\n\n输出包含两个部分:\n\n- **Coast Runtime 规则** — 从开头到以 `---` 开头的那一行之前的所有内容(但不包括该行)\n- **Coasts 技能** — 从 `---` frontmatter 块开始的所有内容(包括 `---` 行以及其后的所有内容)\n\n请保存这两个部分,以供下面的步骤使用。\n\n## 步骤 3:询问用户\n\n询问用户:你在 Conductor 中使用哪些提供商?\n\n- **Claude**(Anthropic)\n- **Codex**(OpenAI)\n- **两者都用**\n- **其他** — 如果用户说的是不同的提供商,请运行\n `coast docs --path SKILLS_FOR_HOST_AGENTS.md` 和\n `coast docs --path harnesses/README.md`,以确定该提供商\n 期望将项目说明和技能放在哪里,然后遵循相同的模式\n\n## 步骤 4:放置文件\n\nConductor 的设置始终是项目级别的。如果目标文件已存在,请追加\nCoast Runtime 部分而不是覆盖——但首先检查是否已存在\n`# Coast Runtime` 部分,如果存在则跳过。\n\n**如果用户选择了 Claude(或两者都用):**\n- 将 Coast Runtime 规则追加到项目根目录的 `CLAUDE.md`\n- 将 Coasts 技能写入 `.claude/skills/coasts/SKILL.md`\n\n**如果用户选择了 Codex(或两者都用):**\n- 将 Coast Runtime 规则追加到项目根目录的 `AGENTS.md`\n- 将 Coasts 技能写入 `.agents/skills/coasts/SKILL.md`\n- 使用以下内容创建 `.agents/skills/coasts/agents/openai.yaml`:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## 步骤 5:确认\n\n放置文件后,向用户展示已创建内容及其位置的摘要。\n\n告诉用户:**完全关闭并重新打开 Conductor** 以使更改生效。\n如果 `/coasts` 命令没有立即出现,请再次关闭并重新打开。\n\n## 步骤 6:更新 Coastfile\n\n读取项目根目录下的 `Coastfile`。查看\n`[coast]` 部分中的 `worktree_dir` 字段。还要读取 `name` 字段——你将需要它来构造\nworktree 路径。\n\nConductor 的 worktree 目录是 `~/conductor/workspaces/`,其中\n`` 是 Coastfile 中 `name` 字段的值。\n\n如果该路径**尚未**列在 `worktree_dir` 中:\n\n- 如果 `worktree_dir` 是单个字符串,请将其转换为数组并追加\n Conductor 路径。例如,`worktree_dir = \".worktrees\"` 变为\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]`。\n- 如果 `worktree_dir` 已经是数组,请将 Conductor 路径追加到其中。\n- 如果根本不存在 `worktree_dir`,请添加\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/\"]`,其中使用\n 实际的项目名称。\n\n这是一个外部路径,因此如果该项目的 Coast 实例已经在运行,\n则必须使用 `coast run` 重新创建它,以使新的绑定挂载生效。\n请将此事告知用户。\n\n## 步骤 7:提交新文件\n\nConductor 会在隔离的 git worktree 中运行每个会话。未提交的文件\n不会带到新的会话中。请提交你刚创建的文件,以便它们在未来的每个工作区中都可用:\n\n git add CLAUDE.md .claude/ AGENTS.md .agents/ 2>/dev/null; git status\n\n向用户展示哪些文件已暂存,并在提交前请求他们确认。\n使用类似 `[dh] feat: add Coasts skill for Conductor` 的提交消息。\n", + "harnesses/cursor_setup_prompt.txt": "你正在为此项目中的 Cursor 设置 Coasts 技能。请从项目根目录运行所有\n命令。\n\n## 第 1 步:检查 Coast CLI\n\n运行以下命令:\n\n coast --version\n\n如果未找到 `coast` 命令,请在此停止并告诉用户:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\n在 CLI 可用之前不要继续。\n\n## 第 2 步:获取技能内容\n\n运行以下命令:\n\n coast skills-prompt\n\n输出包含两部分:\n\n- **Coast Runtime 规则** — 从开头到以 `---` 开始的那一行之前(但不包括该行)的所有内容\n- **Coasts 技能** — 从 `---` frontmatter 块开始往后的所有内容(包括 `---` 行以及其后的所有内容)\n\n保存这两部分,以供下面的步骤使用。\n\n## 第 3 步:询问用户\n\n询问用户:我应该将其设置为**全局**(此机器上的每个项目中都可用)还是**仅用于此项目**?\n\n## 第 4 步:放置文件\n\n如果目标文件已存在,请追加 Coast Runtime 部分而不是覆盖——但要先检查是否已经存在 `# Coast Runtime` 部分,如果存在则跳过。\n\n**全局设置:**\n- 将 Coast Runtime 规则追加到用户的全局 Cursor 规则中\n- 将 Coasts 技能写入 `~/.cursor/skills/coasts/SKILL.md`\n\n**项目设置:**\n- 将 Coast Runtime 规则追加到项目根目录的 `AGENTS.md` 中(如果用户更喜欢 Cursor 原生规则,则写入 `.cursor/rules/coast.md`——询问他们)\n- 将 Coasts 技能写入 `.cursor/skills/coasts/SKILL.md`\n\n## 第 5 步:更新 Coastfile\n\n读取项目根目录中的 `Coastfile`。查看\n`[coast]` 部分中的 `worktree_dir` 字段。还要读取 `name` 字段——你将需要它来构造\nworktree 路径。\n\nCursor 的 worktree 目录是 `~/.cursor/worktrees/`,其中 `` 是\nCoastfile 中 `name` 字段的值。\n\n如果该路径**尚未**列在 `worktree_dir` 中:\n\n- 如果 `worktree_dir` 是单个字符串,将其转换为数组并追加\n Cursor 路径。例如,`worktree_dir = \".worktrees\"` 变为\n `worktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]`。\n- 如果 `worktree_dir` 已经是数组,则将 Cursor 路径追加到其中。\n- 如果 `worktree_dir` 完全不存在,则添加\n `worktree_dir = [\".worktrees\", \"~/.cursor/worktrees/\"]`,并使用\n 实际的项目名称。\n\n这是一个外部路径,因此如果此项目的 Coast 实例已经在运行,\n则必须使用 `coast run` 重新创建它,新的 bind mount 才会生效。\n请告知用户这一点。\n\n## 第 6 步:确认\n\n放置文件后,向用户显示已创建内容及其位置的摘要。\n\n告诉用户:**重启 Cursor**,使技能和规则更改生效。\n", + "harnesses/shep_setup_prompt.txt": "你正在为该项目中的 Shep 设置 Coasts skill。请从项目根目录运行所有\n命令。\n\n## 第 1 步:检查 Coast CLI\n\n运行此命令:\n\n coast --version\n\n如果找不到 `coast` 命令,请在此停止并告知用户:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\n在 CLI 可用之前不要继续。\n\n## 第 2 步:获取 skill 内容\n\n运行此命令:\n\n coast skills-prompt\n\n输出包含两部分:\n\n- **Coast Runtime 规则** —— 从开头直到(但不包括)以 `---` 开头的那一行的所有内容\n- **Coasts skill** —— 从 `---` frontmatter 块开始的所有内容(包括 `---` 行以及其后的所有内容)\n\n保存这两部分内容,以供下面的步骤使用。\n\n## 第 3 步:放置文件\n\nShep 封装了 Claude Code,因此请使用 Claude Code 的文件布局。如果目标文件\n已存在,请追加 Coast Runtime 部分而不是覆盖——但\n先检查是否已经存在 `# Coast Runtime` 部分,如已存在则跳过。\n\n- 将 Coast Runtime 规则追加到项目根目录的 `CLAUDE.md`\n- 将 Coasts skill 写入 `.agents/skills/coasts/SKILL.md`(如果项目已经使用该布局,则为\n `.claude/skills/coasts/SKILL.md`)\n\n## 第 4 步:更新 Coastfile\n\n读取项目根目录中的 `Coastfile`。查看 `worktree_dir` 字段,它位于\n`[coast]` 部分中。\n\n如果 `~/.shep/repos/*/wt` **尚未**列在 `worktree_dir` 中:\n\n- 如果 `worktree_dir` 是单个字符串,将其转换为数组并追加\n `~/.shep/repos/*/wt`。例如,`worktree_dir = \".worktrees\"` 会变成\n `worktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]`。\n- 如果 `worktree_dir` 已经是数组,则向其中追加 `~/.shep/repos/*/wt`。\n- 如果根本不存在 `worktree_dir`,则添加\n `worktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]`。\n\n其中的 `*` 是一个 glob 模式,用于匹配每个仓库对应的哈希目录。Coasts\n会在运行时展开它。\n\n这是一个外部路径,因此如果该项目的 Coast 实例已经在运行,则必须使用 `coast run` 重新创建它,新的绑定挂载才能生效。\n请将此情况告知用户。\n\n## 第 5 步:确认\n\n放置文件后,向用户展示已创建内容及其位置的摘要。\n\n告知用户:**退出并重新打开你的编辑器**,这样 skill 和 CLAUDE.md\n的更改才会生效。\n", + "harnesses/t3_code_setup_prompt.txt": "你正在为此项目中的 T3 Code 设置 Coasts 技能。请从项目根目录运行所有\n命令。\n\n## Step 1: 检查 Coast CLI\n\n运行此命令:\n\n coast --version\n\n如果找不到 `coast` 命令,请在此停止并告诉用户:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\n在 CLI 可用之前不要继续。\n\n## Step 2: 获取技能内容\n\n运行此命令:\n\n coast skills-prompt\n\n输出有两部分:\n\n- **Coast Runtime 规则** — 从开头直到(但不包括)以 `---` 开头的那一行之前的所有内容\n- **Coasts 技能** — 从 `---` frontmatter 代码块开始往后的所有内容(包括 `---` 行以及其后的所有内容)\n\n请为下面的步骤保存这两部分内容。\n\n## Step 3: 询问用户\n\nT3 Code 支持多个提供商。询问用户:你在 T3 Code 中使用哪些提供商?\n\n- **Codex** (OpenAI)\n- **Claude** (Anthropic)\n- **Both**\n- **Other** — 如果用户提到不同的提供商,运行\n `coast docs --path SKILLS_FOR_HOST_AGENTS.md` 和\n `coast docs --path harnesses/README.md` 以确定该提供商期望将项目说明和技能放在哪里,然后遵循相同的模式\n\n## Step 4: 放置文件\n\nT3 Code 的设置始终是项目级别的。如果目标文件已经存在,请追加\nCoast Runtime 部分而不是覆盖——但首先检查是否已经存在\n`# Coast Runtime` 部分,如果存在则跳过。\n\n**如果用户选择了 Codex(或 both):**\n- 将 Coast Runtime 规则追加到项目根目录的 `AGENTS.md`\n- 将 Coasts 技能写入 `.agents/skills/coasts/SKILL.md`(项目级别)\n- 还要将 Coasts 技能写入 `~/.codex/skills/coasts/SKILL.md`(全局\n 回退方案——T3 Code 可能尚未扫描项目级别的 `.agents/skills/`)\n- 创建 `.agents/skills/coasts/agents/openai.yaml`,内容如下:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n**如果用户选择了 Claude(或 both):**\n- 将 Coast Runtime 规则追加到项目根目录的 `CLAUDE.md`\n- 将 Coasts 技能写入 `.claude/skills/coasts/SKILL.md`(项目级别)\n- 还要将 Coasts 技能写入 `~/.claude/skills/coasts/SKILL.md`(全局\n 回退方案——T3 Code 可能尚未可靠地扫描项目级别的 `.claude/skills/`)\n\n**注意:** T3 Code 可能尚未从 `.agents/skills/` 或\n`.claude/skills/` 加载项目级别的技能。不过,`AGENTS.md` 和 `CLAUDE.md` 中的规则仍然会在\n每个任务中生效。全局 `~/.codex/skills/coasts/` 回退方案可确保\nCodex 提供商能够找到该技能。\n\n## Step 5: 更新 Coastfile\n\n读取项目根目录中的 `Coastfile`。查看\n`[coast]` 部分中的 `worktree_dir` 字段。还要读取 `name` 字段——你将需要它来构造\nworktree 路径。\n\nT3 Code 的 worktree 目录是 `~/.t3/worktrees/`,其中 `` 是\nCoastfile 中 `name` 字段的值。\n\n如果该路径**尚未**列在 `worktree_dir` 中:\n\n- 如果 `worktree_dir` 是单个字符串,将其转换为数组并追加\n T3 Code 路径。例如,`worktree_dir = \".worktrees\"` 变为\n `worktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]`。\n- 如果 `worktree_dir` 已经是数组,则将 T3 Code 路径追加到其中。\n- 如果根本不存在 `worktree_dir`,则添加\n `worktree_dir = [\".worktrees\", \"~/.t3/worktrees/\"]`,其中使用\n 实际的项目名称。\n\n这是一个外部路径,因此如果该项目的 Coast 实例已经在运行,\n则必须使用 `coast run` 重新创建它,新的绑定挂载才能生效。\n请将此事告知用户。\n\n## Step 6: 确认\n\n放置文件后,向用户展示创建了什么以及创建到了哪里。\n解释全局 `~/.codex/skills/coasts/` 副本是一个变通方案,因为\nT3 Code 尚未加载项目级别的技能。\n\n告诉用户:**重启 T3 Code**,以使技能和规则的更改生效。\n", "learn-coasts-videos/README.md": "# Coasts 视频课程\n\n一套简短的视频课程,涵盖 Coasts 背后的核心理念。每节课都在三分钟以内。按顺序观看可获得完整理解,或者直接跳转到你需要的主题。\n\n```youtube\nMBGKSKau4sU\n```\n\n## 课程\n\n1. [Coasts](coasts.md) — 什么是 Coast,以及核心模型如何运作。\n2. [Ports](ports.md) — Coasts 如何处理端口隔离和并行运行时访问。\n3. [Assign](assign.md) — 在工作树之间切换一个正在运行的 Coast。\n4. [Checkout](checkout.md) — 将 Coast 带到你的规范端口上以便主动使用。\n5. [Volumes](volumes.md) — Coasts 如何处理卷和持久化服务状态。\n6. [Secrets](secrets.md) — 在 Coast 内管理密钥。\n7. [Getting Started](getting-started.md) — 一个动手实践的演练,帮助你在真实项目上试用 Coasts。\n8. [Coast UI](coast-ui.md) — Coastguard UI 及其公开的运行时信息。\n", "learn-coasts-videos/assign.md": "# 分配\n\n```youtube\nLYCeequ54nk\n```\n\n分配会将一个正在运行的 Coast 从一个工作树移动到另一个工作树,而无需拆除运行时环境。本视频介绍了分配的工作方式,以及你会在何时使用它将一个 Coast 交给不同的分支。\n\n完整参考请见 [Assign and Unassign](../concepts_and_terminology/ASSIGN.md)。\n", "learn-coasts-videos/checkout.md": "# Checkout\n\n```youtube\nJRAXkM4U1UE\n```\n\nCheckout 将你项目的规范端口映射到一个特定的 Coast 实例。此视频展示了如何将一个 Coast 置于前台,这样你的浏览器、API 客户端和测试套件都能在不更改任何端口号的情况下访问正确的环境。\n\n完整参考请参见 [Checkout](../concepts_and_terminology/CHECKOUT.md)。\n", @@ -1092,6 +1104,11 @@ "path": "harnesses/MULTIPLE_HARNESSES.md", "type": "file" }, + { + "name": "SHEP.md", + "path": "harnesses/SHEP.md", + "type": "file" + }, { "name": "T3_CODE.md", "path": "harnesses/T3_CODE.md", @@ -1172,11 +1189,11 @@ "files": { "README.md": "# Coasts ドキュメント\n\n```youtube\nMBGKSKau4sU\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## インストール\n\n- `curl -fsSL https://coasts.dev/install | sh`\n- `coast daemon install`\n\n*`coast daemon install` を実行しないことにした場合、毎回必ず `coast daemon start` でデーモンを手動で起動する責任はあなたにあります。*\n\n## Coasts とは?\n\nA Coast(**containerized host**)は、ローカル開発用のランタイムです。Coasts を使うと、1 台のマシン上で同一プロジェクトの複数の分離された環境を実行できます。\n\nCoasts は、多数の相互依存サービスを持つ複雑な `docker-compose` スタックで特に有用ですが、コンテナ化されていないローカル開発セットアップでも同様に効果的です。Coasts は幅広い[ランタイム構成パターン](concepts_and_terminology/RUNTIMES_AND_SERVICES.md)をサポートしているため、並列に作業する複数のエージェントにとって理想的な環境を形作れます。\n\nCoasts はホスト型クラウドサービスではなく、ローカル開発のために作られています。環境はあなたのマシン上でローカルに動作します。\n\nCoasts プロジェクトは無料でローカル、MIT ライセンス、エージェントプロバイダ非依存、エージェントハーネス非依存のソフトウェアで、AI のアップセルはありません。\n\nCoasts は worktree を使うあらゆるエージェント型コーディングワークフローで動作します。ハーネス側の特別な設定は不要です。\n\n## Worktrees に Coasts を使う理由\n\nGit worktree はコード変更の分離に優れていますが、ランタイムの分離をそれだけで解決するものではありません。\n\n複数の worktree を並行して動かすと、すぐに使い勝手の問題に突き当たります:\n\n- 同じホストポートを想定するサービス間の[ポート競合](concepts_and_terminology/PORTS.md)。\n- worktree ごとのデータベースと[ボリューム設定](concepts_and_terminology/VOLUMES.md)が管理しづらく面倒。\n- worktree ごとにカスタムのランタイム配線が必要な統合テスト環境。\n- worktree を切り替えるたびにランタイムコンテキストを作り直すという生き地獄。[Assign and Unassign](concepts_and_terminology/ASSIGN.md) を参照。\n\nGit がコードのバージョン管理だとすれば、Coasts は worktree のランタイムに対する Git のようなものです。\n\n各環境には専用のポートが割り当てられるため、どの worktree ランタイムも並行して確認できます。worktree ランタイムを[チェックアウト](concepts_and_terminology/CHECKOUT.md)すると、Coasts はそのランタイムをプロジェクトの標準(canonical)ポートへ再マッピングします。\n\nCoasts はランタイム構成を worktree の上にあるシンプルでモジュール式のレイヤーへ抽象化するため、複雑な worktree ごとの設定を手作業で保守することなく、各 worktree が必要とする分離で動かせます。\n\n## 要件\n\n- macOS または Linux\n- macOS では Docker Desktop、Linux では Compose プラグイン付き Docker Engine\n- Git を使うプロジェクト\n- Node.js\n- `socat`(macOS では `brew install socat`、Ubuntu では `sudo apt install socat`)\n\n```text\nLinux note: Dynamic ports work out of the box on Linux.\nIf you need canonical ports below `1024`, see the checkout docs for the required host configuration.\n```\n\n## エージェントをコンテナ化する?\n\nCoast を使ってエージェントをコンテナ化できます。最初は良いアイデアに聞こえるかもしれませんが、多くの場合、実際にはコーディングエージェントをコンテナ内で動かす必要はありません。\n\nCoasts は共有ボリュームマウントを通じてホストマシンと[ファイルシステム](concepts_and_terminology/FILESYSTEM.md)を共有するため、最も簡単で信頼性の高いワークフローは、ホスト上でエージェントを動かし、統合テストのようなランタイム負荷の高いタスクを [`coast exec`](concepts_and_terminology/EXEC_AND_DOCKER.md) を使って Coast インスタンス内で実行するよう指示することです。\n\nただし、エージェントをコンテナ内で動かしたい場合でも、Coasts は[Agent Shells](concepts_and_terminology/AGENT_SHELLS.md) によってそれを全面的にサポートします。[MCP サーバー設定](concepts_and_terminology/MCP_SERVERS.md)を含む、このセットアップのための非常に入り組んだリグを構築できますが、現時点で存在するオーケストレーションソフトウェアとはきれいに相互運用できない可能性があります。ほとんどのワークフローでは、ホスト側エージェントの方がシンプルで信頼性が高いです。\n\n## Coasts vs Dev Containers\n\nCoasts は dev container ではなく、同じものではありません。\n\nDev container は一般に、IDE を 1 つのコンテナ化された開発ワークスペースへマウントするために設計されています。Coasts はヘッドレスで、worktree と並列エージェント利用のための軽量環境として最適化されています。つまり、worktree を認識する複数の分離されたランタイム環境を並べて実行でき、素早いチェックアウト切り替えと、インスタンスごとのランタイム分離制御を提供します。\n\n## Demo Repo\n\nCoasts を試すための小さなサンプルプロジェクトが欲しい場合は、[`coasts-demo` repository](https://github.com/coast-guard/coasts-demo)から始めてください。\n\n## Coasts Video Course\n\n動画の方がよければ、[Coasts Video Course](learn-coasts-videos/README.md) で各コアコンセプトをそれぞれ 3 分未満で学べます。\n", "GETTING_STARTED.md": "# Coasts 入門\n\n```youtube\nJe921fgJ4RY\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## インストール\n\n```bash\ncurl -fsSL https://coasts.dev/install | sh\ncoast daemon install\n```\n\n*`coast daemon install` を実行しないと決めた場合、毎回 `coast daemon start` でデーモンを手動で起動する責任はあなたにあります。*\n\n## 要件\n\n- macOS または Linux\n- macOS では Docker Desktop、Linux では Compose プラグイン付きの Docker Engine\n- Git を使用しているプロジェクト\n- Node.js\n- `socat`(macOS では `brew install socat`、Ubuntu では `sudo apt install socat`)\n\n```text\nLinux note: Dynamic ports work out of the box on Linux.\nIf you need canonical ports below `1024`, see the checkout docs for the required host configuration.\n```\n\n## プロジェクトで Coasts をセットアップする\n\nプロジェクトのルートに Coastfile を追加します。インストール時は worktree 上にいないことを確認してください。\n\n```text\nmy-project/\n├── Coastfile <-- これを Coast が読み込みます\n├── docker-compose.yml\n├── Dockerfile\n├── src/\n│ └── ...\n└── ...\n```\n\n`Coastfile` は既存のローカル開発リソースを指し、Coasts 固有の設定を追加します。完全なスキーマは [Coastfiles documentation](coastfiles/README.md) を参照してください:\n\n```toml\n[coast]\nname = \"my-project\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\ndb = 5432\n```\n\nCoastfile は軽量な TOML ファイルで、*通常* は既存の `docker-compose.yml` を指します(コンテナ化されていないローカル開発セットアップでも動作します)。また、プロジェクトを並列で動かすために必要な変更点(ポートマッピング、ボリューム戦略、シークレット)を記述します。プロジェクトのルートに配置してください。\n\nプロジェクト用の Coastfile を作成する最速の方法は、コーディングエージェントに作ってもらうことです。\n\nCoasts CLI には、任意の AI エージェントに Coastfile の完全なスキーマと CLI を教えるための組み込みプロンプトが付属しています。これをエージェントのチャットにコピーすると、プロジェクトを解析して Coastfile を生成します。\n\n```prompt-copy\ninstallation_prompt.txt\n```\n\nまた、`coast installation-prompt` を実行すると CLI から同じ出力を取得できます。\n\n## 最初の Coast\n\n最初の Coast を起動する前に、実行中の開発環境をすべて停止してください。Docker Compose を使っている場合は `docker-compose down` を実行します。ローカルの開発サーバーを動かしている場合は停止してください。Coasts は自身でポートを管理するため、すでに待ち受けているものがあると競合します。\n\nCoastfile の準備ができたら:\n\n```bash\ncoast build\ncoast run dev-1\n```\n\nインスタンスが実行中であることを確認します:\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ~/dev/my-project\n```\n\nサービスがどのポートで待ち受けているか確認します:\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\n各インスタンスには専用の動的ポート一式が割り当てられるため、複数のインスタンスを並べて同時に実行できます。インスタンスをプロジェクトの正規(canonical)ポートに紐づけるには、チェックアウトします:\n\n```bash\ncoast checkout dev-1\n```\n\nこれは、ランタイムがチェックアウトされ、プロジェクトの正規ポート(`3000`、`5432` など)がこの Coast インスタンスへルーティングされるようになったことを意味します。\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ✓ ~/dev/my-project\n```\n\nプロジェクト向けに Coastguard の可観測性 UI を起動するには:\n\n```bash\ncoast ui\n```\n\n## 次は?\n\n- Coasts とやり取りする方法を理解させるために、[ホストエージェント用のスキル](SKILLS_FOR_HOST_AGENTS.md) を設定する\n", - "SKILLS_FOR_HOST_AGENTS.md": "# ホストエージェント向けスキル\n\nアプリが Coasts 内で動作している間にホスト上で AI コーディングエージェントを使う場合、通常、そのエージェントには Coast 固有のセットアップが 2 つ必要です。\n\n1. ハーネスのプロジェクト指示ファイルまたはルールファイルにある、常時有効な Coast Runtime セクション\n2. ハーネスがプロジェクトスキルをサポートしている場合の、`/coasts` のような再利用可能な Coast ワークフロースキル\n\n1 つ目がないと、エージェントはファイルを編集しても `coast exec` を使うことを忘れます。\n2 つ目がないと、Coast の割り当て、ログ、UI フローを毎回チャットで説明し直す必要があります。\n\nこのガイドでは、セットアップを具体的かつ Coast 固有のものに絞って説明します。つまり、どのファイルを作るか、そこにどんなテキストを入れるか、そしてそれがハーネスごとにどう変わるかを扱います。\n\n## なぜエージェントにこれが必要なのか\n\nCoasts は、ホストマシンと Coast コンテナの間で [filesystem](concepts_and_terminology/FILESYSTEM.md) を共有します。エージェントはホスト上でファイルを編集し、Coast 内で実行中のサービスはその変更を即座に認識します。しかし、エージェントは依然として次のことを行う必要があります。\n\n1. 現在のチェックアウトに対応する Coast インスタンスを見つける\n2. その Coast の中でテスト、ビルド、ランタイムコマンドを実行する\n3. Coast からログとサービス状態を読む\n4. まだ Coast がアタッチされていない場合に worktree の割り当てを安全に処理する\n\n## 何をどこに置くか\n\n- `AGENTS.md`、`CLAUDE.md`、または `.cursor/rules/coast.md` — スキルが呼び出されない場合でも、すべてのタスクに適用されるべき短い Coast ルール\n- skill (`.agents/skills/...`、`.claude/skills/...`、または `.cursor/skills/...`) — `/coasts` のような、再利用可能な Coast ワークフロー本体\n- command file (`.claude/commands/...` または `.cursor/commands/...`) — サポートするハーネス向けの任意の明示的エントリポイント。単純な選択肢の 1 つは、その command から skill を再利用することです\n\n1 つのリポジトリで複数のハーネスを使う場合は、正本となる Coast スキルを 1 か所に置き、必要な場所でそれを公開してください。詳しくは\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md) を参照してください。\n\n## 1. 常時有効な Coast Runtime ルール\n\n次のブロックを、ハーネスの常時有効なプロジェクト指示ファイルまたはルールファイル(`AGENTS.md`、`CLAUDE.md`、`.cursor/rules/coast.md`、または同等のもの)に追加してください。\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\nこのブロックは常時有効ファイルに置くべきです。なぜなら、これらのルールは、エージェントが明示的に `/coasts` ワークフローに入ったときだけでなく、すべてのタスクに適用されるべきだからです。\n\n## 2. 再利用可能な `/coasts` スキル\n\nハーネスがプロジェクトスキルをサポートしている場合は、スキル内容をスキルディレクトリ内の `SKILL.md` として保存してください。完全なスキルテキストは [skills_prompt.txt](skills_prompt.txt) にあります(CLI モードでは `coast skills-prompt` を使ってください)。Coast Runtime ブロックの後ろ、`---` フロントマターから始まる部分がスキル内容です。\n\nCodex や OpenAI 固有のサーフェスを使っている場合は、表示メタデータや呼び出しポリシーのために、スキルの横に `agents/openai.yaml` を任意で追加できます。そのメタデータはスキルの横に置くべきであり、スキル自体の代わりにするべきではありません。\n\n## ハーネス別クイックスタート\n\n| Harness | Always-on file | Reusable Coast workflow | Notes |\n|---------|----------------|-------------------------|-------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Coast ドキュメント向けに推奨する別個のプロジェクト command file はありません。[Codex](harnesses/CODEX.md) を参照してください。 |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md` は任意ですが、ロジックはスキル内に保ってください。[Claude Code](harnesses/CLAUDE_CODE.md) を参照してください。 |\n| Cursor | `AGENTS.md` or `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` or shared `.agents/skills/coasts/SKILL.md` | `.cursor/commands/coasts.md` は任意です。`.cursor/worktrees.json` は Cursor の worktree ブートストラップ用であり、Coast ポリシー用ではありません。[Cursor](harnesses/CURSOR.md) を参照してください。 |\n| Conductor | `CLAUDE.md` | Start with `CLAUDE.md`; use Conductor scripts and settings for Conductor-specific behavior | Claude Code の完全な project command 挙動を前提にしないでください。新しい command が表示されない場合は、Conductor を完全に閉じて再度開いてください。[Conductor](harnesses/CONDUCTOR.md) を参照してください。 |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | これはここで扱う中で最も制限の多いハーネスです。Codex スタイルのレイアウトを使い、Coast ドキュメントのために T3 ネイティブな command レイヤーを作らないでください。[T3 Code](harnesses/T3_CODE.md) を参照してください。 |\n\n## エージェント自身にセットアップさせる\n\n最も手早い方法は、エージェント自身に正しいファイルを書かせることです。以下のプロンプトをエージェントのチャットにコピーしてください。これには Coast Runtime ブロック、`coasts` スキルブロック、および各要素をどこに置くべきかというハーネス別の指示が含まれています。\n\n```prompt-copy\nskills_prompt.txt\n```\n\nCLI から `coast skills-prompt` を実行しても、同じ出力を取得できます。\n\n## 手動セットアップ\n\n- **Codex:** Coast Runtime セクションを `AGENTS.md` に置き、その後、再利用可能な `coasts` スキルを `.agents/skills/coasts/SKILL.md` に置いてください。\n- **Claude Code:** Coast Runtime セクションを `CLAUDE.md` に置き、その後、再利用可能な `coasts` スキルを `.claude/skills/coasts/SKILL.md` に置いてください。`command file` が特に必要な場合にのみ `.claude/commands/coasts.md` を追加してください。\n- **Cursor:** 最も移植性の高い指示にしたいなら Coast Runtime セクションを `AGENTS.md` に置き、Cursor ネイティブなプロジェクトルールにしたいなら `.cursor/rules/coast.md` に置いてください。再利用可能な `coasts` ワークフローは、Cursor 専用のリポジトリなら `.cursor/skills/coasts/SKILL.md` に、他のハーネスと共有するリポジトリなら `.agents/skills/coasts/SKILL.md` に置いてください。明示的な command file が特に必要な場合にのみ `.cursor/commands/coasts.md` を追加してください。\n- **Conductor:** Coast Runtime セクションを `CLAUDE.md` に置いてください。Conductor 固有のブートストラップや実行挙動には、Conductor Repository Settings のスクリプトを使ってください。command を追加しても表示されない場合は、アプリを完全に閉じて再度開いてください。\n- **T3 Code:** Codex と同じレイアウト、つまり `AGENTS.md` と `.agents/skills/coasts/SKILL.md` を使ってください。ここでは T3 Code を別個の Coast command サーフェスとしてではなく、薄い Codex スタイルのハーネスとして扱ってください。\n- **Multiple harnesses:** 正本となるスキルは `.agents/skills/coasts/SKILL.md` に置いてください。Cursor はそれを直接読み込めます。必要であれば `.claude/skills/coasts/` 経由で Claude Code に公開してください。\n\n## さらに読む\n\n- ハーネスごとの対応表については [Harnesses guide](harnesses/README.md) を読んでください\n- 共有レイアウトパターンについては [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md) を読んでください\n- 完全な設定スキーマを学ぶには [Coastfiles documentation](coastfiles/README.md) を読んでください\n- インスタンス管理用コマンドについては [Coast CLI](concepts_and_terminology/CLI.md) を参照してください\n- Coasts を観察および制御するための Web UI である [Coastguard](concepts_and_terminology/COASTGUARD.md) を確認してください\n", + "SKILLS_FOR_HOST_AGENTS.md": "# ホストエージェント向けスキル\n\nアプリが Coasts 内で動作している間にホスト上で AI コーディングエージェントを使う場合、通常、そのエージェントには Coast 固有のセットアップが 2 つ必要です。\n\n1. ハーネスのプロジェクト指示ファイルまたはルールファイルにある、常時有効な Coast Runtime セクション\n2. ハーネスがプロジェクトスキルをサポートしている場合の、`/coasts` のような再利用可能な Coast ワークフロースキル\n\n1 つ目がないと、エージェントはファイルを編集しても `coast exec` を使うことを忘れます。\n2 つ目がないと、Coast の割り当て、ログ、UI フローを毎回チャットで説明し直す必要があります。\n\nこのガイドでは、セットアップを具体的かつ Coast 固有のものに絞って説明します。つまり、どのファイルを作るか、そこにどんなテキストを入れるか、そしてそれがハーネスごとにどう変わるかを扱います。\n\n## なぜエージェントにこれが必要なのか\n\nCoasts は、ホストマシンと Coast コンテナの間で [filesystem](concepts_and_terminology/FILESYSTEM.md) を共有します。エージェントはホスト上でファイルを編集し、Coast 内で実行中のサービスはその変更を即座に認識します。しかし、エージェントは依然として次のことを行う必要があります。\n\n1. 現在のチェックアウトに対応する Coast インスタンスを見つける\n2. その Coast の中でテスト、ビルド、ランタイムコマンドを実行する\n3. Coast からログとサービス状態を読む\n4. まだ Coast がアタッチされていない場合に worktree の割り当てを安全に処理する\n\n## 何をどこに置くか\n\n- `AGENTS.md`、`CLAUDE.md`、または `.cursor/rules/coast.md` — スキルが呼び出されない場合でも、すべてのタスクに適用されるべき短い Coast ルール\n- skill (`.agents/skills/...`、`.claude/skills/...`、または `.cursor/skills/...`) — `/coasts` のような、再利用可能な Coast ワークフロー本体\n- command file (`.claude/commands/...` または `.cursor/commands/...`) — サポートするハーネス向けの任意の明示的エントリポイント。単純な選択肢の 1 つは、その command から skill を再利用することです\n\n1 つのリポジトリで複数のハーネスを使う場合は、正本となる Coast スキルを 1 か所に置き、必要な場所でそれを公開してください。詳しくは\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md) を参照してください。\n\n## 1. 常時有効な Coast Runtime ルール\n\n次のブロックを、ハーネスの常時有効なプロジェクト指示ファイルまたはルールファイル(`AGENTS.md`、`CLAUDE.md`、`.cursor/rules/coast.md`、または同等のもの)に追加してください。\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n coast exec --service # service shell\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Use `coast exec --service ` when you need to run inside an app/service container.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\nこのブロックは常時有効ファイルに置くべきです。なぜなら、これらのルールは、エージェントが明示的に `/coasts` ワークフローに入ったときだけでなく、すべてのタスクに適用されるべきだからです。\n\n## 2. 再利用可能な `/coasts` スキル\n\nハーネスがプロジェクトスキルをサポートしている場合は、スキル内容をスキルディレクトリ内の `SKILL.md` として保存してください。完全なスキルテキストは [skills_prompt.txt](skills_prompt.txt) にあります(CLI モードでは `coast skills-prompt` を使ってください)。Coast Runtime ブロックの後ろ、`---` フロントマターから始まる部分がスキル内容です。\n\nCodex や OpenAI 固有のサーフェスを使っている場合は、表示メタデータや呼び出しポリシーのために、スキルの横に `agents/openai.yaml` を任意で追加できます。そのメタデータはスキルの横に置くべきであり、スキル自体の代わりにするべきではありません。\n\n## ハーネス別クイックスタート\n\n| Harness | Always-on file | Reusable Coast workflow | Notes |\n|---------|----------------|-------------------------|-------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Coast ドキュメント向けに推奨する別個のプロジェクト command file はありません。[Codex](harnesses/CODEX.md) を参照してください。 |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md` は任意ですが、ロジックはスキル内に保ってください。[Claude Code](harnesses/CLAUDE_CODE.md) を参照してください。 |\n| Cursor | `AGENTS.md` or `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` or shared `.agents/skills/coasts/SKILL.md` | `.cursor/commands/coasts.md` は任意です。`.cursor/worktrees.json` は Cursor の worktree ブートストラップ用であり、Coast ポリシー用ではありません。[Cursor](harnesses/CURSOR.md) を参照してください。 |\n| Conductor | `CLAUDE.md` | Start with `CLAUDE.md`; use Conductor scripts and settings for Conductor-specific behavior | Claude Code の完全な project command 挙動を前提にしないでください。新しい command が表示されない場合は、Conductor を完全に閉じて再度開いてください。[Conductor](harnesses/CONDUCTOR.md) を参照してください。 |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | これはここで扱う中で最も制限の多いハーネスです。Codex スタイルのレイアウトを使い、Coast ドキュメントのために T3 ネイティブな command レイヤーを作らないでください。[T3 Code](harnesses/T3_CODE.md) を参照してください。 |\n\n## エージェント自身にセットアップさせる\n\n最も手早い方法は、エージェント自身に正しいファイルを書かせることです。以下のプロンプトをエージェントのチャットにコピーしてください。これには Coast Runtime ブロック、`coasts` スキルブロック、および各要素をどこに置くべきかというハーネス別の指示が含まれています。\n\n```prompt-copy\nskills_prompt.txt\n```\n\nCLI から `coast skills-prompt` を実行しても、同じ出力を取得できます。\n\n## 手動セットアップ\n\n- **Codex:** Coast Runtime セクションを `AGENTS.md` に置き、その後、再利用可能な `coasts` スキルを `.agents/skills/coasts/SKILL.md` に置いてください。\n- **Claude Code:** Coast Runtime セクションを `CLAUDE.md` に置き、その後、再利用可能な `coasts` スキルを `.claude/skills/coasts/SKILL.md` に置いてください。`command file` が特に必要な場合にのみ `.claude/commands/coasts.md` を追加してください。\n- **Cursor:** 最も移植性の高い指示にしたいなら Coast Runtime セクションを `AGENTS.md` に置き、Cursor ネイティブなプロジェクトルールにしたいなら `.cursor/rules/coast.md` に置いてください。再利用可能な `coasts` ワークフローは、Cursor 専用のリポジトリなら `.cursor/skills/coasts/SKILL.md` に、他のハーネスと共有するリポジトリなら `.agents/skills/coasts/SKILL.md` に置いてください。明示的な command file が特に必要な場合にのみ `.cursor/commands/coasts.md` を追加してください。\n- **Conductor:** Coast Runtime セクションを `CLAUDE.md` に置いてください。Conductor 固有のブートストラップや実行挙動には、Conductor Repository Settings のスクリプトを使ってください。command を追加しても表示されない場合は、アプリを完全に閉じて再度開いてください。\n- **T3 Code:** Codex と同じレイアウト、つまり `AGENTS.md` と `.agents/skills/coasts/SKILL.md` を使ってください。ここでは T3 Code を別個の Coast command サーフェスとしてではなく、薄い Codex スタイルのハーネスとして扱ってください。\n- **Multiple harnesses:** 正本となるスキルは `.agents/skills/coasts/SKILL.md` に置いてください。Cursor はそれを直接読み込めます。必要であれば `.claude/skills/coasts/` 経由で Claude Code に公開してください。\n\n## さらに読む\n\n- ハーネスごとの対応表については [Harnesses guide](harnesses/README.md) を読んでください\n- 共有レイアウトパターンについては [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md) を読んでください\n- 完全な設定スキーマを学ぶには [Coastfiles documentation](coastfiles/README.md) を読んでください\n- インスタンス管理用コマンドについては [Coast CLI](concepts_and_terminology/CLI.md) を参照してください\n- Coasts を観察および制御するための Web UI である [Coastguard](concepts_and_terminology/COASTGUARD.md) を確認してください\n", "VIDEO_TUTORIALS.md": "# ビデオチュートリアル\n\nこのページでは、Coasts の YouTube チャンネルにある公式 Coasts チュートリアル動画をまとめています。\n\nドキュメントの残りを読む前に手早く動画でのウォークスルーを見たい場合は、まず概要と入門動画から始め、その後に以下の機能別トピックへ進んでください。\n\n## リンク\n\n- [Coasts YouTube channel](https://www.youtube.com/@coasts-dev) - Coasts 動画の公式チャンネル。\n- [Coasts playlist](https://www.youtube.com/playlist?list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw) - チュートリアルの全プレイリストを1か所にまとめたもの。\n\n## 動画\n\n- [Coasts Overview](https://www.youtube.com/watch?v=MBGKSKau4sU&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=1&pp=iAQB) (2:42) - Coasts とは何か、そしてなぜそれを使うのかについての高レベルな紹介。\n- [Coasts](https://www.youtube.com/watch?v=kYlB5U9O92E&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=2&pp=iAQB) (1:29) - Coasts の中核モデルの短いツアー。\n- [Ports](https://www.youtube.com/watch?v=pBKkBiJ3o-g&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=3&pp=iAQB) (1:46) - Coasts がポートの分離と並列実行時アクセスをどのように扱うか。\n- [Assign](https://www.youtube.com/watch?v=LYCeequ54nk&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=4&pp=iAQB) (1:57) - 実行中の Coast を worktree 間で切り替える方法。\n- [Checkout](https://www.youtube.com/watch?v=JRAXkM4U1UE&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=5&pp=iAQB) (1:46) - アクティブに使用するために、1つの Coast を正規のポートに割り当てる(持ってくる)方法。\n- [Volumes](https://www.youtube.com/watch?v=k1es1Wf0zp0&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=6&pp=iAQB) (2:00) - Coasts がボリュームと永続的なサービス状態をどのように扱うか。\n- [Secrets](https://www.youtube.com/watch?v=4lAfHUjqn50&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=7&pp=iAQB) (2:09) - Coast 内でシークレットを管理する方法。\n- [Getting Started](https://www.youtube.com/watch?v=Je921fgJ4RY&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=8&pp=iAQB) (2:40) - Coasts を試すための簡単な導入ウォークスルー。\n- [Coast UI](https://www.youtube.com/watch?v=Ts-YWkhHR8I&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=9&pp=iAQB0gcJCa4KAYcqIYzv) (1:46) - Coastguard UI と、そこで公開される実行時情報のツアー。\n\nこのページは公式プレイリストの現在の内容を反映しており、新しいチュートリアル動画が追加されると更新される場合があります。\n", - "doc_ordering.txt": "# トップレベル\nREADME.md\nGETTING_STARTED.md\nSKILLS_FOR_HOST_AGENTS.md\n\n# Learn Coasts\nlearn-coasts-videos/README.md\nlearn-coasts-videos/coasts.md\nlearn-coasts-videos/ports.md\nlearn-coasts-videos/assign.md\nlearn-coasts-videos/checkout.md\nlearn-coasts-videos/volumes.md\nlearn-coasts-videos/secrets.md\nlearn-coasts-videos/getting-started.md\nlearn-coasts-videos/coast-ui.md\n\n# ハーネス\nharnesses/README.md\nharnesses/CODEX.md\nharnesses/CONDUCTOR.md\nharnesses/CLAUDE_CODE.md\nharnesses/CURSOR.md\nharnesses/T3_CODE.md\nharnesses/MULTIPLE_HARNESSES.md\n\n# 概念と用語\nconcepts_and_terminology/README.md\nconcepts_and_terminology/COASTS.md\nconcepts_and_terminology/RUN.md\nconcepts_and_terminology/REMOVE.md\nconcepts_and_terminology/FILESYSTEM.md\nconcepts_and_terminology/DAEMON.md\nconcepts_and_terminology/CLI.md\nconcepts_and_terminology/COASTGUARD.md\nconcepts_and_terminology/PORTS.md\nconcepts_and_terminology/PRIMARY_PORT_AND_DNS.md\nconcepts_and_terminology/ASSIGN.md\nconcepts_and_terminology/CHECKOUT.md\nconcepts_and_terminology/LOOKUP.md\nconcepts_and_terminology/VOLUMES.md\nconcepts_and_terminology/SHARED_SERVICES.md\nconcepts_and_terminology/SECRETS.md\nconcepts_and_terminology/BUILDS.md\nconcepts_and_terminology/COASTFILE_TYPES.md\nconcepts_and_terminology/RUNTIMES_AND_SERVICES.md\nconcepts_and_terminology/BARE_SERVICES.md\nconcepts_and_terminology/MIXED_SERVICE_TYPES.md\nconcepts_and_terminology/LOGS.md\nconcepts_and_terminology/EXEC_AND_DOCKER.md\nconcepts_and_terminology/AGENT_SHELLS.md\nconcepts_and_terminology/MCP_SERVERS.md\nconcepts_and_terminology/PERFORMANCE_OPTIMIZATIONS.md\nconcepts_and_terminology/TROUBLESHOOTING.md\n\n# Coastfiles\ncoastfiles/README.md\ncoastfiles/PROJECT.md\ncoastfiles/WORKTREE_DIR.md\ncoastfiles/PORTS.md\ncoastfiles/SHARED_SERVICES.md\ncoastfiles/SERVICES.md\ncoastfiles/SECRETS.md\ncoastfiles/VOLUMES.md\ncoastfiles/ASSIGN.md\ncoastfiles/INHERITANCE.md\ncoastfiles/AGENT_SHELL.md\ncoastfiles/MCP.md\n\n# レシピ\nrecipes/README.md\nrecipes/FULLSTACK_MONOREPO.md\n", - "installation_prompt.txt": "あなたはこのプロジェクトに Coasts をインストールしています。Coast(コンテナ化されたホスト)は CLI ツールで、Docker-in-Docker コンテナを使用して、1 台のマシン上で複数の隔離された開発環境を実行します。各環境はそれぞれ独自のポート、ボリューム、ランタイムを持つため、並列の worktree ワークフローに最適です。\n\nあなたの仕事: このプロジェクトを分析し、Coastfile(プロジェクトルートに置く \"Coastfile\" という名前の TOML ファイル)を生成してください。\n\n=== ドキュメント ===\n\nCoast には CLI からアクセスできる組み込みドキュメントがあります。Coastfile を生成する前に、これらを使って Coastfile スキーマ全体、ボリューム戦略、assign の挙動、その他の設定オプションを理解してください。\n\nドキュメントツリーを参照:\n\n coast docs\n\nこれにより、完全なドキュメントツリーが出力されます。まず README ファイルを読むところから始めてください — 各トピックに適したドキュメントを見つけるためのインデックスが提供されています:\n\n coast docs --path README.md\n coast docs --path coastfiles/README.md\n coast docs --path concepts_and_terminology/README.md\n\n特定のドキュメントを読む:\n\n coast docs --path coastfiles/PROJECT.md\n coast docs --path coastfiles/VOLUMES.md\n\nドキュメントを検索(セマンティック検索 — 探している内容を自然言語で説明):\n\n coast search-docs \"how do volume strategies work\"\n coast search-docs \"shared postgres across instances\"\n coast search-docs \"secret injection from environment variables\"\n\nこれらのドキュメントを使って、このプロジェクトの Coastfile 設定について十分な情報に基づいた判断をしてください。coastfiles/ セクションでは、すべての Coastfile ディレクティブが詳細に解説されています。\n\n=== COASTFILE スキーマ(クイックリファレンス) ===\n\n[coast] — 必須。プロジェクトのメタデータ。\n\n name (string, required) コンテナ/ボリューム命名に使われるプロジェクト識別子。\n compose (string, optional) Coastfile からの相対パスで指定する docker-compose.yml のパス。\n runtime (string, optional) \"dind\"(デフォルト)、\"sysbox\"、または \"podman\"。\n root (string, optional) プロジェクトルートの上書き(相対または絶対)。\n worktree_dir (string, optional) git worktree 用ディレクトリ(デフォルト: \".worktrees\")。実行時に既存の worktree から自動検出。\n\n[coast.setup] — 任意。DinD コンテナ自体をカスタマイズ。\n\n packages (array of strings) インストールする Alpine パッケージ(例: [\"nodejs\", \"npm\", \"git\"])。\n run (array of strings) セットアップ中に実行する任意のコマンド。\n\n[ports] — 必須(少なくとも 1 つ)。論理名からポート番号へのマップ。\n これらのポートは coast がチェックアウトされたときにホストへフォワードされます。\n\n 例:\n [ports]\n web = 3000\n api = 8080\n postgres = 5432\n\n[volumes.*] — 任意。ボリュームごとの設定。\n\n strategy \"isolated\"(デフォルト)または \"shared\"\n service このボリュームを所有する Compose サービス名。\n mount サービスコンテナ内のマウントパス。\n snapshot_source (isolated のみ) 既存のボリューム名からシード。\n\n 例:\n [volumes.postgres_data]\n strategy = \"isolated\"\n service = \"db\"\n mount = \"/var/lib/postgresql/data\"\n\n[secrets.*] — 任意。シークレットの抽出と注入。\n\n extractor \"file\"、\"env\"、\"command\"、または \"macos-keychain\"\n inject \"env:VAR_NAME\" または \"file:/path/in/container\"\n ttl 任意の有効期限(例: \"1h\"、\"30m\")。\n\n extractor 固有パラメータ:\n file: path = \"./path/to/secret\"\n env: var = \"HOST_ENV_VAR\"\n command: run = \"echo secret-value\"\n macos-keychain: item = \"keychain-item-name\"\n\n 例:\n [secrets.db_password]\n extractor = \"env\"\n var = \"DB_PASSWORD\"\n inject = \"env:DATABASE_PASSWORD\"\n\n[inject] — 任意。非シークレットのホストファイル/環境変数の注入。\n\n env フォワードするホスト環境変数名の配列。\n files マウントするホストファイルパスの配列。\n\n 例:\n [inject]\n env = [\"NODE_ENV\", \"DEBUG\"]\n files = [\"~/.ssh/id_ed25519\", \"~/.gitconfig\"]\n\n[shared_services.*] — 任意。ホストの Docker デーモン上で動作し、インスタンス間で共有されるサービス。\n\n image Docker イメージ。\n ports ポート番号の配列。\n volumes ボリュームマウントの配列。\n env 環境変数のインラインテーブル。\n auto_create_db (bool) インスタンスごとのデータベースを自動的に作成。\n inject 接続文字列を coast コンテナへ注入。\n\n 例:\n [shared_services.postgres]\n image = \"postgres:16-alpine\"\n ports = [5432]\n volumes = [\"postgres_data:/var/lib/postgresql/data\"]\n env = { POSTGRES_USER = \"dev\", POSTGRES_PASSWORD = \"dev\", POSTGRES_DB = \"app\" }\n auto_create_db = true\n inject = \"env:DATABASE_URL\"\n\n[assign] — 任意。ブランチ切り替え時(coast assign)の挙動を制御。\n\n default \"none\"、\"restart\"、または \"rebuild\"\n [assign.services] サービスごとの上書き。\n [assign.rebuild_triggers] 再ビルドをトリガーするサービスごとのファイル glob。\n\n 例:\n [assign]\n default = \"none\"\n [assign.services]\n api = \"restart\"\n worker = \"rebuild\"\n [assign.rebuild_triggers]\n worker = [\"Dockerfile\", \"package.json\"]\n\n[services.*] — 任意。プロセスのみのサービス(docker-compose 不要)。\n\n command 実行するシェルコマンド。\n port ポート番号。\n restart \"on-failure\" または \"always\"。\n\n 例:\n [services.web]\n command = \"node server.js\"\n port = 3000\n restart = \"on-failure\"\n\n=== 例: 最小(compose なし) ===\n\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[ports]\napp = 3000\n\n=== 例: docker-compose あり ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\npostgres = 5432\nredis = 6379\n\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n\n=== 例: secrets あり ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\n\n[secrets.api_key]\nextractor = \"env\"\nvar = \"API_KEY\"\ninject = \"env:API_KEY\"\n\n[secrets.ssh_key]\nextractor = \"file\"\npath = \"~/.ssh/id_ed25519\"\ninject = \"file:/run/secrets/ssh_key\"\n\n=== ユーザーと議論すべき主要なトレードオフ ===\n\nCoastfile を生成する前に、曖昧な設定の選択肢についてユーザーに確認してください。主なものは次のとおりです:\n\nデータベースおよびインフラ戦略 — postgres や redis のようなサービスには 3 つの選択肢があります:\n - 隔離ボリューム(デフォルト): 各 Coast インスタンスは DinD コンテナ内にデータのコピーをそれぞれ持ちます。インスタンス同士が干渉できません。ブランチごとの DB 状態が欲しい場合に最適です。\n - 共有ボリューム: すべてのインスタンスが DinD コンテナ内の同じボリュームを読み書きします。ディスク容量は節約できますが、複数インスタンスからの同時書き込みでデータが破損する可能性があります。\n - 共有サービス: 各 Coast 内ではなく、ホストの Docker デーモン上でデータベースを実行します。すべてのインスタンスは 1 つの共有サーバーに接続します。メモリ使用量が最小で、単一の postgres 上でインスタンスごとの DB を作る auto_create_db をサポートし、データはインスタンス削除後も残ります。大規模チームやメモリ制約のあるマシンに最適です。\n - プロジェクトにデータベースがある場合、どのアプローチにしたいかユーザーに確認してください。トレードオフを説明してください — 隔離が最も安全で、共有サービスが最もメモリ効率が良いです。\n\nAssign 戦略 — Coast を worktree 間で切り替えたときに何が起きるか:\n - \"none\": 何もしない(ブランチ間で変化しない postgres/redis のようなサービス向け)。\n - \"restart\": コンテナを再起動(プロセス再起動だけでよいインタプリタ系サービス向け)。\n - \"rebuild\": Docker イメージを再ビルドして再起動(ブランチ変更が Dockerfile やビルド依存に影響するサービス向け)。\n - プロジェクトに複数サービスがある場合、ブランチ切り替え時に再ビルドが必要なものと再起動でよいものをユーザーに確認してください。\n\n=== 手順 ===\n\n1. このプロジェクトの構成を確認します。docker-compose.yml がある場合はそれを読み、サービス、ポート、ボリュームを特定します。\n2. 既存の git worktree ディレクトリを検出します。`git worktree list` を実行し、プロジェクトがすでに git worktree を設定しているか確認します。\n - worktree が存在する場合、パスを調べて共通の親ディレクトリを特定します(例: worktree が `../.worktrees/feat-a` と `../.worktrees/feat-b` にあるなら、worktree_dir は `\"../.worktrees\"`)。\n - 検出したディレクトリに合わせて Coastfile の `worktree_dir` を設定します。\n - worktree が存在しない場合、`worktree_dir` は省略します(Coast のデフォルトは \".worktrees\")。\".coasts\" は使用しないでください — Coast ブランドのディレクトリでプロジェクトを汚染します。\n3. 関連する Coast ドキュメント(`coast docs` と `coast search-docs` を使用)を読み、ボリューム戦略、assign の挙動、このプロジェクトのスタックに適用される設定オプションを理解します。\n4. 曖昧な設定の選択肢についてユーザーに確認します(上記のトレードオフ参照)。推測しないでください — 選択肢を説明し、ユーザーに決めてもらいます。\n5. プロジェクト分析とユーザー入力に基づいて、プロジェクトルートに Coastfile を生成します。\n6. プロジェクトに docker-compose.yml がない場合は、素のプロセス定義には [services.*] を使うか、依存関係のインストールに [coast.setup] を使用します。\n7. `coast build` を実行します。失敗した場合はエラーを確認し、ドキュメント(`coast search-docs \"\"`)を参照してトラブルシュートします。\n8. `coast run dev-1` を実行します。失敗した場合はエラーを確認し、ドキュメントを参照します。\n9. `coast ui` を実行して Coastguard ダッシュボードを開きます(これは作業完了時にユーザーが使用するものです)。\n", - "skills_prompt.txt": "# Coast Runtime\n\nこのプロジェクトでは、サービス、テスト、その他のランタイムコマンドを実行するために Coasts(コンテナ化されたランタイム)を使用します。ファイルシステムはホストとコンテナの間で共有されるため、どちらか一方で行ったファイル編集も即座に両方から見えるようになります。\n\n## Discovery\n\nセッション内で最初のランタイムコマンドを実行する前に、次を実行してください:\n\n coast lookup\n\nこれにより、インスタンス名、ポート、およびコマンド例が表示されます。以降のすべてのコマンドでは、出力にあるインスタンス名を使用してください。\n\n## What runs where\n\nファイルシステムは共有されているため、`coast exec` はコンテナランタイムが必要なもの(データベース、サービス、統合テスト)にだけ使用してください。それ以外はすべてホスト上で直接実行します。\n\n`coast exec` を使うもの:\n- 実行中のサービスが必要なテスト(サービスや db と統合されたユニットテスト、統合テスト、API テスト)\n- サービスの再起動や compose 操作\n- データベース、キャッシュ、その他のコンテナサービスとやり取りするもの\n\nホスト上で直接実行するもの:\n- リント、型チェック、フォーマット\n- Git 操作\n- Playwright とブラウザテスト\n- ホスト側依存関係のインストール (`npm install`, `pip install`)\n- ファイル検索、コード生成、静的解析\n\n例:\n\n coast exec -- sh -c \"cd && npm test\" # DB が必要\n npm run lint # ホストで問題なし\n npx playwright test # ホストで問題なし\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\n`coast lookup` が一致を返さない場合は、`coast ls` を実行して何が存在するか確認してください。\n\nこのプロジェクト用の未割り当ての Coast がすでに実行中であれば、新しく作成するよりも、まずそれに自分の worktree を割り当てることを優先してください:\n\n coast assign -w \n\nすでに使用中の Coast も `coast assign` で再割り当てできますが、現在のスロットを妨げることになるため、必ず先にユーザーへ確認してください。\n\n実行中の Coast がない場合は、作成前にユーザーへ確認してください — Coasts はメモリ消費が大きいことがあります:\n\n coast run -w \n\nインスタンスを作成する前に、プロジェクトはビルドされている必要があります。ビルドが存在しないために `coast run` が失敗した場合は、まず `coast build` を実行してください。\n\n## Coastfile setup\n\nプロジェクトにまだ Coastfile がない場合、または Coastfile を変更する必要がある場合は、まず Coastfile のドキュメントを読んでください:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nCoast の挙動を推測する前に、ドキュメントを確認してください:\n\n coast docs # すべてのドキュメントページを一覧表示\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # セマンティック検索\n\n## Rules\n\n- セッション内で最初のランタイムコマンドを実行する前に、必ず `coast lookup` を実行してください。\n- `coast exec` はコンテナランタイムが必要なものにだけ使用してください。\n- リント、型チェック、フォーマット、および git はホスト上で直接実行してください。\n- Coast の挙動を推測する前に `coast docs` または `coast search-docs` を使ってください。\n- プロジェクトが Coast を前提としている場合、ホスト上でサービスを直接実行しないでください。\n\n---\nname: coasts\ndescription: Inspect and control Coast instances for the current checkout. Use\n when the user says \"/coasts\", asks to assign or reassign a Coast, wants to\n run commands or read logs in the matching Coast, wants to create a new Coast,\n or explicitly asks to open Coast UI.\n---\n\n# Coasts\n\nCoast CLI を直接使用してください。ラッパーは追加しないでください。\n\n## Orient Yourself\n\nまず CLI とドキュメントを確認してください:\n\n coast # 使用可能なすべてのコマンドを表示\n coast docs # すべてのドキュメントページを一覧表示\n coast search-docs \"your question\" # セマンティック検索\n\nCoast の挙動について不明な点があれば、推測する前にドキュメントを読んでください:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\nリクエストを次のいずれかのモードに振り分けてください:\n\n1. **Use Coast** — `coast lookup` を実行し、その後、一致したインスタンスに対して `coast exec`、`coast ps`、または `coast logs` を使用します。\n2. **Create or Assign** — `coast ls` を実行し、その後 `coast run` で新しい Coast を作成するか、`coast assign` で既存のものの向き先を変更します。\n3. **Open UI** — `coast ui` を実行します。\n\n## What Runs Where\n\nホストと Coast はファイルシステムを共有しています。`coast exec` は、コンテナ内で実行中のサービスが必要なものにだけ使用してください。\n\n**`coast exec` を使うもの:**\n- 統合テスト、API テスト、その他データベースやサービスが必要なもの\n- サービスの再起動、compose 操作\n- コンテナ内にしかないプロセスとやり取りするコマンド\n\n**ホスト上で実行するもの:**\n- リント (`eslint`, `rubocop`, `golangci-lint`)\n- 型チェック (`tsc --noEmit`, `go vet`)\n- フォーマット (`prettier`, `gofmt`)\n- Git 操作\n- Playwright とブラウザテスト\n- 静的解析、コード生成\n- パッケージのインストール (`npm install`, `pip install`)\n\n## Create and Assign\n\n`coast lookup` が一致を返さない場合:\n\n1. `coast ls` を実行して利用可能なスロットを確認します。\n2. 作成と割り当てを 1 ステップで行うために、`coast run -w ` を優先してください。\n3. まだビルドが存在しない場合は、まず `coast build` を実行してください。\n4. 作成後、確認のために `coast lookup` を再実行してください。\n\n既存の Coast を別の worktree に切り替えたい場合:\n\n coast assign -w \n\nこれは、すでに割り当て済みまたはチェックアウト済みの Coast に対しても機能しますが、使用中のスロットを再割り当てする前には必ずユーザーへ確認してください。\n\n## Coastfile Setup\n\nプロジェクトで新規または変更された Coastfile が必要な場合は、まずドキュメントを読んでください:\n\n coast docs --path coastfiles/README.md\n\nCoastfile のドキュメントでは、compose 設定、ポート、ボリューム、シークレット、共有サービス、bare services、および継承を扱っています。\n\n## Safety Rules\n\n- 何か行動を起こす前に `coast lookup` を実行し、トポロジー変更後にも再度実行してください。\n- 既存のスロットを妨げる可能性がある場合、`coast assign`、`coast unassign`、または `coast checkout` の前に確認してください。\n- ユーザーが既存スロットの再割り当てを明示的に望んでいない限り、チェックアウト済みまたはすでに割り当て済みのものを再利用するより、新しい Coast を作成することを優先してください。\n- 推測する前に `coast docs` または `coast search-docs` を使ってください。\n", + "doc_ordering.txt": "# トップレベル\nREADME.md\nGETTING_STARTED.md\nSKILLS_FOR_HOST_AGENTS.md\n\n# Learn Coasts\nlearn-coasts-videos/README.md\nlearn-coasts-videos/coasts.md\nlearn-coasts-videos/ports.md\nlearn-coasts-videos/assign.md\nlearn-coasts-videos/checkout.md\nlearn-coasts-videos/volumes.md\nlearn-coasts-videos/secrets.md\nlearn-coasts-videos/getting-started.md\nlearn-coasts-videos/coast-ui.md\n\n# ハーネス\nharnesses/README.md\nharnesses/CODEX.md\nharnesses/CONDUCTOR.md\nharnesses/CLAUDE_CODE.md\nharnesses/CURSOR.md\nharnesses/T3_CODE.md\nharnesses/SHEP.md\nharnesses/MULTIPLE_HARNESSES.md\n\n# 概念と用語\nconcepts_and_terminology/README.md\nconcepts_and_terminology/COASTS.md\nconcepts_and_terminology/RUN.md\nconcepts_and_terminology/REMOVE.md\nconcepts_and_terminology/FILESYSTEM.md\nconcepts_and_terminology/DAEMON.md\nconcepts_and_terminology/CLI.md\nconcepts_and_terminology/COASTGUARD.md\nconcepts_and_terminology/PORTS.md\nconcepts_and_terminology/PRIMARY_PORT_AND_DNS.md\nconcepts_and_terminology/ASSIGN.md\nconcepts_and_terminology/CHECKOUT.md\nconcepts_and_terminology/LOOKUP.md\nconcepts_and_terminology/VOLUMES.md\nconcepts_and_terminology/SHARED_SERVICES.md\nconcepts_and_terminology/SECRETS.md\nconcepts_and_terminology/BUILDS.md\nconcepts_and_terminology/COASTFILE_TYPES.md\nconcepts_and_terminology/RUNTIMES_AND_SERVICES.md\nconcepts_and_terminology/BARE_SERVICES.md\nconcepts_and_terminology/MIXED_SERVICE_TYPES.md\nconcepts_and_terminology/LOGS.md\nconcepts_and_terminology/EXEC_AND_DOCKER.md\nconcepts_and_terminology/AGENT_SHELLS.md\nconcepts_and_terminology/MCP_SERVERS.md\nconcepts_and_terminology/PERFORMANCE_OPTIMIZATIONS.md\nconcepts_and_terminology/TROUBLESHOOTING.md\n\n# Coastfiles\ncoastfiles/README.md\ncoastfiles/PROJECT.md\ncoastfiles/WORKTREE_DIR.md\ncoastfiles/PORTS.md\ncoastfiles/SHARED_SERVICES.md\ncoastfiles/SERVICES.md\ncoastfiles/SECRETS.md\ncoastfiles/VOLUMES.md\ncoastfiles/ASSIGN.md\ncoastfiles/INHERITANCE.md\ncoastfiles/AGENT_SHELL.md\ncoastfiles/MCP.md\n\n# レシピ\nrecipes/README.md\nrecipes/FULLSTACK_MONOREPO.md\n", + "installation_prompt.txt": "あなたはこのプロジェクトに Coasts をインストールしています。Coast(コンテナ化されたホスト)は CLI ツールで、Docker-in-Docker コンテナを使用して、1 台のマシン上で複数の隔離された開発環境を実行します。各環境はそれぞれ独自のポート、ボリューム、ランタイムを持つため、並列の worktree ワークフローに最適です。\n\nあなたの仕事: このプロジェクトを分析し、Coastfile(プロジェクトルートに置く \"Coastfile\" という名前の TOML ファイル)を生成してください。\n\n=== ドキュメント ===\n\nCoast には CLI からアクセスできる組み込みドキュメントがあります。Coastfile を生成する前に、これらを使って Coastfile スキーマ全体、ボリューム戦略、assign の挙動、その他の設定オプションを理解してください。\n\nドキュメントツリーを参照:\n\n coast docs\n\nこれにより、完全なドキュメントツリーが出力されます。まず README ファイルを読むところから始めてください — 各トピックに適したドキュメントを見つけるためのインデックスが提供されています:\n\n coast docs --path README.md\n coast docs --path coastfiles/README.md\n coast docs --path concepts_and_terminology/README.md\n\n特定のドキュメントを読む:\n\n coast docs --path coastfiles/PROJECT.md\n coast docs --path coastfiles/VOLUMES.md\n\nドキュメントを検索(セマンティック検索 — 探している内容を自然言語で説明):\n\n coast search-docs \"how do volume strategies work\"\n coast search-docs \"shared postgres across instances\"\n coast search-docs \"secret injection from environment variables\"\n\nこれらのドキュメントを使って、このプロジェクトの Coastfile 設定について十分な情報に基づいた判断をしてください。coastfiles/ セクションでは、すべての Coastfile ディレクティブが詳細に解説されています。\n\n=== COASTFILE スキーマ(クイックリファレンス) ===\n\n[coast] — 必須。プロジェクトのメタデータ。\n\n name (string, required) コンテナ/ボリューム命名に使われるプロジェクト識別子。\n compose (string, optional) Coastfile からの相対パスで指定する docker-compose.yml のパス。\n runtime (string, optional) \"dind\"(デフォルト)、\"sysbox\"、または \"podman\"。\n root (string, optional) プロジェクトルートの上書き(相対または絶対)。\n worktree_dir (string or array, optional) git worktree 用のディレクトリまたはディレクトリ群(デフォルト: \".worktrees\")。単一の文字列または文字列の配列を受け付けます。実行時に既存の worktree から自動検出されます。\n\n[coast.setup] — 任意。DinD コンテナ自体をカスタマイズ。\n\n packages (array of strings) インストールする Alpine パッケージ(例: [\"nodejs\", \"npm\", \"git\"])。\n run (array of strings) セットアップ中に実行する任意のコマンド。\n\n[ports] — 必須(少なくとも 1 つ)。論理名からポート番号へのマップ。\n これらのポートは coast がチェックアウトされたときにホストへフォワードされます。\n\n 例:\n [ports]\n web = 3000\n api = 8080\n postgres = 5432\n\n[volumes.*] — 任意。ボリュームごとの設定。\n\n strategy \"isolated\"(デフォルト)または \"shared\"\n service このボリュームを所有する Compose サービス名。\n mount サービスコンテナ内のマウントパス。\n snapshot_source (isolated のみ) 既存のボリューム名からシード。\n\n 例:\n [volumes.postgres_data]\n strategy = \"isolated\"\n service = \"db\"\n mount = \"/var/lib/postgresql/data\"\n\n[secrets.*] — 任意。シークレットの抽出と注入。\n\n extractor \"file\"、\"env\"、\"command\"、または \"macos-keychain\"\n inject \"env:VAR_NAME\" または \"file:/path/in/container\"\n ttl 任意の有効期限(例: \"1h\"、\"30m\")。\n\n extractor 固有パラメータ:\n file: path = \"./path/to/secret\"\n env: var = \"HOST_ENV_VAR\"\n command: run = \"echo secret-value\"\n macos-keychain: item = \"keychain-item-name\"\n\n 例:\n [secrets.db_password]\n extractor = \"env\"\n var = \"DB_PASSWORD\"\n inject = \"env:DATABASE_PASSWORD\"\n\n[inject] — 任意。非シークレットのホストファイル/環境変数の注入。\n\n env フォワードするホスト環境変数名の配列。\n files マウントするホストファイルパスの配列。\n\n 例:\n [inject]\n env = [\"NODE_ENV\", \"DEBUG\"]\n files = [\"~/.ssh/id_ed25519\", \"~/.gitconfig\"]\n\n[shared_services.*] — 任意。ホストの Docker デーモン上で動作し、インスタンス間で共有されるサービス。\n\n image Docker イメージ。\n ports ポート番号の配列。\n volumes ボリュームマウントの配列。\n env 環境変数のインラインテーブル。\n auto_create_db (bool) インスタンスごとのデータベースを自動的に作成。\n inject 接続文字列を coast コンテナへ注入。\n\n 例:\n [shared_services.postgres]\n image = \"postgres:16-alpine\"\n ports = [5432]\n volumes = [\"postgres_data:/var/lib/postgresql/data\"]\n env = { POSTGRES_USER = \"dev\", POSTGRES_PASSWORD = \"dev\", POSTGRES_DB = \"app\" }\n auto_create_db = true\n inject = \"env:DATABASE_URL\"\n\n[assign] — 任意。ブランチ切り替え時(coast assign)の挙動を制御。\n\n default \"none\"、\"restart\"、または \"rebuild\"\n [assign.services] サービスごとの上書き。\n [assign.rebuild_triggers] 再ビルドをトリガーするサービスごとのファイル glob。\n\n 例:\n [assign]\n default = \"none\"\n [assign.services]\n api = \"restart\"\n worker = \"rebuild\"\n [assign.rebuild_triggers]\n worker = [\"Dockerfile\", \"package.json\"]\n\n[services.*] — 任意。プロセスのみのサービス(docker-compose 不要)。\n\n command 実行するシェルコマンド。\n port ポート番号。\n restart \"on-failure\" または \"always\"。\n\n 例:\n [services.web]\n command = \"node server.js\"\n port = 3000\n restart = \"on-failure\"\n\n=== 例: 最小(compose なし) ===\n\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[ports]\napp = 3000\n\n=== 例: docker-compose あり ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\npostgres = 5432\nredis = 6379\n\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n\n=== 例: secrets あり ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\n\n[secrets.api_key]\nextractor = \"env\"\nvar = \"API_KEY\"\ninject = \"env:API_KEY\"\n\n[secrets.ssh_key]\nextractor = \"file\"\npath = \"~/.ssh/id_ed25519\"\ninject = \"file:/run/secrets/ssh_key\"\n\n=== ユーザーと議論すべき主要なトレードオフ ===\n\nCoastfile を生成する前に、曖昧な設定の選択肢についてユーザーに確認してください。主なものは次のとおりです:\n\nデータベースおよびインフラ戦略 — postgres や redis のようなサービスには 3 つの選択肢があります:\n - 隔離ボリューム(デフォルト): 各 Coast インスタンスは DinD コンテナ内にデータのコピーをそれぞれ持ちます。インスタンス同士が干渉できません。ブランチごとの DB 状態が欲しい場合に最適です。\n - 共有ボリューム: すべてのインスタンスが DinD コンテナ内の同じボリュームを読み書きします。ディスク容量は節約できますが、複数インスタンスからの同時書き込みでデータが破損する可能性があります。\n - 共有サービス: 各 Coast 内ではなく、ホストの Docker デーモン上でデータベースを実行します。すべてのインスタンスは 1 つの共有サーバーに接続します。メモリ使用量が最小で、単一の postgres 上でインスタンスごとの DB を作る auto_create_db をサポートし、データはインスタンス削除後も残ります。大規模チームやメモリ制約のあるマシンに最適です。\n - プロジェクトにデータベースがある場合、どのアプローチにしたいかユーザーに確認してください。トレードオフを説明してください — 隔離が最も安全で、共有サービスが最もメモリ効率が良いです。\n\nAssign 戦略 — Coast を worktree 間で切り替えたときに何が起きるか:\n - \"none\": 何もしない(ブランチ間で変化しない postgres/redis のようなサービス向け)。\n - \"restart\": コンテナを再起動(プロセス再起動だけでよいインタプリタ系サービス向け)。\n - \"rebuild\": Docker イメージを再ビルドして再起動(ブランチ変更が Dockerfile やビルド依存に影響するサービス向け)。\n - プロジェクトに複数サービスがある場合、ブランチ切り替え時に再ビルドが必要なものと再起動でよいものをユーザーに確認してください。\n\n=== 手順 ===\n\n1. このプロジェクトの構成を確認します。docker-compose.yml がある場合はそれを読み、サービス、ポート、ボリュームを特定します。\n2. 既存の git worktree ディレクトリを検出します。`git worktree list` を実行し、プロジェクトがすでに git worktree を設定しているか確認します。\n - worktree が存在する場合、パスを調べて共通の親ディレクトリを特定します(例: worktree が `../.worktrees/feat-a` と `../.worktrees/feat-b` にあるなら、worktree_dir は `\"../.worktrees\"`)。\n - 検出したディレクトリに合わせて Coastfile の `worktree_dir` を設定します。\n - worktree が存在しない場合、`worktree_dir` は省略します(Coast のデフォルトは \".worktrees\")。\".coasts\" は使用しないでください — Coast ブランドのディレクトリでプロジェクトを汚染します。\n3. このプロジェクトで次のいずれかのコーディングハーネスを使っているか、ユーザーに確認します:\n - **Claude Code** — worktree は `.claude/worktrees`\n - **OpenAI Codex** — worktree は `~/.codex/worktrees`\n - **Cursor** — worktree は `~/.cursor/worktrees/`(`` は `[coast] name` の coast 名)\n - **Conductor** — worktree は `~/conductor/workspaces/`\n - **T3 Code** — worktree は `~/.t3/worktrees/`\n ユーザーが選んだ各ハーネスについて、その worktree ディレクトリを `worktree_dir` 配列に含めます。これをステップ 2 で検出したディレクトリと組み合わせます。ユーザーがどれも選ばず、かつステップ 2 で worktree が検出されなかった場合は、`worktree_dir` を省略します(Coast のデフォルトは \".worktrees\")。\n4. 関連する Coast ドキュメント(`coast docs` と `coast search-docs` を使用)を読み、ボリューム戦略、assign の挙動、このプロジェクトのスタックに適用される設定オプションを理解します。\n5. 曖昧な設定の選択肢についてユーザーに確認します(上記のトレードオフ参照)。推測しないでください — 選択肢を説明し、ユーザーに決めてもらいます。\n6. プロジェクト分析とユーザー入力に基づいて、プロジェクトルートに Coastfile を生成します。\n7. プロジェクトに docker-compose.yml がない場合は、素のプロセス定義には [services.*] を使うか、依存関係のインストールに [coast.setup] を使用します。\n8. `coast build` を実行します。失敗した場合はエラーを確認し、ドキュメント(`coast search-docs \"\"`)を参照してトラブルシュートします。\n9. `coast run dev-1` を実行します。失敗した場合はエラーを確認し、ドキュメントを参照します。\n10. `coast ui` を実行して Coastguard ダッシュボードを開きます(これは作業完了時にユーザーが使用するものです)。\n", + "skills_prompt.txt": "# Coast Runtime\n\nこのプロジェクトでは、サービス、テスト、その他のランタイムコマンドを実行するために Coasts(コンテナ化されたランタイム)を使用します。ファイルシステムはホストとコンテナの間で共有されるため、どちらか一方で行ったファイル編集も即座に両方から見えるようになります。\n\n## Discovery\n\nセッション内で最初のランタイムコマンドを実行する前に、次を実行してください:\n\n coast lookup\n\nこれにより、インスタンス名、ポート、およびコマンド例が表示されます。以降のすべてのコマンドでは、出力にあるインスタンス名を使用してください。\n\n## What runs where\n\nファイルシステムは共有されているため、`coast exec` はコンテナランタイムが必要なもの(データベース、サービス、統合テスト)にだけ使用してください。それ以外はすべてホスト上で直接実行します。\n\n`coast exec` を使うもの:\n- 実行中のサービスが必要なテスト(サービスや db と統合されたユニットテスト、統合テスト、API テスト)\n- サービスの再起動や compose 操作\n- データベース、キャッシュ、その他のコンテナサービスとやり取りするもの\n\nホスト上で直接実行するもの:\n- リント、型チェック、フォーマット\n- Git 操作\n- Playwright とブラウザテスト\n- ホスト側依存関係のインストール (`npm install`, `pip install`)\n- ファイル検索、コード生成、静的解析\n\n例:\n\n coast exec -- sh -c \"cd && npm test\" # DB が必要\n coast exec --service # サービスシェル\n npm run lint # ホストで問題なし\n npx playwright test # ホストで問題なし\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\n`coast lookup` が一致を返さない場合は、`coast ls` を実行して何が存在するか確認してください。\n\nこのプロジェクト用の未割り当ての Coast がすでに実行中であれば、新しく作成するよりも、まずそれに自分の worktree を割り当てることを優先してください:\n\n coast assign -w \n\nすでに使用中の Coast も `coast assign` で再割り当てできますが、現在のスロットを妨げることになるため、必ず先にユーザーへ確認してください。\n\n実行中の Coast がない場合は、作成前にユーザーへ確認してください — Coasts はメモリ消費が大きいことがあります:\n\n coast run -w \n\nインスタンスを作成する前に、プロジェクトはビルドされている必要があります。ビルドが存在しないために `coast run` が失敗した場合は、まず `coast build` を実行してください。\n\n## Coastfile setup\n\nプロジェクトにまだ Coastfile がない場合、または Coastfile を変更する必要がある場合は、まず Coastfile のドキュメントを読んでください:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nCoast の挙動を推測する前に、ドキュメントを確認してください:\n\n coast docs # すべてのドキュメントページを一覧表示\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # セマンティック検索\n\n## Rules\n\n- セッション内で最初のランタイムコマンドを実行する前に、必ず `coast lookup` を実行してください。\n- `coast exec` はコンテナランタイムが必要なものにだけ使用してください。\n- アプリ/サービスのコンテナ内で実行する必要がある場合は、`coast exec --service ` を使用してください。\n- リント、型チェック、フォーマット、および git はホスト上で直接実行してください。\n- Coast の挙動を推測する前に `coast docs` または `coast search-docs` を使ってください。\n- プロジェクトが Coast を前提としている場合、ホスト上でサービスを直接実行しないでください。\n\n---\nname: coasts\ndescription: Inspect and control Coast instances for the current checkout. Use\n when the user says \"/coasts\", asks to assign or reassign a Coast, wants to\n run commands or read logs in the matching Coast, wants to create a new Coast,\n or explicitly asks to open Coast UI.\n---\n\n# Coasts\n\nCoast CLI を直接使用してください。ラッパーは追加しないでください。\n\n## Orient Yourself\n\nまず CLI とドキュメントを確認してください:\n\n coast # 使用可能なすべてのコマンドを表示\n coast docs # すべてのドキュメントページを一覧表示\n coast search-docs \"your question\" # セマンティック検索\n\nCoast の挙動について不明な点があれば、推測する前にドキュメントを読んでください:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\nリクエストを次のいずれかのモードに振り分けてください:\n\n1. **Use Coast** — `coast lookup` を実行し、その後、一致したインスタンスに対して `coast exec`、`coast ps`、または `coast logs` を使用します。\n2. **Create or Assign** — `coast ls` を実行し、その後 `coast run` で新しい Coast を作成するか、`coast assign` で既存のものの向き先を変更します。\n3. **Open UI** — `coast ui` を実行します。\n\n## What Runs Where\n\nホストと Coast はファイルシステムを共有しています。`coast exec` は、コンテナ内で実行中のサービスが必要なものにだけ使用してください。\n\n**`coast exec` を使うもの:**\n- 統合テスト、API テスト、その他データベースやサービスが必要なもの\n- サービスの再起動、compose 操作\n- コンテナ内にしかないプロセスとやり取りするコマンド\n\n**ホスト上で実行するもの:**\n- リント (`eslint`, `rubocop`, `golangci-lint`)\n- 型チェック (`tsc --noEmit`, `go vet`)\n- フォーマット (`prettier`, `gofmt`)\n- Git 操作\n- Playwright とブラウザテスト\n- 静的解析、コード生成\n- パッケージのインストール (`npm install`, `pip install`)\n\n## Create and Assign\n\n`coast lookup` が一致を返さない場合:\n\n1. `coast ls` を実行して利用可能なスロットを確認します。\n2. 作成と割り当てを 1 ステップで行うために、`coast run -w ` を優先してください。\n3. まだビルドが存在しない場合は、まず `coast build` を実行してください。\n4. 作成後、確認のために `coast lookup` を再実行してください。\n\n既存の Coast を別の worktree に切り替えたい場合:\n\n coast assign -w \n\nこれは、すでに割り当て済みまたはチェックアウト済みの Coast に対しても機能しますが、使用中のスロットを再割り当てする前には必ずユーザーへ確認してください。\n\n## Coastfile Setup\n\nプロジェクトで新規または変更された Coastfile が必要な場合は、まずドキュメントを読んでください:\n\n coast docs --path coastfiles/README.md\n\nCoastfile のドキュメントでは、compose 設定、ポート、ボリューム、シークレット、共有サービス、bare services、および継承を扱っています。\n\n## Safety Rules\n\n- 何か行動を起こす前に `coast lookup` を実行し、トポロジー変更後にも再度実行してください。\n- 既存のスロットを妨げる可能性がある場合、`coast assign`、`coast unassign`、または `coast checkout` の前に確認してください。\n- ユーザーが既存スロットの再割り当てを明示的に望んでいない限り、チェックアウト済みまたはすでに割り当て済みのものを再利用するより、新しい Coast を作成することを優先してください。\n- 推測する前に `coast docs` または `coast search-docs` を使ってください。\n", "coastfiles/README.md": "# Coastfiles\n\nCoastfile は、プロジェクトのルートに配置される TOML 設定ファイルです。これは、そのプロジェクト用の分離された開発環境を構築して実行するために Coast が知る必要のあるすべての情報、つまり、どのサービスを実行するか、どのポートを転送するか、データをどのように扱うか、シークレットをどのように管理するかを Coast に伝えます。\n\nすべての Coast プロジェクトには、少なくとも 1 つの Coastfile が必要です。ファイル名は常に `Coastfile` です(大文字の C、拡張子なし)。異なるワークフロー向けのバリアントが必要な場合は、`Coastfile.light` や `Coastfile.snap` のような型付き Coastfile を作成し、[ベースを継承](INHERITANCE.md)します。\n\nCoastfile が Coast の他の部分とどのように関係しているかをより深く理解するには、[Coasts](../concepts_and_terminology/COASTS.md) と [Builds](../concepts_and_terminology/BUILDS.md) を参照してください。\n\n## Quickstart\n\n可能な限り最小の Coastfile:\n\n```toml\n[coast]\nname = \"my-app\"\n```\n\nこれにより、`coast exec` で入れる DinD コンテナが得られます。ほとんどのプロジェクトでは、`compose` 参照または [bare services](SERVICES.md) のいずれかが必要になります。\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\napi = 8080\n```\n\nあるいは、compose を使わずに bare services を使う場合:\n\n```toml\n[coast]\nname = \"my-app\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\nrestart = \"on-failure\"\n\n[ports]\nweb = 3000\n```\n\n`coast build` を実行してから `coast run dev-1` を実行すれば、分離された環境が得られます。\n\n## Example Coastfiles\n\n### Simple bare-service project\n\ncompose ファイルなしの Next.js アプリです。Coast が Node をインストールし、`npm install` を実行し、開発サーバーを直接起動します。\n\n```toml\n[coast]\nname = \"my-crm\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --turbopack --port 3002 --hostname 0.0.0.0\"\nport = 3002\nrestart = \"on-failure\"\n\n[ports]\nweb = 3002\n```\n\n### Full-stack compose project\n\n共有データベース、シークレット、ボリューム戦略、カスタムセットアップを備えたマルチサービスプロジェクトです。\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./infra/docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"python3\", \"curl\", \"git\", \"bash\", \"ca-certificates\", \"wget\"]\nrun = [\n \"ARCH=$(uname -m | sed 's/aarch64/arm64/' | sed 's/x86_64/amd64/') && wget -qO /tmp/go.tar.gz https://go.dev/dl/go1.24.1.linux-${ARCH}.tar.gz && tar -C /usr/local -xzf /tmp/go.tar.gz && rm /tmp/go.tar.gz\",\n \"GOBIN=/usr/local/bin go install github.com/air-verse/air@v1.61.7\",\n]\n\n[ports]\nweb = 3000\nbackend = 8080\npostgres = 5432\nredis = 6379\n\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\" }\n\n[shared_services.redis]\nimage = \"redis:7\"\nports = [6379]\n\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n\n[secrets.db_password]\nextractor = \"env\"\nvar = \"DB_PASSWORD\"\ninject = \"env:DB_PASSWORD\"\n\n[omit]\nservices = [\"monitoring\", \"admin-panel\", \"nginx-proxy\"]\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### Lightweight test variant (inheritance)\n\nベースの Coastfile を拡張しつつ、バックエンドテストの実行に必要なものだけに絞り込みます。ポートなし、共有サービスなし、分離データベースです。\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n\n[unset]\nports = [\"web\", \"backend\", \"postgres\", \"redis\"]\nshared_services = [\"postgres\", \"redis\"]\n\n[omit]\nservices = [\"redis\", \"backend\", \"web\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend-test = \"rebuild\"\n```\n\n### Snapshot-seeded variant\n\n各 coast インスタンスは、ホスト上にある既存のデータベースボリュームのコピーから開始し、その後はそれぞれ独立して分岐します。\n\n```toml\n[coast]\nextends = \"Coastfile\"\n\n[unset]\nshared_services = [\"postgres\", \"redis\", \"mongodb\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_mongodb_data\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n\n## Conventions\n\n- ファイル名は `Coastfile` でなければならず(大文字の C、拡張子なし)、プロジェクトルートに配置する必要があります。\n- 型付きバリアントは `Coastfile.{type}` というパターンを使います。たとえば `Coastfile.light`、`Coastfile.snap` です。[Inheritance and Types](INHERITANCE.md) を参照してください。\n- 予約名 `Coastfile.default` は使用できません。\n- 全体を通して TOML 構文を使用します。すべてのセクションヘッダーは `[brackets]` を使用し、名前付きエントリは `[section.name]` を使用します(array-of-tables ではありません)。\n- 同じ Coastfile 内で `compose` と `[services]` の両方を使うことはできません。どちらか一方を選んでください。\n- 相対パス(`compose`、`root` など)は、Coastfile の親ディレクトリを基準に解決されます。\n\n## Reference\n\n| Page | Sections | What it covers |\n|------|----------|----------------|\n| [Project and Setup](PROJECT.md) | `[coast]`, `[coast.setup]` | 名前、compose パス、ランタイム、worktree ディレクトリ、コンテナセットアップ |\n| [Worktree Directories](WORKTREE_DIR.md) | `worktree_dir`, `default_worktree_dir` | ローカルおよび外部 worktree ディレクトリ、チルダパス、Codex/Claude 統合 |\n| [Ports](PORTS.md) | `[ports]`, `[egress]` | ポート転送、egress 宣言、プライマリポート |\n| [Volumes](VOLUMES.md) | `[volumes.*]` | 分離、共有、スナップショットシードのボリューム戦略 |\n| [Shared Services](SHARED_SERVICES.md) | `[shared_services.*]` | ホストレベルのデータベースおよびインフラサービス |\n| [Secrets](SECRETS.md) | `[secrets.*]`, `[inject]` | シークレットの抽出、注入、ホスト環境/ファイル転送 |\n| [Bare Services](SERVICES.md) | `[services.*]` | Docker Compose を使わずにプロセスを直接実行する方法 |\n| [Agent Shell](AGENT_SHELL.md) | `[agent_shell]` | コンテナ化されたエージェント TUI ランタイム |\n| [MCP Servers](MCP.md) | `[mcp.*]`, `[mcp_clients.*]` | 内部およびホストプロキシ型 MCP サーバー、クライアントコネクタ |\n| [Assign](ASSIGN.md) | `[assign]` | サービスごとのブランチ切り替え動作 |\n| [Inheritance and Types](INHERITANCE.md) | `extends`, `includes`, `[unset]`, `[omit]` | 型付き Coastfile、構成、およびオーバーライド |\n", "coastfiles/AGENT_SHELL.md": "# Agent Shell\n\n> **ほとんどのワークフローでは、コーディングエージェントをコンテナ化する必要はありません。** Coasts はホストマシンと [filesystem](../concepts_and_terminology/FILESYSTEM.md) を共有するため、最もシンプルな方法はホスト上でエージェントを実行し、統合テストのような実行時負荷の高いタスクには [`coast exec`](../concepts_and_terminology/EXEC_AND_DOCKER.md) を使うことです。エージェントシェルは、エージェントをコンテナ内で動かしたい場合 — たとえば内部の Docker デーモンへ直接アクセスさせたい場合や、環境を完全に隔離したい場合 — に利用します。\n\n`[agent_shell]` セクションは、Claude Code や Codex のようなエージェント TUI を Coast コンテナ内で実行するように設定します。これが存在する場合、Coast はインスタンス起動時に、設定されたコマンドを実行する永続的な PTY セッションを自動的に起動します。\n\nエージェントシェルの動作(アクティブなエージェントモデル、入力の送信、ライフサイクルと復旧)を含む全体像については、[Agent Shells](../concepts_and_terminology/AGENT_SHELLS.md) を参照してください。\n\n## Configuration\n\nこのセクションには必須フィールドが 1 つあります: `command`。\n\n```toml\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\n### `command` (required)\n\nエージェント PTY で実行するシェルコマンドです。通常は `[coast.setup]` でインストールしたコーディングエージェントの CLI になります。\n\nコマンドは DinD コンテナ内の `/workspace`(プロジェクトルート)で実行されます。compose サービスではありません — compose スタックや素のサービスと並行して動作し、それらの中で動くわけではありません。\n\n## Lifecycle\n\n- エージェントシェルは `coast run` で自動的に起動します。\n- [Coastguard](../concepts_and_terminology/COASTGUARD.md) では、閉じることのできない永続的な「Agent」タブとして表示されます。\n- エージェントプロセスが終了した場合、Coast はそれを再起動できます。\n- 実行中のエージェントシェルへは `coast agent-shell input` を通して入力を送信できます。\n\n## Examples\n\n### Claude Code\n\n`[coast.setup]` で Claude Code をインストールし、[secrets](SECRETS.md) で認証情報を設定してから、エージェントシェルを設定します:\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"git\", \"bash\"]\nrun = [\n \"npm install -g @anthropic-ai/claude-code\",\n \"mkdir -p /root/.claude\",\n]\n\n[secrets.claude_credentials]\nextractor = \"keychain\"\nservice = \"Claude Code-credentials\"\ninject = \"file:/root/.claude/.credentials.json\"\n\n[agent_shell]\ncommand = \"cd /workspace; exec claude --dangerously-skip-permissions --effort high\"\n```\n\n### Simple agent shell\n\n機能が動作することをテストするための最小限のエージェントシェル:\n\n```toml\n[coast]\nname = \"test-agent\"\n\n[coast.setup]\npackages = [\"bash\"]\n\n[agent_shell]\ncommand = \"exec sh -c 'while true; do echo agent-heartbeat; sleep 5; done'\"\n```\n", "coastfiles/ASSIGN.md": "# Assign\n\n`[assign]` セクションは、`coast assign` でブランチを切り替えるときに、Coast インスタンス内のサービスがどう扱われるかを制御します。各サービスは、フルリビルドが必要か、再起動が必要か、ホットリロードが必要か、あるいは何もしないかに応じて、異なる戦略で設定できます。\n\n実行時に `coast assign` と `coast unassign` がどのように動作するかについては、[Assign](../concepts_and_terminology/ASSIGN.md) を参照してください。\n\n## `[assign]`\n\n### `default`\n\nブランチ切り替え時に、すべてのサービスに適用されるデフォルトのアクションです。`[assign]` セクション全体が省略された場合、デフォルトは `\"restart\"` になります。\n\n- **`\"none\"`** — 何もしません。サービスはそのまま実行され続けます。コードに依存しないデータベースやキャッシュに適しています。\n- **`\"hot\"`** — コードはすでに [filesystem](../concepts_and_terminology/FILESYSTEM.md) によってライブマウントされているため、サービスは(ファイルウォッチャーやホットリロードなどにより)変更を自動的に取り込みます。コンテナの再起動は不要です。\n- **`\"restart\"`** — サービスコンテナを再起動します。サービスが起動時にコードを読み込むが、完全なイメージのリビルドまでは不要な場合に使用します。\n- **`\"rebuild\"`** — サービスの Docker イメージをリビルドして再起動します。Dockerfile の `COPY` や `ADD` によってコードがイメージに焼き込まれている場合に必要です。\n\n```toml\n[assign]\ndefault = \"none\"\n```\n\n### `[assign.services]`\n\nサービスごとの上書き設定です。各キーは compose のサービス名で、値は上記 4 つのアクションのいずれかです。\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\nこれにより、データベースやキャッシュは(デフォルトで `\"none\"` として)手を触れずに、変更されたコードに依存するサービスだけをリビルドまたは再起動できます。\n\n### `[assign.rebuild_triggers]`\n\nデフォルトのアクションがより軽いものになっていても、特定サービスについてリビルドを強制するファイルパターンです。各キーはサービス名で、値はファイルパスまたはパターンのリストです。\n\n```toml\n[assign]\ndefault = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\", \"package-lock.json\"]\n```\n\n### `exclude_paths`\n\n`coast assign` 中の worktree 同期から除外するパスのリストです。大規模なモノレポで、特定のディレクトリが Coast 上で動作しているサービスと無関係であり、割り当て操作(assign)を遅くしてしまう場合に有用です。\n\n```toml\n[assign]\ndefault = \"none\"\nexclude_paths = [\"apps/ide\", \"apps/extension\", \"apps/ide-extension\"]\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n## Examples\n\n### Rebuild app, leave everything else alone\n\napp サービスがコードを Docker イメージに焼き込む一方で、データベースがコード変更から独立している場合:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\n### Hot-reload frontend and backend\n\n両サービスがファイルウォッチャー(例: Next.js dev server、Go air、nodemon)を使用しており、コードがライブマウントされている場合:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### Per-service rebuild with triggers\n\nAPI サービスは通常は再起動のみですが、`Dockerfile` または `package.json` が変更された場合はリビルドします:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napi = \"restart\"\nworker = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\"]\n```\n\n### Full rebuild for everything\n\nすべてのサービスがコードをイメージに焼き込む場合:\n\n```toml\n[assign]\ndefault = \"rebuild\"\n```\n", @@ -1188,19 +1205,19 @@ "coastfiles/SERVICES.md": "# ベアサービス\n\n> **注:** ベアサービスは、プレーンなプロセスとして Coast コンテナ内で直接実行されます — コンテナ化されません。サービスがすでに Docker 化されている場合は、代わりに `compose` を使用してください。ベアサービスは、Dockerfile や docker-compose.yml を書くオーバーヘッドを省きたいシンプルな構成に最適です。\n\n`[services.*]` セクションは、Coast が Docker Compose を使わずに DinD コンテナ内で直接実行するプロセスを定義します。これは `compose` ファイルを使う代替手段です — 同じ Coastfile 内で両方を使うことはできません。\n\nベアサービスは Coast によって監督され、ログの取得と任意の再起動ポリシーが提供されます。ベアサービスの動作方法、制限、そして compose へ移行すべきタイミングについてのより深い背景は、[Bare Services](../concepts_and_terminology/BARE_SERVICES.md) を参照してください。\n\n## サービスの定義\n\n各サービスは `[services]` 配下の名前付き TOML セクションです。`command` フィールドは必須です。\n\n```toml\n[services.web]\ncommand = \"node server.js\"\nport = 3000\n```\n\n### `command`(必須)\n\n実行するシェルコマンド。空または空白のみであってはなりません。\n\n```toml\n[services.web]\ncommand = \"npx next dev --turbopack --port 3000 --hostname 0.0.0.0\"\n```\n\n### `port`\n\nサービスがリッスンするポート。ヘルスチェックおよびポートフォワーディング連携に使用されます。指定する場合は 0 以外でなければなりません。\n\n```toml\n[services.web]\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\n```\n\n### `restart`\n\nプロセスが終了した場合の再起動ポリシー。デフォルトは `\"no\"` です。\n\n- `\"no\"` — 再起動しない\n- `\"on-failure\"` — プロセスが非ゼロコードで終了した場合のみ再起動する\n- `\"always\"` — 常に再起動する\n\n```toml\n[services.web]\ncommand = \"node server.js\"\nport = 3000\nrestart = \"on-failure\"\n```\n\n### `install`\n\nサービス開始前に実行するコマンド(例: 依存関係のインストール)。単一の文字列または文字列配列を受け付けます。\n\n```toml\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\n```\n\n```toml\n[services.web]\ninstall = [\"npm install\", \"npm run build\"]\ncommand = \"npm start\"\nport = 3000\n```\n\n## compose との相互排他\n\nCoastfile は `compose` と `[services]` の両方を定義できません。`[coast]` に `compose` フィールドがある場合、任意の `[services.*]` セクションを追加するとエラーになります。Coastfile ごとにどちらか一方のアプローチを選んでください。\n\ncompose 経由でコンテナ化するサービスと、ベアで動かすサービスを混在させたい場合でも、すべて compose を使用してください — ベアサービスから compose へ移行する方法は、[Bare Services の移行ガイダンス](../concepts_and_terminology/BARE_SERVICES.md) を参照してください。\n\n## 例\n\n### 単一サービスの Next.js アプリ\n\n```toml\n[coast]\nname = \"my-frontend\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --turbopack --port 3002 --hostname 0.0.0.0\"\nport = 3002\nrestart = \"on-failure\"\n\n[ports]\nweb = 3002\n```\n\n### バックグラウンドワーカー付き Web サーバー\n\n```toml\n[coast]\nname = \"my-app\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"node server.js\"\nport = 3000\nrestart = \"on-failure\"\n\n[services.worker]\ncommand = \"node worker.js\"\nrestart = \"always\"\n\n[ports]\nweb = 3000\n```\n\n### 複数ステップの install を伴う Python サービス\n\n```toml\n[coast]\nname = \"ml-service\"\n\n[coast.setup]\npackages = [\"python3\", \"py3-pip\"]\n\n[services.api]\ninstall = [\"pip install -r requirements.txt\", \"python manage.py migrate\"]\ncommand = \"python manage.py runserver 0.0.0.0:8000\"\nport = 8000\nrestart = \"on-failure\"\n\n[ports]\napi = 8000\n```\n", "coastfiles/SHARED_SERVICES.md": "# 共有サービス\n\n`[shared_services.*]` セクションは、個々の Coast コンテナ内部ではなくホストの Docker デーモン上で実行されるインフラサービス(データベース、キャッシュ、メッセージブローカー)を定義します。複数の Coast インスタンスは、ブリッジネットワーク経由で同じ共有サービスに接続します。\n\n共有サービスが実行時にどのように動作するか、ライフサイクル管理、トラブルシューティングについては、[Shared Services](../concepts_and_terminology/SHARED_SERVICES.md) を参照してください。\n\n## 共有サービスの定義\n\n各共有サービスは、`[shared_services]` 配下の名前付き TOML セクションです。`image` フィールドは必須で、それ以外はすべて任意です。\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\n```\n\n### `image`(必須)\n\nホストのデーモン上で実行する Docker イメージ。\n\n### `ports`\n\nサービスが公開するポートの一覧。Coast は、コンテナポートのみの指定、または Docker Compose スタイルの `\"HOST:CONTAINER\"` マッピングのいずれも受け付けます。\n\n```toml\n[shared_services.redis]\nimage = \"redis:7-alpine\"\nports = [6379]\n```\n\n```toml\n[shared_services.postgis]\nimage = \"ghcr.io/baosystems/postgis:12-3.3\"\nports = [\"5433:5432\"]\n```\n\n- `6379` のような整数のみの指定は、`\"6379:6379\"` の省略形です。\n- `\"5433:5432\"` のようなマッピング文字列は、共有サービスをホストポート `5433` で公開しつつ、Coast 内部からは `service-name:5432` で到達可能なままにします。\n- ホストポートとコンテナポートは、どちらも 0 以外でなければなりません。\n\n### `volumes`\n\nデータ永続化のための Docker ボリュームのバインド文字列。これらはホストレベルの Docker ボリュームであり、Coast が管理するボリュームではありません。\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\n```\n\n### `env`\n\nサービスコンテナに渡される環境変数。\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\", POSTGRES_DB = \"mydb\" }\n```\n\n### `auto_create_db`\n\n`true` の場合、Coast は各 Coast インスタンスごとに、共有サービス内にインスタンス単位のデータベースを自動作成します。デフォルトは `false` です。\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\nauto_create_db = true\n```\n\n### `inject`\n\n共有サービスの接続情報を、環境変数またはファイルとして Coast インスタンスへ注入します。[secrets](SECRETS.md) と同じ `env:NAME` または `file:/path` 形式を使用します。\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\ninject = \"env:DATABASE_URL\"\n```\n\n## ライフサイクル\n\n共有サービスは、それらを参照する最初の Coast インスタンスが実行されたときに自動的に開始します。`coast stop` や `coast rm` を跨いでも稼働し続けます。インスタンスを削除しても共有サービスのデータには影響しません。共有サービスを停止して削除するのは `coast shared rm` のみです。\n\n`auto_create_db` によって作成されたインスタンス単位のデータベースも、インスタンス削除後に残ります。サービスとそのデータを完全に削除するには `coast shared-services rm` を使用してください。\n\n## 共有サービスとボリュームの使い分け\n\n複数の Coast インスタンスが同じデータベースサーバーに接続する必要がある場合(例:共有 Postgres を用意し、各インスタンスに専用データベースを割り当てる)は共有サービスを使用してください。compose 内部のサービスのデータを共有するか隔離するかを制御したい場合は、[ボリューム戦略](VOLUMES.md) を使用してください。\n\n## 例\n\n### Postgres、Redis、MongoDB\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\", POSTGRES_MULTIPLE_DATABASES = \"dev_db,test_db\" }\n\n[shared_services.redis]\nimage = \"redis:7\"\nports = [6379]\nvolumes = [\"infra_redis_data:/data\"]\n\n[shared_services.mongodb]\nimage = \"mongo:latest\"\nports = [27017]\nvolumes = [\"infra_mongodb_data:/data/db\"]\nenv = { MONGO_INITDB_ROOT_USERNAME = \"myapp\", MONGO_INITDB_ROOT_PASSWORD = \"myapp_pass\" }\n```\n\n### 最小構成の共有 Postgres\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16-alpine\"\nports = [5432]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\", POSTGRES_DB = \"coast_demo\" }\n```\n\n### ホスト/コンテナをマッピングした共有 Postgres\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16-alpine\"\nports = [\"5433:5432\"]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\", POSTGRES_DB = \"coast_demo\" }\n```\n\n### データベースを自動作成する共有サービス\n\n```toml\n[shared_services.db]\nimage = \"postgres:16-alpine\"\nports = [5432]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\" }\nauto_create_db = true\n```\n", "coastfiles/VOLUMES.md": "# ボリューム\n\n`[volumes.*]` セクションは、名前付き Docker ボリュームが Coast インスタンス間でどのように扱われるかを制御します。各ボリュームは、インスタンスがデータを共有するか、独立したコピーを持つかを決定する戦略で設定されます。\n\n共有サービスを代替案として含む Coast におけるデータ分離の全体像については、[Volumes](../concepts_and_terminology/VOLUMES.md) を参照してください。\n\n## ボリュームの定義\n\n各ボリュームは `[volumes]` 配下の名前付き TOML セクションです。3 つのフィールドが必須です。\n\n- **`strategy`** — `\"isolated\"` または `\"shared\"`\n- **`service`** — このボリュームを使用する compose のサービス名\n- **`mount`** — ボリュームのコンテナ内マウントパス\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## 戦略\n\n### `isolated`\n\n各 Coast インスタンスは独立したボリュームを持ちます。データはインスタンス間で共有されません。ボリュームは `coast run` で作成され、`coast rm` で削除されます。\n\n```toml\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n```\n\nこれはほとんどのデータベース用ボリュームに適した選択です。各インスタンスはクリーンスレートから開始し、他のインスタンスに影響を与えることなく自由にデータを変更できます。\n\n### `shared`\n\nすべての Coast インスタンスが単一の Docker ボリュームを使用します。あるインスタンスが書き込んだデータは、他のすべてのインスタンスから参照できます。\n\n```toml\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n```\n\n共有ボリュームは `coast rm` では決して削除されません。手動で削除するまで永続します。\n\nデータベースのようなサービスにアタッチされたボリュームで `shared` を使用している場合、Coast はビルド時に警告を出力します。単一のデータベースボリュームを複数の同時実行インスタンスで共有すると、破損を引き起こす可能性があります。共有データベースが必要な場合は、代わりに [shared services](SHARED_SERVICES.md) を使用してください。\n\n共有ボリュームの良い用途: 依存関係キャッシュ(Go modules、npm cache、pip cache)、ビルド成果物キャッシュ、そして同時書き込みが安全、または起こりにくいその他のデータ。\n\n## スナップショットのシーディング\n\n分離ボリュームは、インスタンス作成時に `snapshot_source` を使って既存の Docker ボリュームからシードできます。ソースボリュームのデータが新しい分離ボリュームにコピーされ、その後は独立して分岐します。\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n`snapshot_source` は `strategy = \"isolated\"` の場合にのみ有効です。共有ボリュームに設定するとエラーになります。\n\nこれは、各 Coast インスタンスをホストの開発用データベースからコピーした現実的なデータセットで開始したい一方で、インスタンスがそのデータを自由に変更してもソースや他のインスタンスに影響を与えないようにしたい場合に有用です。\n\n## 例\n\n### 分離データベース、共有の依存関係キャッシュ\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n```\n\n### スナップショットでシードされたフルスタック\n\n各インスタンスはホスト上の既存のデータベースボリュームのコピーから開始し、その後は独立して分岐します。\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_mongodb_data\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n\n### インスタンスごとにクリーンなデータベースを持つテストランナー\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"test-redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n", - "coastfiles/WORKTREE_DIR.md": "# Worktree ディレクトリ\n\n`[coast]` の `worktree_dir` フィールドは、git worktree をどこに配置するかを制御します。Coast は git worktree を使用して、フルのリポジトリを複製することなく、各インスタンスに異なるブランチ上のコードベースの独自コピーを持たせます。\n\n## 構文\n\n`worktree_dir` は単一の文字列または文字列の配列を受け取ります:\n\n```toml\n# Single directory (default)\nworktree_dir = \".worktrees\"\n\n# Multiple directories\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\n省略した場合、デフォルトは `\".worktrees\"` です。\n\n## パスタイプ\n\n### 相対パス\n\n`~/` または `/` で始まらないパスは、プロジェクトルートを基準に解決されます。これらが最も一般的で、特別な処理は不要です — これらはプロジェクトディレクトリ内にあり、標準の `/host-project` バインドマウントを通じて Coast コンテナ内で自動的に利用可能です。\n\n```toml\nworktree_dir = \".worktrees\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### チルダパス(外部)\n\n`~/` で始まるパスはユーザーのホームディレクトリに展開され、**外部** worktree ディレクトリとして扱われます。Coast は、コンテナがそれらにアクセスできるように別個のバインドマウントを追加します。\n\n```toml\nworktree_dir = [\"~/.codex/worktrees\", \".worktrees\"]\n```\n\nこれは、OpenAI Codex のようにプロジェクトルート外に worktree を作成するツールと統合する方法です(Codex は常に `$CODEX_HOME/worktrees` に worktree を作成します)。\n\n### 絶対パス(外部)\n\n`/` で始まるパスも外部として扱われ、専用のバインドマウントを取得します。\n\n```toml\nworktree_dir = [\"/shared/worktrees\", \".worktrees\"]\n```\n\n## 外部ディレクトリの動作\n\nCoast が外部 worktree ディレクトリ(チルダパスまたは絶対パス)を検出すると、3 つのことが起こります:\n\n1. **コンテナのバインドマウント** — コンテナ作成時(`coast run`)に、解決されたホストパスが `/host-external-wt/{index}` にバインドマウントされます。ここで `{index}` は `worktree_dir` 配列内の位置です。これにより、外部ファイルがコンテナ内からアクセス可能になります。\n\n2. **プロジェクトのフィルタリング** — 外部ディレクトリには複数のプロジェクトの worktree が含まれている可能性があります。Coast は `git worktree list --porcelain`(本質的に現在のリポジトリにスコープされたもの)を使って、このプロジェクトに属する worktree のみを検出します。git watcher も、各 worktree の `.git` ファイルを読み取り、その `gitdir:` ポインタが現在のリポジトリに解決されることを確認することで所有関係を検証します。\n\n3. **ワークスペースの再マウント** — 外部 worktree に対して `coast assign` すると、Coast は通常の `/host-project/{dir}/{name}` の代わりに、外部バインドマウントパスから `/workspace` を再マウントします。\n\n## 外部 worktree の命名\n\nブランチがチェックアウトされている外部 worktree は、ローカル worktree と同様にブランチ名で表示されます。\n\n**detached HEAD** 上の外部 worktree(Codex で一般的)は、外部ディレクトリ内での相対パスを使って表示されます。たとえば、`~/.codex/worktrees/a0db/coastguard-platform` にある Codex worktree は、UI と CLI では `a0db/coastguard-platform` として表示されます。\n\n## `default_worktree_dir`\n\nCoast が**新しい** worktree を作成する際に使用するディレクトリを制御します(たとえば、既存の worktree がないブランチを割り当てる場合)。デフォルトでは `worktree_dir` の最初のエントリです。\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\ndefault_worktree_dir = \".worktrees\"\n```\n\n外部ディレクトリが新しい worktree の作成に使われることはありません — Coast は常にローカル(相対)ディレクトリに worktree を作成します。`default_worktree_dir` フィールドが必要なのは、デフォルト(最初のエントリ)を上書きしたい場合だけです。\n\n## 例\n\n### Codex 統合\n\nOpenAI Codex は `~/.codex/worktrees/{hash}/{project-name}` に worktree を作成します。これらを Coast で可視化し、割り当て可能にするには:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nこれを追加すると、Codex の worktree が checkout モーダルおよび `coast ls` の出力に表示されるようになります。Coast インスタンスを Codex worktree に割り当てて、そのコードをフル開発環境で実行できます。\n\n注意: 外部ディレクトリを追加した後でバインドマウントを有効にするには、コンテナを再作成する必要があります(`coast run`)。既存インスタンスを再起動するだけでは不十分です。\n\n### Claude Code 統合\n\nClaude Code はプロジェクト内の `.claude/worktrees/` に worktree を作成します。これは相対パス(プロジェクトルート内)なので、他のローカル worktree ディレクトリと同様に動作します — 外部マウントは不要です:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### 3 つすべてを組み合わせる\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\n## Live Coastfile 読み取り\n\nCoastfile 内の `worktree_dir` への変更は、worktree の**一覧表示**には即座に反映されます(API と git watcher は、キャッシュされたビルドアーティファクトだけでなく、ディスク上の最新の Coastfile を読み取ります)。ただし、外部の**バインドマウント**はコンテナ作成時にのみ作成されるため、新しく追加した外部ディレクトリをマウント可能にするにはインスタンスを再作成する必要があります。\n", + "coastfiles/WORKTREE_DIR.md": "# Worktree ディレクトリ\n\n`[coast]` の `worktree_dir` フィールドは、git worktree をどこに配置するかを制御します。Coast は git worktree を使用して、フルのリポジトリを複製することなく、各インスタンスに異なるブランチ上のコードベースの独自コピーを持たせます。\n\n## 構文\n\n`worktree_dir` は単一の文字列または文字列の配列を受け取ります:\n\n```toml\n# Single directory (default)\nworktree_dir = \".worktrees\"\n\n# Multiple directories\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\n省略した場合、デフォルトは `\".worktrees\"` です。\n\n## パスタイプ\n\n### 相対パス\n\n`~/` または `/` で始まらないパスは、プロジェクトルートを基準に解決されます。これらが最も一般的で、特別な処理は不要です — これらはプロジェクトディレクトリ内にあり、標準の `/host-project` バインドマウントを通じて Coast コンテナ内で自動的に利用可能です。\n\n```toml\nworktree_dir = \".worktrees\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### チルダパス(外部)\n\n`~/` で始まるパスはユーザーのホームディレクトリに展開され、**外部** worktree ディレクトリとして扱われます。Coast は、コンテナがそれらにアクセスできるように別個のバインドマウントを追加します。\n\n```toml\nworktree_dir = [\"~/.codex/worktrees\", \".worktrees\"]\n```\n\nこれは、OpenAI Codex のようにプロジェクトルート外に worktree を作成するツールと統合する方法です(Codex は常に `$CODEX_HOME/worktrees` に worktree を作成します)。\n\n### 絶対パス(外部)\n\n`/` で始まるパスも外部として扱われ、専用のバインドマウントを取得します。\n\n```toml\nworktree_dir = [\"/shared/worktrees\", \".worktrees\"]\n```\n\n### グロブパターン(外部)\n\n外部パスにはグロブのメタ文字(`*`、`?`、`[...]`)を含めることができます。Coast はこれらを実行時にホストのファイルシステムに対して展開し、一致した各ディレクトリごとにバインドマウントを作成します。\n\n```toml\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\nこれは、ツールがプロジェクトごとに変化するパス要素(ハッシュのようなもの)の下に worktree を生成する場合に便利です。`*` は任意の単一ディレクトリ名に一致するため、`~/.shep/repos/*/wt` は `~/.shep/repos/a21f0cda9ab9d456/wt` や、`wt` サブディレクトリを含む他の任意のハッシュディレクトリに一致します。\n\nサポートされるグロブ構文:\n\n- `*` — 単一のパス要素内の任意の文字列に一致\n- `?` — 任意の 1 文字に一致\n- `[abc]` — 集合内の任意の 1 文字に一致\n- `[!abc]` — 集合に含まれない任意の 1 文字に一致\n\nグロブ展開は、worktree ディレクトリが解決されるすべての場所で行われます: コンテナ作成、assign、start、lookup、および git watcher。結果は決定的な順序になるようソートされます。グロブがどのディレクトリにも一致しない場合は、黙ってスキップされます。\n\n他の外部パスと同様に、グロブパターンを追加した後でバインドマウントを有効にするには、コンテナを再作成する必要があります(`coast run`)。\n\n## 外部ディレクトリの動作\n\nCoast が外部 worktree ディレクトリ(チルダパスまたは絶対パス)を検出すると、3 つのことが起こります:\n\n1. **コンテナのバインドマウント** — コンテナ作成時(`coast run`)に、解決されたホストパスが `/host-external-wt/{index}` にバインドマウントされます。ここで `{index}` は `worktree_dir` 配列内の位置です。これにより、外部ファイルがコンテナ内からアクセス可能になります。\n\n2. **プロジェクトのフィルタリング** — 外部ディレクトリには複数のプロジェクトの worktree が含まれている可能性があります。Coast は `git worktree list --porcelain`(本質的に現在のリポジトリにスコープされたもの)を使って、このプロジェクトに属する worktree のみを検出します。git watcher も、各 worktree の `.git` ファイルを読み取り、その `gitdir:` ポインタが現在のリポジトリに解決されることを確認することで所有関係を検証します。\n\n3. **ワークスペースの再マウント** — 外部 worktree に対して `coast assign` すると、Coast は通常の `/host-project/{dir}/{name}` の代わりに、外部バインドマウントパスから `/workspace` を再マウントします。\n\n## 外部 worktree の命名\n\nブランチがチェックアウトされている外部 worktree は、ローカル worktree と同様にブランチ名で表示されます。\n\n**detached HEAD** 上の外部 worktree(Codex で一般的)は、外部ディレクトリ内での相対パスを使って表示されます。たとえば、`~/.codex/worktrees/a0db/coastguard-platform` にある Codex worktree は、UI と CLI では `a0db/coastguard-platform` として表示されます。\n\n## `default_worktree_dir`\n\nCoast が**新しい** worktree を作成する際に使用するディレクトリを制御します(たとえば、既存の worktree がないブランチを割り当てる場合)。デフォルトでは `worktree_dir` の最初のエントリです。\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\ndefault_worktree_dir = \".worktrees\"\n```\n\n外部ディレクトリが新しい worktree の作成に使われることはありません — Coast は常にローカル(相対)ディレクトリに worktree を作成します。`default_worktree_dir` フィールドが必要なのは、デフォルト(最初のエントリ)を上書きしたい場合だけです。\n\n## 例\n\n### Codex 統合\n\nOpenAI Codex は `~/.codex/worktrees/{hash}/{project-name}` に worktree を作成します。これらを Coast で可視化し、割り当て可能にするには:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nこれを追加すると、Codex の worktree が checkout モーダルおよび `coast ls` の出力に表示されるようになります。Coast インスタンスを Codex worktree に割り当てて、そのコードをフル開発環境で実行できます。\n\n注意: 外部ディレクトリを追加した後でバインドマウントを有効にするには、コンテナを再作成する必要があります(`coast run`)。既存インスタンスを再起動するだけでは不十分です。\n\n### Claude Code 統合\n\nClaude Code はプロジェクト内の `.claude/worktrees/` に worktree を作成します。これは相対パス(プロジェクトルート内)なので、他のローカル worktree ディレクトリと同様に動作します — 外部マウントは不要です:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Shep 統合\n\nShep は `~/.shep/repos/{hash}/wt/{branch-slug}` に worktree を作成し、このハッシュはリポジトリごとに異なります。ハッシュディレクトリに一致させるにはグロブパターンを使用します:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n### すべてのハーネスをまとめて使用\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n## Live Coastfile 読み取り\n\nCoastfile 内の `worktree_dir` への変更は、worktree の**一覧表示**には即座に反映されます(API と git watcher は、キャッシュされたビルドアーティファクトだけでなく、ディスク上の最新の Coastfile を読み取ります)。ただし、外部の**バインドマウント**はコンテナ作成時にのみ作成されるため、新しく追加した外部ディレクトリをマウント可能にするにはインスタンスを再作成する必要があります。\n", "concepts_and_terminology/README.md": "# 概念と用語\n\nこのセクションでは、Coasts 全体で使用される中核となる概念と語彙を扱います。Coasts が初めての場合は、設定や高度な使い方に入る前に、ここから始めてください。\n\n- [Coasts](COASTS.md) — プロジェクトの自己完結型ランタイム。それぞれが独自のポート、ボリューム、worktree の割り当てを持ちます。\n- [Run](RUN.md) — 最新のビルドから新しい Coast インスタンスを作成し、必要に応じて worktree を割り当てます。\n- [Remove](REMOVE.md) — クリーンに再作成したい場合や Coasts を停止したい場合に、Coast インスタンスとその分離されたランタイム状態を削除します。\n- [Filesystem](FILESYSTEM.md) — ホストと Coast 間の共有マウント、ホスト側エージェント、そして worktree の切り替え。\n- [Coast Daemon](DAEMON.md) — ライフサイクル操作を実行するローカルの `coastd` コントロールプレーン。\n- [Coast CLI](CLI.md) — コマンド、スクリプト、エージェントのワークフローのためのターミナル・インターフェース。\n- [Coastguard](COASTGUARD.md) — 可観測性と制御のために `coast ui` で起動する Web UI。\n- [Ports](PORTS.md) — 正規ポートと動的ポート、および checkout がそれらの間でどのようにスワップするか。\n- [Primary Port & DNS](PRIMARY_PORT_AND_DNS.md) — プライマリサービスへのクイックリンク、Cookie 分離のためのサブドメインルーティング、URL テンプレート。\n- [Assign and Unassign](ASSIGN.md) — Coast を worktree 間で切り替える方法と、利用可能な assign 戦略。\n- [Checkout](CHECKOUT.md) — 正規ポートを Coast インスタンスにマッピングすること、およびそれが必要になるタイミング。\n- [Lookup](LOOKUP.md) — エージェントの現在の worktree に一致する Coast インスタンスを発見する方法。\n- [Volume Topology](VOLUMES.md) — 共有サービス、共有ボリューム、分離ボリューム、スナップショット。\n- [Shared Services](SHARED_SERVICES.md) — ホスト管理のインフラサービスとボリュームの識別。\n- [Secrets and Extractors](SECRETS.md) — ホストのシークレットを抽出し、Coast コンテナへ注入する。\n- [Builds](BUILDS.md) — coast build の構造、成果物の保存場所、自動プルーニング、型付きビルド。\n- [Coastfile Types](COASTFILE_TYPES.md) — extends、unset、omit、autostart を備えた合成可能な Coastfile バリアント。\n- [Runtimes and Services](RUNTIMES_AND_SERVICES.md) — DinD ランタイム、Docker-in-Docker アーキテクチャ、そしてサービスが Coast 内でどのように実行されるか。\n- [Bare Services](BARE_SERVICES.md) — Coast 内で非コンテナ化プロセスを実行すること、および代わりにコンテナ化すべき理由。\n- [Logs](LOGS.md) — Coast 内からサービスログを読む方法、MCP のトレードオフ、Coastguard のログビューア。\n- [Exec & Docker](EXEC_AND_DOCKER.md) — Coast 内でコマンドを実行し、内側の Docker デーモンと通信する。\n- [Agent Shells](AGENT_SHELLS.md) — コンテナ化されたエージェント TUI、OAuth のトレードオフ、そしておそらくエージェントはホスト上で実行すべき理由。\n- [MCP Servers](MCP_SERVERS.md) — コンテナ化されたエージェントのために Coast 内で MCP ツールを設定すること、内部サーバーとホストプロキシされたサーバー。\n- [Troubleshooting](TROUBLESHOOTING.md) — doctor、デーモン再起動、プロジェクト削除、そして factory-reset の全消去オプション。\n", "concepts_and_terminology/AGENT_SHELLS.md": "# Agent Shells\n\nエージェントシェルは、Coast の内部にあるシェルで、エージェントの TUI ランタイム(Claude Code、Codex、または任意の CLI エージェント)に直接接続して開きます。Coastfile の `[agent_shell]` セクションで設定し、Coast が DinD コンテナ内でエージェントプロセスを起動します。\n\n**ほとんどのユースケースでは、これを行うべきではありません。** 代わりにホストマシン上でコーディングエージェントを実行してください。共有[ファイルシステム](FILESYSTEM.md)により、ホスト側のエージェントは通常どおりコードを編集しながら、ランタイム情報のために [`coast logs`](LOGS.md)、[`coast exec`](EXEC_AND_DOCKER.md)、[`coast ps`](RUNTIMES_AND_SERVICES.md) を呼び出せます。エージェントシェルは、資格情報のマウント、OAuth の複雑さ、ライフサイクルの複雑さを追加します。エージェント自体をコンテナ化する明確な理由がない限り、これらは不要です。\n\n## The OAuth Problem\n\nClaude Code、Codex、または同様の OAuth で認証するツールを使用している場合、トークンはホストマシン向けに発行されています。その同じトークンを Linux コンテナ内(異なるユーザーエージェント、異なる環境)から使用すると、プロバイダがそれを検知してフラグ付けしたり失効させたりする可能性があります。デバッグが難しい断続的な認証失敗が発生します。\n\nコンテナ化されたエージェントでは、API キーベースの認証の方が安全な選択です。キーを Coastfile の [secret](SECRETS.md) として設定し、コンテナ環境へ注入してください。\n\nAPI キーが使えない場合は、OAuth 資格情報を Coast にマウントできます(下の Configuration セクション参照)が、摩擦があることを想定してください。macOS で `keychain` シークレット抽出器を使って OAuth トークンを取り出す場合、`coast build` のたびに macOS キーチェーンのパスワード入力を求められます。これは特に頻繁に再ビルドする場合に面倒です。キーチェーンのプロンプトは macOS のセキュリティ要件であり、回避できません。\n\n## Configuration\n\nCoastfile に `[agent_shell]` セクションを追加し、実行するコマンドを指定します:\n\n```toml\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\nこのコマンドは DinD コンテナ内の `/workspace` で実行されます。Coast はコンテナ内に `coast` ユーザーを作成し、資格情報を `/root/.claude/` から `/home/coast/.claude/` にコピーして、そのユーザーとしてコマンドを実行します。エージェントがコンテナに資格情報をマウントする必要がある場合は、ファイル注入付きの `[secrets]`([Secrets and Extractors](SECRETS.md) を参照)と、エージェント CLI をインストールするための `[coast.setup]` を使用してください:\n\n```toml\n[coast.setup]\nrun = [\"npm install -g @anthropic-ai/claude-code\"]\n\n[secrets.claude_credentials]\nextractor = \"keychain\"\nservice = \"Claude Code-credentials\"\ninject = \"file:/root/.claude/.credentials.json\"\n\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\n`[agent_shell]` が設定されている場合、インスタンス起動時に Coast は自動でシェルを起動します。設定は `extends` により継承され、[Coastfile type](COASTFILE_TYPES.md) ごとに上書きできます。\n\n## The Active Agent Model\n\n各 Coast インスタンスは複数のエージェントシェルを持てますが、同時に **active** になれるのは 1 つだけです。active シェルは、`--shell` ID を指定しないコマンドのデフォルトターゲットになります。\n\n```bash\ncoast agent-shell dev-1 ls\n\n SHELL STATUS ACTIVE\n 1 running ★\n 2 running\n```\n\nactive シェルを切り替えます:\n\n```bash\ncoast agent-shell dev-1 activate 2\n```\n\nactive シェルは閉じられません — 先に別のものを active にしてください。これは、操作中のシェルを誤って終了させるのを防ぎます。\n\nCoastguard では、エージェントシェルは Exec パネル内のタブとして表示され、active/inactive のバッジが付きます。タブをクリックして端末を表示し、ドロップダウンメニューから有効化、起動、または閉じる操作ができます。\n\n![Agent shell in Coastguard](../../assets/coastguard-agent-shell.png)\n*Coastguard の Exec タブからアクセスできる、Coast インスタンス内で Claude Code を実行しているエージェントシェル。*\n\n## Sending Input\n\nコンテナ化されたエージェントをプログラム的に駆動する主な方法は `coast agent-shell input` です:\n\n```bash\ncoast agent-shell dev-1 input \"fix the failing test in auth.test.ts\"\n```\n\nこれはテキストを active エージェントの TUI に書き込み、Enter を押します。エージェントは、端末に手入力したかのように受け取ります。\n\nオプション:\n\n- `--no-send` — Enter を押さずにテキストを書き込みます。部分的な入力を組み立てたり、TUI メニューを操作したりするのに便利です。\n- `--shell ` — active ではなく特定のシェルを対象にします。\n- `--show-bytes` — デバッグのため、送信される正確なバイト列を表示します。\n\n内部的には、入力は PTY のマスターファイルディスクリプタに直接書き込まれます。テキストと Enter キーストロークは 2 回の別々の write として送られ、その間に 25ms の間隔を置きます。これは、一部の TUI フレームワークが高速入力を受け取った際に示すペーストモードの副作用を避けるためです。\n\n## Other Commands\n\n```bash\ncoast agent-shell dev-1 spawn # create a new shell\ncoast agent-shell dev-1 spawn --activate # create and immediately activate\ncoast agent-shell dev-1 tty # attach interactive TTY to active shell\ncoast agent-shell dev-1 tty --shell 2 # attach to a specific shell\ncoast agent-shell dev-1 read-output # read full scrollback buffer\ncoast agent-shell dev-1 read-last-lines 50 # read last 50 lines of output\ncoast agent-shell dev-1 session-status # check if the shell process is alive\n```\n\n`tty` はライブのインタラクティブセッションを提供します — エージェントの TUI に直接入力できます。標準の端末エスケープシーケンスでデタッチできます。`read-output` と `read-last-lines` は非インタラクティブでテキストを返すため、スクリプトや自動化に便利です。\n\n## Lifecycle and Recovery\n\nエージェントシェルのセッションは、Coastguard でページ移動しても維持されます。スクロールバックバッファ(最大 512KB)は、タブへ再接続した際にリプレイされます。\n\n`coast stop` で Coast インスタンスを停止すると、すべてのエージェントシェル PTY プロセスが kill され、データベースレコードがクリーンアップされます。`[agent_shell]` が設定されている場合、`coast start` は新しいエージェントシェルを自動起動します。\n\nデーモンの再起動後、以前動作していたエージェントシェルは dead と表示されます。システムはこれを自動検出します — active シェルが dead の場合、最初の live シェルが active に昇格します。生きているシェルが 1 つもない場合は、`coast agent-shell spawn --activate` で新しいものを起動してください。\n\n## Who This Is For\n\nエージェントシェルは、Coasts の周りに **ファーストパーティ統合を構築するプロダクト** 向けに設計されています — オーケストレーションプラットフォーム、エージェントラッパー、そして `input`、`read-output`、`session-status` API を通じてコンテナ化されたコーディングエージェントをプログラム的に管理したいツールです。\n\n一般用途の並列エージェントコーディングでは、ホスト上でエージェントを実行してください。よりシンプルで、OAuth 問題を回避し、資格情報マウントの複雑さを避け、共有ファイルシステムの利点を最大限に活用できます。エージェントコンテナ化のオーバーヘッドなしに、Coast の利点(分離されたランタイム、ポート管理、worktree 切り替え)をすべて得られます。\n\nエージェントシェルのさらに上の複雑さの段階は、コンテナ化されたエージェントがツールへアクセスできるように [MCP servers](MCP_SERVERS.md) を Coast にマウントすることです。これは統合面をさらに拡大し、別途取り上げています。必要ならその機能はありますが、ほとんどのユーザーには不要です。\n", "concepts_and_terminology/ASSIGN.md": "# 割り当てと割り当て解除\n\n割り当て(assign)と割り当て解除(unassign)は、Coast インスタンスがどの worktree を指すかを制御します。マウントレベルでの worktree 切り替えの仕組みについては [Filesystem](FILESYSTEM.md) を参照してください。\n\n## 割り当て\n\n`coast assign` は、Coast インスタンスを特定の worktree に切り替えます。Coast は worktree がまだ存在しない場合は作成し、Coast 内のコードを更新し、設定された割り当て戦略に従ってサービスを再起動します。\n\n```bash\ncoast assign dev-1 --worktree feature/oauth\n```\n\n```text\nBefore:\n┌─── dev-1 ──────────────────┐\n│ branch: main │\n│ worktree: - │\n└────────────────────────────┘\n\ncoast assign dev-1 --worktree feature/oauth\n\nAfter:\n┌─── dev-1 ──────────────────┐\n│ branch: feature/oauth │\n│ worktree: feature/oauth │\n│ │\n│ postgres → skipped (none) │\n│ web → hot swapped │\n│ api → restarted │\n│ worker → rebuilt │\n└────────────────────────────┘\n```\n\n割り当て後、`dev-1` は `feature/oauth` ブランチで稼働し、すべてのサービスが起動した状態になります。\n\n## 割り当て解除\n\n`coast unassign` は、Coast インスタンスをプロジェクトルート(main/master ブランチ)に戻します。worktree の関連付けが削除され、Coast はプライマリリポジトリから実行する状態に戻ります。\n\n```text\ncoast unassign dev-1\n\n┌─── dev-1 ──────────────────┐\n│ branch: main │\n│ worktree: - │\n└────────────────────────────┘\n```\n\n## 割り当て戦略\n\nCoast が新しい worktree に割り当てられると、各サービスはコード変更をどのように扱うかを把握する必要があります。これは [Coastfile](COASTFILE_TYPES.md) の `[assign]` 配下でサービスごとに設定します。\n\n```toml\n[assign]\ndefault = \"restart\"\n\n[assign.services]\npostgres = \"none\"\nredis = \"none\"\nweb = \"hot\"\nworker = \"rebuild\"\n```\n\n```text\ncoast assign dev-1 --worktree feature/billing\n\n postgres (strategy: none) → skipped, unchanged between branches\n redis (strategy: none) → skipped, unchanged between branches\n web (strategy: hot) → filesystem swapped, file watcher picks it up\n api (strategy: restart) → container restarted\n worker (strategy: rebuild) → image rebuilt, container restarted\n```\n\n利用可能な戦略は次のとおりです。\n\n- **none** — 何もしません。Postgres や Redis のようにブランチ間で変化しないサービスに使用します。\n- **hot** — ファイルシステムのみを入れ替えます。サービスは稼働したままで、マウントの伝播とファイルウォッチャー(例: ホットリロード付きの開発サーバー)により変更を取り込みます。\n- **restart** — サービスコンテナを再起動します。プロセスの再起動だけが必要なインタプリタ系サービスに使用します。これがデフォルトです。\n- **rebuild** — サービスイメージを再ビルドして再起動します。ブランチ変更が `Dockerfile` やビルド時依存関係に影響する場合に使用します。\n\nまた、特定のファイルが変更されたときだけサービスが再ビルドされるように、rebuild トリガーを指定することもできます。\n\n```toml\n[assign.rebuild_triggers]\nworker = [\"Dockerfile\", \"package.json\"]\n```\n\nブランチ間でトリガーファイルがどれも変更されていない場合、戦略が `rebuild` に設定されていても、そのサービスは再ビルドをスキップします。\n\n## 削除された Worktree\n\n割り当てられている worktree が削除された場合、`coastd` デーモンはそのインスタンスを自動的にメインの Git リポジトリルートへ割り当て解除します。\n\n---\n\n> **ヒント: 大規模コードベースで assign の待ち時間を削減する**\n>\n> 内部的には、新しい worktree への最初の assign で、選択された gitignored ファイルがその worktree にブートストラップされ、`[assign.rebuild_triggers]` を持つサービスは再ビルドが必要かどうか判断するために `git diff --name-only` を実行する場合があります。大規模コードベースでは、このブートストラップ手順と不要な再ビルドが assign 時間の大半を占めがちです。\n>\n> Coastfile の `exclude_paths` を使って gitignored のブートストラップ対象範囲を縮小し、ファイルウォッチャーを持つサービスには `\"hot\"` を使用し、`[assign.rebuild_triggers]` は真のビルド時入力に絞ってください。既存の worktree に対して ignored-file のブートストラップを手動で更新する必要がある場合は、`coast assign --force-sync` を実行します。完全なガイドは [Performance Optimizations](PERFORMANCE_OPTIMIZATIONS.md) を参照してください。\n", "concepts_and_terminology/BARE_SERVICES.md": "# ベアサービス\n\nプロジェクトをコンテナ化できるなら、そうすべきです。ベアサービスは、まだコンテナ化されておらず、短期的に `Dockerfile` と `docker-compose.yml` を追加するのが現実的ではないプロジェクトのために存在します。これは踏み台であり、到達点ではありません。\n\nコンテナ化されたサービスをオーケストレーションする `docker-compose.yml` の代わりに、ベアサービスでは Coastfile にシェルコマンドを定義し、Coast がそれらを Coast コンテナ内の軽量なスーパーバイザーで素のプロセスとして実行します。\n\n## 代わりにコンテナ化すべき理由\n\n[Docker Compose](RUNTIMES_AND_SERVICES.md) サービスが提供するもの:\n\n- Dockerfile による再現可能なビルド\n- 起動時に Coast が待機できるヘルスチェック\n- サービス間のプロセス分離\n- Docker によって処理されるボリュームとネットワーク管理\n- CI、ステージング、本番で動作するポータブルな定義\n\nベアサービスにはこれらが一切ありません。プロセスは同じファイルシステムを共有し、クラッシュリカバリーはシェルループであり、「自分のマシンでは動く」は Coast の中でも外でも同じくらい起こり得ます。プロジェクトにすでに `docker-compose.yml` があるなら、それを使ってください。\n\n## ベアサービスが有用な場合\n\n- 一度もコンテナ化されたことのないプロジェクトで Coast を採用しており、worktree の分離とポート管理からすぐに価値を得たい\n- Dockerfile が過剰になりがちな単一プロセスのツールや CLI である\n- コンテナ化を段階的に進めたい — まずベアサービスから始め、後で compose に移行する\n\n## 設定\n\nベアサービスは Coastfile 内の `[services.]` セクションで定義します。Coastfile はベアサービスのみを定義することも、`compose` と並べて定義することもできます。後者については [Mixed Service Types](MIXED_SERVICE_TYPES.md) を参照してください。\n\n```toml\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\nrestart = \"on-failure\"\n\n[services.worker]\ncommand = \"node worker.js\"\nrestart = \"always\"\n\n[ports]\nweb = 3000\n```\n\n各サービスには 4 つのフィールドがあります:\n\n| Field | Required | Description |\n|---|---|---|\n| `command` | yes | 実行するシェルコマンド(例: `\"npm run dev\"`) |\n| `port` | no | サービスが待ち受けるポート。ポートマッピングに使用 |\n| `restart` | no | 再起動ポリシー: `\"no\"`(デフォルト)、`\"on-failure\"`、または `\"always\"` |\n| `install` | no | 起動前に実行する 1 つ以上のコマンド(例: `\"npm install\"` または `[\"npm install\", \"npm run build\"]`) |\n\n### セットアップパッケージ\n\nベアサービスは素のプロセスとして動作するため、Coast コンテナに適切なランタイムがインストールされている必要があります。`[coast.setup]` を使ってシステムパッケージを宣言します:\n\n```toml\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n```\n\nこれらは、どのサービスが開始される前にもインストールされます。これがないと、コンテナ内で `npm` や `node` コマンドが失敗します。\n\n### インストールコマンド\n\n`install` フィールドは、サービス開始前に実行され、さらに毎回 [`coast assign`](ASSIGN.md)(ブランチ切り替え)時にも再実行されます。依存関係のインストールはここに置きます:\n\n```toml\n[services.api]\ninstall = [\"pip install -r requirements.txt\", \"python manage.py migrate\"]\ncommand = \"python manage.py runserver 0.0.0.0:8000\"\nport = 8000\n```\n\nインストールコマンドは順番に実行されます。いずれかのインストールコマンドが失敗した場合、そのサービスは開始されません。\n\n### 再起動ポリシー\n\n- **`no`** — サービスは 1 回だけ実行されます。終了したら、そのまま停止した状態になります。ワンショットのタスクや手動で管理したいサービスに使用します。\n- **`on-failure`** — 非ゼロコードで終了した場合にサービスを再起動します。正常終了(コード 0)はそのままにします。1 秒から最大 30 秒までの指数バックオフを使用し、10 回連続でクラッシュすると諦めます。\n- **`always`** — 成功を含むあらゆる終了で再起動します。`on-failure` と同じバックオフです。決して止まってほしくない長時間稼働のサーバーに使用します。\n\nクラッシュする前にサービスが 30 秒以上稼働していた場合、リトライカウンターとバックオフはリセットされます。しばらくは健全だったとみなし、そのクラッシュは新しい問題だという前提です。\n\n## 内部での仕組み\n\n```text\n┌─── Coast: dev-1 ──────────────────────────────────────┐\n│ │\n│ /coast-supervisor/ │\n│ ├── web.sh (runs command, tracks PID) │\n│ ├── worker.sh │\n│ ├── start-all.sh (launches all services) │\n│ ├── stop-all.sh (SIGTERM via PID files) │\n│ └── ps.sh (checks PID liveness) │\n│ │\n│ /var/log/coast-services/ │\n│ ├── web.log │\n│ └── worker.log │\n│ │\n│ No inner Docker daemon images are used. │\n│ Processes run directly on the container OS. │\n└───────────────────────────────────────────────────────┘\n```\n\nCoast は各サービス用のシェルスクリプトラッパーを生成し、DinD コンテナ内の `/coast-supervisor/` に配置します。各ラッパーは PID を追跡し、出力をログファイルにリダイレクトし、再起動ポリシーをシェルループとして実装します。Docker Compose はなく、内部の Docker イメージもなく、サービス間のコンテナレベルの分離もありません。\n\n`coast ps` は Docker に問い合わせるのではなく PID の生存確認を行い、`coast logs` は `docker compose logs` を呼ぶのではなくログファイルを tail します。ログ出力形式は compose の `service | line` 形式に一致するため、Coastguard の UI は変更なしで動作します。\n\n## ポート\n\nポート設定は compose ベースの Coast とまったく同じように動作します。サービスが待ち受けるポートを `[ports]` で定義します:\n\n```toml\n[services.web]\ncommand = \"npm start\"\nport = 3000\n\n[ports]\nweb = 3000\n```\n\n[Dynamic ports](PORTS.md) は `coast run` 時に割り当てられ、[`coast checkout`](CHECKOUT.md) は通常どおりカノニカルポートを入れ替えます。唯一の違いは、サービス間に Docker ネットワークがないことです — すべてのサービスはコンテナのループバックまたは `0.0.0.0` に直接バインドします。\n\n## ブランチ切り替え\n\nベアサービスの Coast で `coast assign` を実行すると、次のことが起こります:\n\n1. 実行中の全サービスが SIGTERM により停止される\n2. worktree が新しいブランチに切り替わる\n3. インストールコマンドが再実行される(例: `npm install` が新しいブランチの依存関係を取り込む)\n4. 全サービスが再起動する\n\nこれは compose で起こること — `docker compose down`、ブランチ切り替え、再ビルド、`docker compose up` — と同等ですが、コンテナの代わりにシェルプロセスを使用します。\n\n## 制限事項\n\n- **ヘルスチェックなし。** Coast は、ヘルスチェックを定義した compose サービスのように、ベアサービスが「healthy」になるのを待てません。プロセスを起動して、うまくいくことを祈るだけです。\n- **サービス間の分離なし。** すべてのプロセスは Coast コンテナ内で同じファイルシステムとプロセス名前空間を共有します。問題のあるサービスが他に影響する可能性があります。\n- **ビルドキャッシュなし。** Docker Compose のビルドはレイヤーごとにキャッシュされます。ベアサービスの `install` コマンドは assign のたびに最初から実行されます。\n- **クラッシュリカバリーは基本的。** 再起動ポリシーは指数バックオフを備えたシェルループを使用します。systemd や supervisord のようなプロセススーパーバイザーではありません。\n- **サービスに対する `[omit]` や `[unset]` がない。** Coastfile の型合成は compose サービスでは動作しますが、ベアサービスでは型付き Coastfile によって個別のサービスを省略することはサポートされません。\n\n## Compose への移行\n\nコンテナ化の準備ができたら、移行パスは簡単です:\n\n1. 各サービスの `Dockerfile` を書く\n2. それらを参照する `docker-compose.yml` を作成する\n3. Coastfile の `[services.*]` セクションを、compose ファイルを指す `compose` フィールドに置き換える\n4. Dockerfile によって扱われるようになった `[coast.setup]` のパッケージを削除する\n5. [`coast build`](BUILDS.md) で再ビルドする\n\nポートマッピング、[volumes](VOLUMES.md)、[shared services](SHARED_SERVICES.md)、[secrets](SECRETS.md) の設定はすべて変更なしで引き継がれます。変わるのは、サービス自体の実行方法だけです。\n", "concepts_and_terminology/BUILDS.md": "# ビルド\n\ncoast のビルドは、追加の支援機能が付いた Docker イメージだと考えてください。ビルドはディレクトリベースの成果物で、Coast インスタンスを作成するために必要なものをすべてまとめています: 解決済みの [Coastfile](COASTFILE_TYPES.md)、書き換えられた compose ファイル、事前に pull された OCI イメージ tarball、そして注入されたホストファイルです。これは Docker イメージそのものではありませんが、Docker イメージ(tarball として)と、それらをつなぎ合わせるために Coast が必要とするメタデータを含んでいます。\n\n## `coast build` が行うこと\n\n`coast build` を実行すると、デーモンは次の手順を順番に実行します:\n\n1. Coastfile を解析して検証します。\n2. compose ファイルを読み取り、省略されたサービスを除外します。\n3. 設定された extractor から [secrets](SECRETS.md) を抽出し、keystore に暗号化して保存します。\n4. `build:` ディレクティブを持つ compose サービスの Docker イメージを(ホスト上で)ビルドします。\n5. `image:` ディレクティブを持つ compose サービスの Docker イメージを pull します。\n6. すべてのイメージを `~/.coast/image-cache/` に OCI tarball としてキャッシュします。\n7. `[coast.setup]` が設定されている場合、指定されたパッケージ、コマンド、ファイルを使ってカスタム DinD ベースイメージをビルドします。\n8. manifest、解決済み coastfile、書き換え済み compose、注入ファイルを含むビルド成果物ディレクトリを書き込みます。\n9. `latest` シンボリックリンクを更新して新しいビルドを指すようにします。\n10. 保持上限を超えた古いビルドを自動的に削除します。\n\n## ビルドの保存場所\n\n```text\n~/.coast/\n images/\n my-project/\n latest -> a3c7d783_20260227143000 (symlink)\n a3c7d783_20260227143000/ (versioned build)\n manifest.json\n coastfile.toml\n compose.yml\n inject/\n b4d8e894_20260226120000/ (older build)\n ...\n image-cache/ (shared tarball cache)\n postgres_16_a1b2c3d4e5f6.tar\n redis_7_f6e5d4c3b2a1.tar\n coast-built_my-project_web_latest_...tar\n```\n\n各ビルドには、`{coastfile_hash}_{YYYYMMDDHHMMSS}` 形式の一意な **build ID** が付与されます。このハッシュには Coastfile の内容と解決済み設定が含まれるため、Coastfile を変更すると新しい build ID が生成されます。\n\n`latest` シンボリックリンクは、素早く解決できるよう常に最新のビルドを指します。プロジェクトで型付き Coastfile(例: `Coastfile.light`)を使用している場合、各タイプは独自のシンボリックリンクを持ちます: `latest-light`。\n\n`~/.coast/image-cache/` にあるイメージキャッシュは、すべてのプロジェクトで共有されます。2 つのプロジェクトが同じ Postgres イメージを使っている場合、その tarball は 1 回だけキャッシュされます。\n\n## ビルドに含まれるもの\n\n各ビルドディレクトリには次のものが含まれます:\n\n- **`manifest.json`** -- プロジェクト名、ビルドタイムスタンプ、coastfile ハッシュ、キャッシュ済み/ビルド済みイメージの一覧、シークレット名、省略されたサービス、[volume strategies](VOLUMES.md) などを含む完全なビルドメタデータ。\n- **`coastfile.toml`** -- 解決済み Coastfile(`extends` を使用している場合は親とマージ済み)。\n- **`compose.yml`** -- compose ファイルを書き換えたバージョンで、`build:` ディレクティブは事前ビルド済みイメージタグに置き換えられ、省略されたサービスは取り除かれます。\n- **`inject/`** -- `[inject].files` からのホストファイルのコピー(例: `~/.gitconfig`、`~/.npmrc`)。\n\n## ビルドにはシークレットは含まれません\n\nシークレットはビルド手順中に抽出されますが、`~/.coast/keystore.db` にある別の暗号化された keystore に保存されます -- ビルド成果物ディレクトリの中には保存されません。manifest には、抽出されたシークレットの **名前** だけが記録され、値は決して記録されません。\n\nこれは、機密データを露出することなくビルド成果物を安全に確認できることを意味します。シークレットは後で、`coast run` で Coast インスタンスが作成されるときに復号化されて注入されます。\n\n## ビルドと Docker\n\nビルドには 3 種類の Docker イメージが関わります:\n\n- **ビルド済みイメージ** -- `build:` ディレクティブを持つ compose サービスは、ホスト上で `docker build` によりビルドされ、`coast-built/{project}/{service}:latest` としてタグ付けされ、イメージキャッシュに tarball として保存されます。\n- **pull 済みイメージ** -- `image:` ディレクティブを持つ compose サービスは pull され、tarball として保存されます。\n- **Coast イメージ** -- `[coast.setup]` が設定されている場合、指定されたパッケージ、コマンド、ファイルを使って `docker:dind` の上にカスタム Docker イメージがビルドされます。`coast-image/{project}:{build_id}` としてタグ付けされます。\n\nランタイム時([`coast run`](RUN.md))には、これらの tarball は `docker load` によって内部の [DinD daemon](RUNTIMES_AND_SERVICES.md) に読み込まれます。これにより、Coast インスタンスはレジストリからイメージを pull する必要なく高速に起動できます。\n\n## ビルドとインスタンス\n\n[`coast run`](RUN.md) を実行すると、Coast は最新のビルド(または特定の `--build-id`)を解決し、その成果物を使ってインスタンスを作成します。build ID はそのインスタンスに記録されます。\n\nさらにインスタンスを作成するために再ビルドする必要はありません。1 つのビルドで、並列実行される複数の Coast インスタンスに対応できます。\n\n## 再ビルドするタイミング\n\nCoastfile、`docker-compose.yml`、またはインフラ構成が変更されたときだけ再ビルドしてください。再ビルドはリソース集約的です -- イメージを再 pull し、Docker イメージを再ビルドし、シークレットを再抽出します。\n\nコードの変更では再ビルドは必要ありません。Coast はプロジェクトディレクトリを各インスタンスに直接マウントするため、コードの更新は即座に反映されます。\n\n## 自動削除\n\nCoast は Coastfile のタイプごとに最大 5 個のビルドを保持します。`coast build` が成功するたびに、上限を超えた古いビルドは自動的に削除されます。\n\n実行中のインスタンスで使用されているビルドは、上限に関係なく決して削除されません。7 個のビルドがあり、そのうち 3 個がアクティブなインスタンスを支えている場合、その 3 個はすべて保護されます。\n\n## 手動削除\n\nビルドは `coast rm-build` または Coastguard の Builds タブから手動で削除できます。\n\n- **プロジェクト全体の削除** (`coast rm-build `) は、まずすべてのインスタンスを停止して削除しておく必要があります。これはビルドディレクトリ全体、関連する Docker イメージ、volume、container を削除します。\n- **選択的削除**(build ID による削除。Coastguard UI で利用可能)は、実行中のインスタンスで使用中のビルドをスキップします。\n\n## 型付きビルド\n\nプロジェクトが複数の Coastfile を使用している場合(例: デフォルト設定用の `Coastfile` と、スナップショットで seed された volume 用の `Coastfile.snap`)、各タイプは独自の `latest-{type}` シンボリックリンクと独自の 5 ビルド削除プールを維持します。\n\n```bash\ncoast build # uses Coastfile, updates \"latest\"\ncoast build --type snap # uses Coastfile.snap, updates \"latest-snap\"\n```\n\n`snap` ビルドの削除が `default` ビルドに影響することはなく、その逆も同様です。\n", - "concepts_and_terminology/CHECKOUT.md": "# Checkout\n\nCheckout は、あなたのプロジェクトの[canonical ports](PORTS.md)をどの Coast インスタンスが所有するかを制御します。Coast をチェックアウトすると、`localhost:3000`、`localhost:5432`、およびその他すべての canonical port がそのインスタンスに直接マッピングされます。\n\n```bash\ncoast checkout dev-1\n```\n\n```text\nBefore checkout:\n localhost:3000 ──→ (nothing)\n localhost:5432 ──→ (nothing)\n\nAfter checkout:\n localhost:3000 ──→ dev-1 web\n localhost:5432 ──→ dev-1 db\n```\n\nCheckout の切り替えは瞬時に行われます — Coast は軽量な `socat` フォワーダーを停止して再生成します。コンテナは再起動されません。\n\n```bash\ncoast checkout dev-2 # instant swap\n\n# localhost:3000 ──→ dev-2 web\n# localhost:5432 ──→ dev-2 db\n```\n\n## Linux Note\n\n動的ポートは、Linux では特別な権限なしで常に動作します。\n\n`1024` 未満の canonical port は異なります。Coastfile で `80` や `443` のようなポートを宣言している場合、ホストを設定するまで Linux が `coast checkout` によるバインドをブロックすることがあります。一般的な対処法は次のとおりです。\n\n- `net.ipv4.ip_unprivileged_port_start` を引き上げる\n- フォワーディング用バイナリまたはプロセスに bind capability を付与する\n\nホストがバインドを拒否した場合、Coast はこれを明示的に報告します。\n\nWSL では、Coast は Docker によって公開された checkout bridge を使用するため、Windows のブラウザやツールは Sail のような Docker Desktop ワークフローと同様に、`127.0.0.1` を通じてチェックアウトされた canonical port に到達できます。\n\n## Do You Need to Check Out?\n\n必ずしもそうではありません。実行中の各 Coast は常にそれぞれ独自の動的ポートを持っており、何もチェックアウトしなくても、いつでもそれらのポートを通じて任意の Coast にアクセスできます。\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\nチェックアウトしなくても、ブラウザで `localhost:62217` を開いて dev-1 の web サーバーにアクセスできます。これは多くのワークフローでまったく問題なく、`coast checkout` を一度も使わずに、好きなだけ多くの Coast を実行できます。\n\n## When Checkout Is Useful\n\n動的ポートだけでは不十分で、canonical port が必要になる状況があります。\n\n- **canonical port にハードコードされたクライアントアプリケーション。** Coast の外で動作するクライアント、たとえばホスト上のフロントエンド開発サーバー、スマートフォン上のモバイルアプリ、またはデスクトップアプリが `localhost:3000` や `localhost:8080` を前提としている場合、あらゆる場所でポート番号を変更するのは現実的ではありません。Coast をチェックアウトすると、設定を一切変更せずに本来のポートを利用できます。\n\n- **Webhook とコールバック URL。** Stripe、GitHub、OAuth プロバイダのようなサービスは、登録済みの URL — 通常は `localhost:3000` に転送する `https://your-ngrok-tunnel.io` のようなもの — にコールバックを送信します。動的ポートに切り替えると、コールバックは届かなくなります。チェックアウトにより、テスト中の Coast に対して canonical port が有効であることが保証されます。\n\n- **データベースツール、デバッガー、IDE 連携。** 多くの GUI クライアント(pgAdmin、DataGrip、TablePlus)、デバッガー、IDE の実行構成は、特定のポートを持つ接続プロファイルを保存します。Checkout を使えば、保存済みプロファイルはそのままに、その背後にある Coast だけを切り替えられます — コンテキストを切り替えるたびに、デバッガーのアタッチ先やデータベース接続を再設定する必要はありません。\n\n## Releasing Checkout\n\n別の Coast をチェックアウトせずに canonical port を解放したい場合:\n\n```bash\ncoast checkout --none\n```\n\nこの後、canonical port を所有する Coast はなくなります。すべての Coast は引き続きそれぞれの動的ポートを通じてアクセス可能です。\n\n## Only One at a Time\n\n一度にチェックアウトできる Coast は正確に 1 つだけです。`dev-1` がチェックアウトされている状態で `coast checkout dev-2` を実行すると、canonical port は即座に `dev-2` に切り替わります。空白時間はありません — 古いフォワーダーが停止され、新しいものが同じ操作の中で生成されます。\n\n```text\n┌──────────────────────────────────────────────────┐\n│ Your machine │\n│ │\n│ Canonical (checked-out Coast only): │\n│ localhost:3000 ──→ dev-2 web │\n│ localhost:5432 ──→ dev-2 db │\n│ │\n│ Dynamic (always available): │\n│ localhost:62217 ──→ dev-1 web │\n│ localhost:55681 ──→ dev-1 db │\n│ localhost:63104 ──→ dev-2 web │\n│ localhost:57220 ──→ dev-2 db │\n└──────────────────────────────────────────────────┘\n```\n\n動的ポートは checkout の影響を受けません。変わるのは、canonical port の向き先だけです。\n", + "concepts_and_terminology/CHECKOUT.md": "# Checkout\n\nCheckout は、あなたのプロジェクトの[canonical ports](PORTS.md)をどの Coast インスタンスが所有するかを制御します。Coast をチェックアウトすると、`localhost:3000`、`localhost:5432`、およびその他すべての canonical port がそのインスタンスに直接マッピングされます。\n\n```bash\ncoast checkout dev-1\n```\n\n```text\nBefore checkout:\n localhost:3000 ──→ (nothing)\n localhost:5432 ──→ (nothing)\n\nAfter checkout:\n localhost:3000 ──→ dev-1 web\n localhost:5432 ──→ dev-1 db\n```\n\nCheckout の切り替えは瞬時に行われます — Coast は軽量な `socat` フォワーダーを停止して再生成します。コンテナは再起動されません。\n\n```bash\ncoast checkout dev-2 # instant swap\n\n# localhost:3000 ──→ dev-2 web\n# localhost:5432 ──→ dev-2 db\n```\n\n## Linux Note\n\n動的ポートは、Linux では特別な権限なしで常に動作します。\n\n`1024` 未満の canonical port は異なります。Coastfile で `80` や `443` のようなポートを宣言している場合、ホストを設定するまで Linux が `coast checkout` によるバインドをブロックすることがあります。一般的な対処法は次のとおりです。\n\n- `net.ipv4.ip_unprivileged_port_start` を引き上げる\n- フォワーディング用バイナリまたはプロセスに bind capability を付与する\n\nホストがバインドを拒否した場合、Coast はこれを明示的に報告します。\n\nWSL では、Coast は Docker によって公開された checkout bridge を使用するため、Windows のブラウザやツールは Sail のような Docker Desktop ワークフローと同様に、`127.0.0.1` を通じてチェックアウトされた canonical port に到達できます。\n\nCaddy を使うローカル HTTPS プロジェクトでは、Coast は Coast のインストールごとに 1 つの Caddy ローカル CA を再利用します。そのルートを一度信頼すれば、同じインストール配下で再作成されたワークスペースでも引き続きそれが使われます。\n\nルート証明書の場所は次のとおりです。\n\n- 通常のインストールでは `~/.coast/caddy/pki/authorities/local/root.crt`\n- `coast-dev` では `~/.coast-dev/caddy/pki/authorities/local/root.crt`\n\nこれらは意図的に分離されているため、`coast-dev` を信頼しても通常の `coast` インストールまで信頼されることはなく、その逆も同様です。\n\nアクティブなインストールのルート証明書を確認またはエクスポートするには:\n\n```bash\ncoast cert info\ncoast cert path\ncoast cert fingerprint\ncoast cert export --to ~/Downloads/coast-root.crt\n```\n\nCoast は信頼ストアへのインストール自体はユーザーに委ねています。証明書をエクスポートし、必要に応じて OS またはブラウザの信頼ストアにインポートしてください。\n\n## Do You Need to Check Out?\n\n必ずしもそうではありません。実行中の各 Coast は常にそれぞれ独自の動的ポートを持っており、何もチェックアウトしなくても、いつでもそれらのポートを通じて任意の Coast にアクセスできます。\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\nチェックアウトしなくても、ブラウザで `localhost:62217` を開いて dev-1 の web サーバーにアクセスできます。これは多くのワークフローでまったく問題なく、`coast checkout` を一度も使わずに、好きなだけ多くの Coast を実行できます。\n\n## When Checkout Is Useful\n\n動的ポートだけでは不十分で、canonical port が必要になる状況があります。\n\n- **canonical port にハードコードされたクライアントアプリケーション。** Coast の外で動作するクライアント、たとえばホスト上のフロントエンド開発サーバー、スマートフォン上のモバイルアプリ、またはデスクトップアプリが `localhost:3000` や `localhost:8080` を前提としている場合、あらゆる場所でポート番号を変更するのは現実的ではありません。Coast をチェックアウトすると、設定を一切変更せずに本来のポートを利用できます。\n\n- **Webhook とコールバック URL。** Stripe、GitHub、OAuth プロバイダのようなサービスは、登録済みの URL — 通常は `localhost:3000` に転送する `https://your-ngrok-tunnel.io` のようなもの — にコールバックを送信します。動的ポートに切り替えると、コールバックは届かなくなります。チェックアウトにより、テスト中の Coast に対して canonical port が有効であることが保証されます。\n\n- **データベースツール、デバッガー、IDE 連携。** 多くの GUI クライアント(pgAdmin、DataGrip、TablePlus)、デバッガー、IDE の実行構成は、特定のポートを持つ接続プロファイルを保存します。Checkout を使えば、保存済みプロファイルはそのままに、その背後にある Coast だけを切り替えられます — コンテキストを切り替えるたびに、デバッガーのアタッチ先やデータベース接続を再設定する必要はありません。\n\n## Releasing Checkout\n\n別の Coast をチェックアウトせずに canonical port を解放したい場合:\n\n```bash\ncoast checkout --none\n```\n\nこの後、canonical port を所有する Coast はなくなります。すべての Coast は引き続きそれぞれの動的ポートを通じてアクセス可能です。\n\n## Only One at a Time\n\n一度にチェックアウトできる Coast は正確に 1 つだけです。`dev-1` がチェックアウトされている状態で `coast checkout dev-2` を実行すると、canonical port は即座に `dev-2` に切り替わります。空白時間はありません — 古いフォワーダーが停止され、新しいものが同じ操作の中で生成されます。\n\n```text\n┌──────────────────────────────────────────────────┐\n│ Your machine │\n│ │\n│ Canonical (checked-out Coast only): │\n│ localhost:3000 ──→ dev-2 web │\n│ localhost:5432 ──→ dev-2 db │\n│ │\n│ Dynamic (always available): │\n│ localhost:62217 ──→ dev-1 web │\n│ localhost:55681 ──→ dev-1 db │\n│ localhost:63104 ──→ dev-2 web │\n│ localhost:57220 ──→ dev-2 db │\n└──────────────────────────────────────────────────┘\n```\n\n動的ポートは checkout の影響を受けません。変わるのは、canonical port の向き先だけです。\n", "concepts_and_terminology/CLI.md": "# Coast CLI\n\nCoast CLI(`coast`)は、Coast を操作するための主要なコマンドラインインターフェースです。意図的に薄い設計になっており、コマンドを解析し、[`coastd`](DAEMON.md) にリクエストを送信し、構造化された出力を端末に表示します。\n\n## 何に使うのか\n\n一般的なワークフローはすべて CLI から実行されます。\n\n```bash\ncoast build # see Builds\ncoast run dev-1 # see Run\ncoast assign dev-1 --worktree feature/oauth # see Assign\ncoast ports dev-1 # see Ports\ncoast checkout dev-1 # see Checkout\ncoast ui # see Coastguard\n```\n\nCLI には、人間とエージェントの両方に役立つドキュメント用コマンドも含まれています。\n\n```bash\ncoast docs\ncoast docs --path concepts_and_terminology/CHECKOUT.md\ncoast search-docs \"canonical vs dynamic ports\"\n```\n\n## なぜデーモンから分離されているのか\n\nCLI をデーモンから分離することで、いくつかの重要な利点があります。\n\n- デーモンは状態と長寿命のプロセスを保持します。\n- CLI は高速で、組み合わせやすく、スクリプト化しやすいままです。\n- ターミナルの状態を維持したままにしなくても、単発のコマンドを実行できます。\n- エージェント用ツールは、予測可能で自動化に適した方法で CLI コマンドを呼び出せます。\n\n## CLI と Coastguard\n\nそのときに適したインターフェースを使ってください。\n\n- CLI は運用全体をカバーするように設計されています。Coastguard でできることは、CLI からもできるはずです。\n- CLI は自動化インターフェースとして扱ってください — スクリプト、エージェントのワークフロー、CI ジョブ、カスタム開発者ツール向けです。\n- [Coastguard](COASTGUARD.md) は人間向けインターフェースとして扱ってください — 視覚的な確認、対話的なデバッグ、運用の可視性向けです。\n\nどちらも同じデーモンと通信するため、同じ基盤となるプロジェクト状態に対して動作します。\n", "concepts_and_terminology/COASTFILE_TYPES.md": "# Coastfile のタイプ\n\n1つのプロジェクトは、異なるユースケース向けに複数の Coastfile を持てます。各バリアントは「type(タイプ)」と呼ばれます。タイプを使うと、共通のベースを共有しつつ、実行するサービス、ボリュームの扱い、サービスを自動起動するかどうかといった点が異なる設定を組み立てられます。\n\n## Types の仕組み\n\n命名規則は、デフォルトが `Coastfile`、バリアントが `Coastfile.{type}` です。ドットの後ろのサフィックスがタイプ名になります。\n\n- `Coastfile` -- デフォルトタイプ\n- `Coastfile.test` -- テストタイプ\n- `Coastfile.snap` -- スナップショットタイプ\n- `Coastfile.light` -- 軽量タイプ\n\nタイプ付き Coast は `--type` でビルドと実行を行います。\n\n```bash\ncoast build --type test\ncoast run test-1 --type test\ncoast exec test-1 -- go test ./...\n```\n\n## extends\n\nタイプ付き Coastfile は `extends` により親から継承します。親の内容はすべてマージされます。子は上書きまたは追加するものだけを指定すれば十分です。\n\n```toml\n[coast]\nextends = \"Coastfile\"\n```\n\nこれにより、バリアントごとに設定全体を複製することを避けられます。子は親から、すべての [ports](PORTS.md)、[secrets](SECRETS.md)、[volumes](VOLUMES.md)、[shared services](SHARED_SERVICES.md)、[assign strategies](ASSIGN.md)、セットアップコマンド、そして [MCP](MCP_SERVERS.md) の設定を継承します。子で定義したものは親より優先されます。\n\n## [unset]\n\n親から継承した特定の項目を、名前で指定して削除します。`ports`、`shared_services`、`secrets`、`volumes` を unset できます。\n\n```toml\n[unset]\nports = [\"web\", \"redis\", \"backend\"]\nshared_services = [\"postgres\", \"redis\"]\n```\n\nこれは、テスト用バリアントが shared services を外し(データベースを Coast 内で分離ボリューム付きで動かすため)、不要なポートを削除する方法です。\n\n## [omit]\n\ncompose サービスをビルドから完全に取り除きます。omit されたサービスは compose ファイルから削除され、Coast 内では一切実行されません。\n\n```toml\n[omit]\nservices = [\"redis\", \"backend\", \"mailhog\", \"web\"]\n```\n\nバリアントの目的に無関係なサービスを除外するために使います。テスト用バリアントでは、データベース、マイグレーション、テストランナーだけを残すことがあります。\n\n## autostart\n\nCoast の起動時に `docker compose up` を自動実行するかどうかを制御します。デフォルトは `true` です。\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n```\n\nフルスタックを起動するのではなく、特定のコマンドを手動で実行したいバリアントでは `autostart = false` を設定します。これはテストランナーで一般的です。Coast を作成し、その後 [`coast exec`](EXEC_AND_DOCKER.md) を使って個別のテストスイートを実行します。\n\n## よくあるパターン\n\n### テスト用バリアント\n\nテスト実行に必要なものだけを残す `Coastfile.test`:\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n\n[unset]\nports = [\"web\", \"redis\", \"backend\"]\nshared_services = [\"postgres\", \"redis\"]\n\n[omit]\nservices = [\"redis\", \"backend\", \"mailhog\", \"web\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[assign]\ndefault = \"none\"\n[assign.services]\ntest-runner = \"rebuild\"\nmigrations = \"rebuild\"\n```\n\n各テスト Coast はそれぞれクリーンなデータベースを持ちます。テストは内部の compose ネットワーク越しにサービスへ接続するため、ポートは公開されません。`autostart = false` は、`coast exec` で手動でテスト実行をトリガーすることを意味します。\n\n### スナップショット用バリアント\n\nホストに既存のデータベースボリュームのコピーを各 Coast に投入する `Coastfile.snap`:\n\n```toml\n[coast]\nextends = \"Coastfile\"\n\n[unset]\nshared_services = [\"postgres\", \"redis\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"my_project_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"my_project_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n```\n\nshared services は unset され、データベースは各 Coast 内で実行されます。`snapshot_source` は、ビルド時に既存のホストボリュームから分離ボリュームへシードします。作成後は、各インスタンスのデータは独立して分岐します。\n\n### 軽量バリアント\n\n特定のワークフロー向けに、プロジェクトを最小構成まで削ぎ落とす `Coastfile.light` — たとえば高速な反復のために、バックエンドサービスとそのデータベースだけにする、といった用途です。\n\n## 独立したビルドプール\n\n各タイプはそれぞれ独自の `latest-{type}` シンボリックリンクと、5ビルドの自動プルーニングプールを持ちます。\n\n```bash\ncoast build # latest を更新し、default ビルドを prune\ncoast build --type test # latest-test を更新し、test ビルドを prune\ncoast build --type snap # latest-snap を更新し、snap ビルドを prune\n```\n\n`test` タイプをビルドしても `default` や `snap` のビルドには影響しません。プルーニングはタイプごとに完全に独立しています。\n\n## タイプ付き Coast の実行\n\n`--type` で作成されたインスタンスには、そのタイプがタグ付けされます。同一プロジェクトで、異なるタイプのインスタンスを同時に実行できます。\n\n```bash\ncoast run dev-1 # default type\ncoast run test-1 --type test # test type\ncoast run snapshot-1 --type snap # snapshot type\n\ncoast ls\n# All three appear, each with their own type, ports, and volume strategy\n```\n\nこれにより、同じプロジェクトに対して、フルの開発環境を動かしながら、分離されたテストランナーやスナップショットでシードされたインスタンスも並行して、すべて同時に運用できます。\n", "concepts_and_terminology/COASTGUARD.md": "# Coastguard\n\nCoastguard は Coast のローカル Web UI(Coast の Docker Desktop 風インターフェースを想定)で、ポート `31415` で動作します。CLI から起動します:\n\n```bash\ncoast ui\n```\n\n![Coastguard project overview](../../assets/coastguard-overview.png)\n*実行中の Coast インスタンス、それらのブランチ/ワークツリー、およびチェックアウト状態を表示するプロジェクトダッシュボード。*\n\n![Coastguard port mappings](../../assets/coastguard-ports.png)\n*特定の Coast インスタンスの ports ページ。各サービスの標準(canonical)および動的なポートマッピングを表示します。*\n\n## What Coastguard Is Good For\n\nCoastguard は、プロジェクトのための視覚的な制御および可観測性のための画面を提供します:\n\n- プロジェクト、インスタンス、ステータス、ブランチ、チェックアウト状態を確認。\n- [ポートマッピング](PORTS.md) を確認し、サービスに直接ジャンプ。\n- [ログ](LOGS.md)、ランタイム統計を表示し、データを検査。\n- [ビルド](BUILDS.md)、イメージ成果物、[ボリューム](VOLUMES.md)、[シークレット](SECRETS.md) のメタデータを参照。\n- 作業しながらアプリ内でドキュメントを閲覧。\n\n## Relationship to CLI and Daemon\n\nCoastguard は CLI を置き換えるものではありません。人間向けのインターフェースとしてそれを補完します。\n\n- [`coast` CLI](CLI.md) は、スクリプト、エージェントのワークフロー、ツール連携のための自動化インターフェースです。\n- Coastguard は、視覚的な確認、対話的なデバッグ、日常的な運用可視性のための人間向けインターフェースです。\n- どちらも [`coastd`](DAEMON.md) のクライアントであるため、同期された状態を保ちます。\n", "concepts_and_terminology/COASTS.md": "# Coast\n\nCoast は、あなたのプロジェクトの自己完結型ランタイムです。[Docker-in-Docker コンテナ](RUNTIMES_AND_SERVICES.md)内で実行され、複数のサービス(Web サーバー、データベース、キャッシュなど)をすべて 1 つの Coast インスタンス内で実行できます。\n\n```text\n┌─── Coast: dev-1 (branch: feature/oauth) ──────────────┐\n│ │\n│ ┌─────────┐ ┌──────────┐ ┌─────────┐ │\n│ │ web │ │ postgres │ │ redis │ │\n│ │ :3000 │ │ :5432 │ │ :6379 │ │\n│ └─────────┘ └──────────┘ └─────────┘ │\n│ │\n│ dynamic ports: 62217, 55681, 56905 │\n└───────────────────────────────────────────────────────┘\n\n┌─── Coast: dev-2 (branch: feature/billing) ────────────┐\n│ │\n│ ┌─────────┐ ┌──────────┐ ┌─────────┐ │\n│ │ web │ │ postgres │ │ redis │ │\n│ │ :3000 │ │ :5432 │ │ :6379 │ │\n│ └─────────┘ └──────────┘ └─────────┘ │\n│ │\n│ dynamic ports: 63104, 57220, 58412 │\n└───────────────────────────────────────────────────────┘\n```\n\n各 Coast は、それぞれ独自の[動的ポート](PORTS.md)のセットをホストマシンに公開します。つまり、他に何が実行中であっても、いつでも任意の実行中の Coast にアクセスできます。\n\nCoast を[チェックアウト](CHECKOUT.md)すると、プロジェクトの正規ポートがその Coast にマッピングされます。したがって、`localhost:3000` は動的ポートではなく、チェックアウトされた Coast にアクセスします。\n\n```text\ncoast checkout dev-1\n\nlocalhost:3000 ──→ dev-1 web\nlocalhost:5432 ──→ dev-1 postgres\nlocalhost:6379 ──→ dev-1 redis\n\ncoast checkout dev-2 (instant swap)\n\nlocalhost:3000 ──→ dev-2 web\nlocalhost:5432 ──→ dev-2 postgres\nlocalhost:6379 ──→ dev-2 redis\n```\n\n通常、Coast は[特定の worktree に割り当て](ASSIGN.md)られます。これにより、同じプロジェクトの複数の worktree を、ポート競合やボリューム衝突なしに並行して実行できます。\n\nCoast インスタンスは [`coast run`](RUN.md) で作成します。Coast をいつ起動し、いつ停止するかはあなた次第です。おそらく、メモリ消費の大きいプロジェクトで 20 個の Coast を同時に動かしたいとは思わないでしょうが、それぞれのやり方があります。\n", "concepts_and_terminology/DAEMON.md": "# Coast Daemon\n\nCoast デーモン(`coastd`)は、実際のオーケストレーション作業を行う長時間稼働のローカルプロセスです。[CLI](CLI.md) と [Coastguard](COASTGUARD.md) はクライアントであり、`coastd` はそれらの背後にあるコントロールプレーンです。\n\n## Architecture at a Glance\n\n```text\ncoast CLI (automation) -----+\n +--> coastd daemon\nCoastguard UI (human) ------+ |\n +--> Coasts\n +--> Ports\n +--> State\n```\n\nCLI はローカルの Unix ソケット経由で `coastd` にリクエストを送信し、Coastguard は WebSocket 経由で接続します。デーモンは実行時状態に変更を適用します。\n\n## What It Does\n\n`coastd` は、永続的な状態とバックグラウンドでの調整を必要とする操作を処理します:\n\n- Coast インスタンス、ビルド、共有サービスを追跡します。\n- Coast ランタイムの作成、起動、停止、削除を行います。\n- assign/unassign/checkout 操作を適用します。\n- 正規および動的な [port forwarding](PORTS.md) を管理します。\n- [logs](LOGS.md)、ステータス、ランタイムイベントを CLI および UI クライアントへストリーミングします。\n\n要するに: `coast run`、`coast assign`、`coast checkout`、または `coast ls` を実行する場合、作業を行うコンポーネントはデーモンです。\n\n## How It Runs\n\nデーモンは一般的に次の 2 つの方法で実行できます:\n\n```bash\n# Register daemon auto-start at login (recommended)\ncoast daemon install\n\n# Manual start mode\ncoast daemon start\n```\n\ndaemon install を省略した場合、Coast コマンドを使用する前に、各セッションで自分で起動する必要があります。\n\n## Reporting Bugs\n\n問題に遭遇した場合は、バグレポートを提出する際に `coastd` デーモンログを含めてください。ログには、ほとんどの問題を診断するのに必要なコンテキストが含まれています:\n\n```bash\ncoast daemon logs\n```\n", - "concepts_and_terminology/EXEC_AND_DOCKER.md": "# Exec & Docker\n\n`coast exec` は、Coast の DinD コンテナ内のシェルへ入ります。作業ディレクトリは `/workspace` — Coastfile が置かれている [bind-mounted なプロジェクトルート](FILESYSTEM.md) です。これはホストマシンから Coast 内でコマンドを実行したり、ファイルを調べたり、サービスをデバッグしたりするための主要な方法です。\n\n`coast docker` は、内側の Docker デーモンと直接やり取りするための補助コマンドです。\n\n## `coast exec`\n\nCoast インスタンス内でシェルを開きます:\n\n```bash\ncoast exec dev-1\n```\n\nこれは `/workspace` で `sh` セッションを開始します。Coast コンテナは Alpine ベースのため、デフォルトのシェルは `bash` ではなく `sh` です。\n\n対話シェルに入らずに、特定のコマンドだけを実行することもできます:\n\n```bash\ncoast exec dev-1 ls -la\ncoast exec dev-1 -- npm install\ncoast exec dev-1 -- go test ./...\n```\n\nインスタンス名の後ろに続くものはすべてコマンドとして渡されます。`--` を使って、実行したいコマンド側のフラグと `coast exec` 側のフラグを分離してください。\n\n### Working Directory\n\nシェルは `/workspace` から開始します。これはホストのプロジェクトルートがコンテナに bind-mount されたものです。つまり、ソースコード、Coastfile、そしてすべてのプロジェクトファイルがそこにあります:\n\n```text\n/workspace $ ls\nCoastfile README.md apps/ packages/\nCoastfile.light go.work infra/ scripts/\nCoastfile.snap go.work.sum package-lock.json\n```\n\n`/workspace` 配下のファイルに加えた変更は、ホスト側に即座に反映されます — コピーではなく bind mount です。\n\n### Interactive vs Non-Interactive\n\nstdin が TTY(ターミナルで入力している状態)の場合、`coast exec` はデーモンを完全にバイパスし、フル TTY パススルーのために `docker exec -it` を直接実行します。これにより、色表示、カーソル移動、タブ補完、対話的プログラムが期待どおり動作します。\n\nstdin がパイプやスクリプト(CI、エージェントワークフロー、`coast exec dev-1 -- some-command | grep foo`)の場合、リクエストはデーモン経由で処理され、構造化された stdout、stderr、および終了コードが返されます。\n\n### File Permissions\n\nexec はホストユーザーの UID:GID として実行されるため、Coast 内で作成したファイルはホスト上でも正しい所有権になります。ホストとコンテナ間で権限の不一致が起きません。\n\n## `coast docker`\n\n`coast exec` が DinD コンテナ自体のシェルを提供するのに対し、`coast docker` は **内側の** Docker デーモン — compose サービスを管理しているデーモン — に対して Docker CLI コマンドを実行できます。\n\n```bash\ncoast docker dev-1 # defaults to: docker ps\ncoast docker dev-1 ps # same as above\ncoast docker dev-1 compose ps # docker compose ps (inner services)\ncoast docker dev-1 images # list images in the inner daemon\ncoast docker dev-1 compose logs web # docker compose logs for a service\n```\n\n渡したすべてのコマンドには自動的に `docker` が前置されます。したがって、`coast docker dev-1 compose ps` は Coast コンテナ内で `docker compose ps` を実行し、内側のデーモンと通信します。\n\n### `coast exec` vs `coast docker`\n\n違いは「何を対象にしているか」です:\n\n| Command | Runs as | Target |\n|---|---|---|\n| `coast exec dev-1 ls /workspace` | DinD コンテナ内で `sh -c \"ls /workspace\"` | Coast コンテナ自体(プロジェクトファイル、インストール済みツール) |\n| `coast docker dev-1 ps` | DinD コンテナ内で `docker ps` | 内側の Docker デーモン(compose サービスのコンテナ) |\n| `coast docker dev-1 compose logs web` | DinD コンテナ内で `docker compose logs web` | 内側のデーモン経由で特定の compose サービスのログ |\n\nプロジェクトレベルの作業 — テスト実行、依存関係のインストール、ファイルの調査 — には `coast exec` を使ってください。内側の Docker デーモンが何をしているか — コンテナ状態、イメージ、ネットワーク、compose 操作 — を確認したい場合は `coast docker` を使ってください。\n\n## Coastguard Exec Tab\n\nCoastguard の Web UI は、WebSocket 経由で接続される永続的な対話ターミナルを提供します。\n\n![Exec tab in Coastguard](../../assets/coastguard-exec.png)\n*Coastguard の Exec タブ。Coast インスタンス内の /workspace でのシェルセッションを表示。*\n\nこのターミナルは xterm.js によって提供され、以下を備えています:\n\n- **永続セッション** — ターミナルセッションはページ移動やブラウザの更新をまたいで維持されます。再接続時にはスクロールバックバッファが再生され、中断したところから続けられます。\n- **複数タブ** — 複数のシェルを同時に開けます。各タブは独立したセッションです。\n- **[Agent shell](AGENT_SHELLS.md) タブ** — AI コーディングエージェント向けの専用エージェントシェルを起動し、アクティブ/非アクティブ状態の追跡ができます。\n- **フルスクリーンモード** — ターミナルを画面全体に拡大します(Escape で終了)。\n\nインスタンスレベルの exec タブに加えて、Coastguard は他のレベルでもターミナルアクセスを提供します:\n\n- **Service exec** — Services タブから個別のサービスをクリックし、その特定の内側コンテナ内のシェルに入ります(`docker exec` を二重に実行 — まず DinD コンテナへ、次にサービスコンテナへ)。\n- **[Shared service](SHARED_SERVICES.md) exec** — ホストレベルの共有サービスコンテナ内のシェルに入ります。\n- **Host terminal** — Coast に入らずに、プロジェクトルートでホストマシン上のシェルを開きます。\n\n## When to Use Which\n\n- **`coast exec`** — DinD コンテナ内で、プロジェクトレベルのコマンド(npm install、go test、ファイル調査、デバッグ)を実行します。\n- **`coast docker`** — 内側の Docker デーモンを調査または管理します(コンテナ状態、イメージ、ネットワーク、compose 操作)。\n- **Coastguard Exec tab** — 永続セッション、複数タブ、エージェントシェル対応による対話的デバッグ。UI の他の部分を操作しながら複数のターミナルを開いたままにしたい場合に最適です。\n- **`coast logs`** — サービス出力を読むには、`coast docker compose logs` の代わりに `coast logs` を使用します。[Logs](LOGS.md) を参照してください。\n- **`coast ps`** — サービス状態を確認するには、`coast docker compose ps` の代わりに `coast ps` を使用します。[Runtimes and Services](RUNTIMES_AND_SERVICES.md) を参照してください。\n", + "concepts_and_terminology/EXEC_AND_DOCKER.md": "# Exec と Docker\n\n`coast exec` は、Coast の DinD コンテナ内のシェルに入ります。作業ディレクトリは `/workspace` です。これは、Coastfile が存在する [bind-mounted project root](FILESYSTEM.md) です。これは、ホストマシンから Coast 内でコマンドを実行したり、ファイルを確認したり、サービスをデバッグしたりするための主要な方法です。\n\n`coast docker` は、内部の Docker デーモンと直接やり取りするための補助コマンドです。\n\n## `coast exec`\n\nCoast インスタンス内でシェルを開きます:\n\n```bash\ncoast exec dev-1\n```\n\nこれにより、`/workspace` で `sh` セッションが開始されます。Coast コンテナは Alpine ベースなので、デフォルトシェルは `bash` ではなく `sh` です。\n\n対話シェルに入らずに、特定のコマンドを実行することもできます:\n\n```bash\ncoast exec dev-1 ls -la\ncoast exec dev-1 -- npm install\ncoast exec dev-1 -- go test ./...\ncoast exec dev-1 --service web\ncoast exec dev-1 --service web -- php artisan test\n```\n\nインスタンス名の後に続くものはすべてコマンドとして渡されます。自分のコマンドに属するフラグと `coast exec` に属するフラグを分けるには、`--` を使用してください。\n\n外側の Coast コンテナではなく、特定の compose サービスコンテナを対象にするには `--service ` を渡します。Coast のデフォルトのホスト UID:GID マッピングではなく、生のコンテナルートアクセスが必要な場合は `--root` を渡します。\n\n### Working Directory\n\nシェルは `/workspace` で開始されます。これは、ホストのプロジェクトルートがコンテナに bind mount されたものです。つまり、ソースコード、Coastfile、およびすべてのプロジェクトファイルがそこにあります:\n\n```text\n/workspace $ ls\nCoastfile README.md apps/ packages/\nCoastfile.light go.work infra/ scripts/\nCoastfile.snap go.work.sum package-lock.json\n```\n\n`/workspace` 配下のファイルに加えた変更は、ホストに即座に反映されます。これはコピーではなく bind mount です。\n\n### Interactive vs Non-Interactive\n\nstdin が TTY のとき(ターミナルで入力しているとき)、`coast exec` はデーモンを完全にバイパスし、完全な TTY パススルーのために `docker exec -it` を直接実行します。これは、色、カーソル移動、タブ補完、対話型プログラムがすべて期待どおりに動作することを意味します。\n\nstdin がパイプまたはスクリプト経由の場合(CI、エージェントワークフロー、`coast exec dev-1 -- some-command | grep foo`)、リクエストはデーモンを通り、構造化された stdout、stderr、および終了コードを返します。\n\n### File Permissions\n\nexec はホストユーザーの UID:GID として実行されるため、Coast 内で作成されたファイルはホスト上で正しい所有権を持ちます。ホストとコンテナの間で権限の不一致は発生しません。\n\n## `coast docker`\n\n`coast exec` は DinD コンテナ自体の中でシェルを提供しますが、`coast docker` は **内部の** Docker デーモン、つまり compose サービスを管理しているものに対して Docker CLI コマンドを実行できます。\n\n```bash\ncoast docker dev-1 # defaults to: docker ps\ncoast docker dev-1 ps # same as above\ncoast docker dev-1 compose ps # docker compose ps for the active Coast-managed stack\ncoast docker dev-1 images # list images in the inner daemon\ncoast docker dev-1 compose logs web # docker compose logs for a service\n```\n\n渡したすべてのコマンドには自動的に `docker` が前置されます。したがって、`coast docker dev-1 compose ps` は Coast コンテナ内で `docker compose ps` を実行し、内部デーモンと通信します。\n\n### `coast exec` vs `coast docker`\n\n違いは、何を対象にしているかです:\n\n| Command | Runs as | Target |\n|---|---|---|\n| `coast exec dev-1 ls /workspace` | DinD コンテナ内での `sh -c \"ls /workspace\"` | Coast コンテナ自体(プロジェクトファイル、インストール済みツール) |\n| `coast exec dev-1 --service web` | 解決された内部サービスコンテナ内での `docker exec ... sh` | 特定の compose サービスコンテナ |\n| `coast docker dev-1 ps` | DinD コンテナ内での `docker ps` | 内部 Docker デーモン(compose サービスコンテナ) |\n| `coast docker dev-1 compose logs web` | DinD コンテナ内での `docker compose logs web` | 内部デーモン経由での特定 compose サービスのログ |\n\nプロジェクトレベルの作業(テストの実行、依存関係のインストール、ファイルの確認)には `coast exec` を使用します。内部 Docker デーモンが何をしているか(コンテナの状態、イメージ、ネットワーク、compose 操作)を確認する必要がある場合は `coast docker` を使用します。\n\n## Coastguard Exec Tab\n\nCoastguard の Web UI は、WebSocket 経由で接続された永続的な対話型ターミナルを提供します。\n\n![Exec tab in Coastguard](../../assets/coastguard-exec.png)\n*Coast インスタンス内の /workspace でのシェルセッションを表示している Coastguard Exec タブ。*\n\nこのターミナルは xterm.js によって提供され、以下を備えています:\n\n- **永続セッション** — ターミナルセッションは、ページ移動やブラウザのリフレッシュ後も維持されます。再接続するとスクロールバックバッファが再生されるため、中断したところから再開できます。\n- **複数タブ** — 複数のシェルを同時に開けます。各タブは独立したセッションです。\n- **[Agent shell](AGENT_SHELLS.md) タブ** — AI コーディングエージェント用の専用エージェントシェルを起動でき、アクティブ/非アクティブ状態の追跡があります。\n- **フルスクリーンモード** — ターミナルを画面いっぱいに拡大します(終了は Escape)。\n\nインスタンスレベルの exec タブに加えて、Coastguard は他のレベルでもターミナルアクセスを提供します:\n\n- **Service exec** — Services タブから個別のサービスに入ると、その特定の内部コンテナ内のシェルを取得できます(これは二重の `docker exec` を行います。最初に DinD コンテナに入り、次にサービスコンテナに入ります)。\n- **[Shared service](SHARED_SERVICES.md) exec** — ホストレベルの共有サービスコンテナ内のシェルを取得できます。\n- **Host terminal** — Coast に入ることなく、プロジェクトルートでホストマシン上のシェルを使えます。\n\n## When to Use Which\n\n- **`coast exec`** — DinD コンテナ内でプロジェクトレベルのコマンドを実行する、または `--service` を渡して特定の compose サービスコンテナ内でシェルを開くかコマンドを実行します。\n- **`coast docker`** — 内部 Docker デーモンを確認または管理します(コンテナの状態、イメージ、ネットワーク、compose 操作)。\n- **Coastguard Exec tab** — 永続セッション、複数タブ、エージェントシェル対応を備えた対話型デバッグ向け。UI の他の部分を移動しながら複数のターミナルを開いたままにしたい場合に最適です。\n- **`coast logs`** — サービス出力を読むには、`coast docker compose logs` ではなく `coast logs` を使用してください。[Logs](LOGS.md) を参照してください。\n- **`coast ps`** — サービス状態を確認するには、`coast docker compose ps` ではなく `coast ps` を使用してください。[Runtimes and Services](RUNTIMES_AND_SERVICES.md) を参照してください。\n", "concepts_and_terminology/FILESYSTEM.md": "# Filesystem\n\nホストマシンと各 Coast インスタンスは同じプロジェクトファイルを共有します。ホスト側のプロジェクトルートは DinD コンテナ内の `/host-project` に読み書き可能でマウントされ、Coast はアクティブな作業ツリーを `/workspace` にバインドマウントします。これにより、ホストマシン上で動作するエージェントがコードを編集しつつ、Coast 内のサービスが変更をリアルタイムで反映できるようになります。\n\n## The Shared Mount\n\n```text\nHost machine\n│\n├── ~/dev/my-app/ (project root)\n│ ├── src/\n│ ├── Coastfile\n│ ├── docker-compose.yml\n│ └── .worktrees/ (worktrees, gitignored)\n│ ├── feature-auth/\n│ └── feature-billing/\n│\n└── Docker daemon (host)\n │\n └── Coast: dev-1 (docker:dind)\n │\n ├── /host-project ← Docker bind mount of project root (RW, fixed)\n │\n ├── /workspace ← mount --bind /host-project (switchable)\n │ ├── src/ same files, same bytes, instant sync\n │ ├── Coastfile\n │ └── docker-compose.yml\n │\n └── Inner Docker daemon\n └── web service\n └── /app ← compose bind mount from /workspace/src\n```\n\nホスト側のプロジェクトルートは、コンテナ作成時に [DinD コンテナ](RUNTIMES_AND_SERVICES.md) 内の `/host-project` に読み書き可能でマウントされます。コンテナ起動後、コンテナ内で `mount --bind /host-project /workspace` を実行し、共有マウント伝播(`mount --make-rshared`)付きの作業用 `/workspace` パスを作成します。これにより、`/workspace` のサブディレクトリを bind-mount する内側の compose サービスは正しい内容を参照できます。\n\nこの二段階のアプローチには理由があります。`/host-project` の Docker bind mount はコンテナ作成時に固定され、コンテナを再作成しない限り変更できません。一方、コンテナ内の Linux bind mount である `/workspace` は、コンテナのライフサイクルに触れずにアンマウントして別のサブディレクトリ(worktree)へ再バインドできます。これが `coast assign` を高速にしている要因です。\n\n`/workspace` は読み書き可能です。ファイル変更は両方向に即時反映されます。ホストでファイルを保存すると Coast 内の dev サーバーがそれを拾います。Coast 内でファイルを作成するとホストに表示されます。\n\n## Host Agents and Coast\n\n```text\n┌─── Host machine ──────────────────────────────────────────┐\n│ │\n│ AI Agent (Cursor, Claude Code, etc.) │\n│ │ │\n│ ├── reads/writes files at /src/ │\n│ │ ↕ (instant, same filesystem) │\n│ ├── coast logs dev-1 --service web --tail 50 │\n│ ├── coast ps dev-1 │\n│ └── coast exec dev-1 -- npm test │\n│ │\n├───────────────────────────────────────────────────────────┤\n│ │\n│ Coast: dev-1 │\n│ └── /workspace/src/ ← same bytes as host project/src │\n│ └── web service picks up changes on save │\n│ │\n└───────────────────────────────────────────────────────────┘\n```\n\nファイルシステムが共有されているため、ホスト上で動作する AI コーディングエージェントは自由にファイルを編集でき、Coast 内で稼働中のサービスは変更を即座に認識します。エージェントは Coast コンテナ内で動作する必要はなく、通常どおりホストから操作できます。\n\nエージェントが実行時情報(ログ、サービス状態、テスト出力など)を必要とする場合は、ホストから Coast CLI コマンドを呼び出します。\n\n- `coast logs dev-1 --service web --tail 50` でサービス出力を確認([Logs](LOGS.md) を参照)\n- `coast ps dev-1` でサービス状態を確認([Runtimes and Services](RUNTIMES_AND_SERVICES.md) を参照)\n- `coast exec dev-1 -- npm test` で Coast 内でコマンドを実行([Exec & Docker](EXEC_AND_DOCKER.md) を参照)\n\nこれが基本となるアーキテクチャ上の利点です: **コード編集はホストで行い、実行は Coast で行い、共有ファイルシステムがそれらを橋渡しします。** ホスト側エージェントは作業のために Coast の「内側」に入る必要がありません。\n\n## Worktree Switching\n\n`coast assign` が Coast を別の worktree に切り替えると、プロジェクトルートではなくその git worktree を指すように `/workspace` を再マウントします。\n\n```text\ncoast assign dev-1 --worktree feature-auth\n\nBefore: /workspace ←──mount── /host-project (project root)\nAfter: /workspace ←──mount── /host-project/.worktrees/feature-auth (worktree)\n```\n\nworktree はホスト上の `{project_root}/.worktrees/{worktree_name}` に作成されます。`.worktrees` ディレクトリ名は Coastfile の `worktree_dir` で設定可能で、`.gitignore` に含めるべきです。\n\nworktree が新規の場合、Coast は再マウントの前に、プロジェクトルートから選択した gitignored ファイルをブートストラップします。`git ls-files --others --ignored --exclude-standard` で無視ファイルを列挙し、一般的に重いディレクトリと設定された `exclude_paths` を除外してから、`rsync --files-from` と `--link-dest` を用いて選択ファイルを worktree へハードリンクします。Coast はそのブートストラップを内部 worktree メタデータに記録し、同一 worktree への後続の assign では、`coast assign --force-sync` で明示的に更新しない限りスキップします。\n\nコンテナ内では、`/workspace` が遅延アンマウントされ、`/host-project/.worktrees/{branch_name}` にある worktree サブディレクトリへ再バインドされます。この再マウントは高速で、DinD コンテナの再作成や内側の Docker デーモン再起動は行いません。compose サービスおよび bare サービスは、新しい `/workspace` を経由して bind mount が解決されるよう、再マウント後に再作成または再起動されることがあります。\n\n`node_modules` のような大きな依存ディレクトリは、この汎用ブートストラップ経路の対象ではありません。通常はサービス固有のキャッシュやボリュームによって扱います。\n\n`[assign.rebuild_triggers]` を使用している場合、Coast はホスト上で `git diff --name-only ..` も実行し、`rebuild` とマークされたサービスを `restart` に格下げできるかどうかを判断します。assign のレイテンシに影響する詳細は [Assign and Unassign](ASSIGN.md) および [Performance Optimizations](PERFORMANCE_OPTIMIZATIONS.md) を参照してください。\n\n`coast unassign` は `/workspace` を `/host-project`(プロジェクトルート)に戻します。停止後に `coast start` を実行すると、インスタンスに worktree が割り当てられているかどうかに基づいて、正しいマウントが再適用されます。\n\n## All Mounts\n\nすべての Coast コンテナには次のマウントがあります。\n\n| Path | Type | Access | Purpose |\n|---|---|---|---|\n| `/workspace` | bind mount (in-container) | RW | プロジェクトルートまたは worktree。assign で切り替え可能。 |\n| `/host-project` | Docker bind mount | RW | 生のプロジェクトルート。コンテナ作成時に固定。 |\n| `/image-cache` | Docker bind mount | RO | `~/.coast/image-cache/` からの事前 pull 済み OCI tarball。 |\n| `/coast-artifact` | Docker bind mount | RO | 書き換え済み compose ファイルを含むビルド成果物。 |\n| `/coast-override` | Docker bind mount | RO | [shared services](SHARED_SERVICES.md) 向けに生成された compose オーバーライド。 |\n| `/var/lib/docker` | Named volume | RW | 内側の Docker デーモン状態。コンテナ削除後も永続化。 |\n\n読み取り専用マウントはインフラです。Coast が生成するビルド成果物、キャッシュ済みイメージ、compose オーバーライドを運びます。これらは `coast build` と Coastfile を通じて間接的に操作します。読み書き可能マウントは、あなたのコードが存在する場所であり、内側のデーモンが状態を保存する場所です。\n", "concepts_and_terminology/LOGS.md": "# ログ\n\nCoast 内のサービスはネストされたコンテナ内で動作します。つまり、あなたの compose サービスは DinD コンテナ内の内側の Docker デーモンによって管理されています。これは、ホストレベルのロギングツールからはそれらが見えないことを意味します。ホスト上で Docker ログを読む logging MCP をワークフローに含めている場合、見えるのは外側の DinD コンテナだけで、その内側で動作している Web サーバー、データベース、ワーカーは見えません。\n\n解決策は `coast logs` です。Coast インスタンスからサービス出力を読む必要があるエージェントやツールは、ホストレベルの Docker ログアクセスではなく Coast CLI を使用する必要があります。\n\n## MCP のトレードオフ\n\nlogging MCP(ホストから Docker コンテナログを取得するツール — [MCP Servers](MCP_SERVERS.md) を参照)を備えた AI エージェントを使用している場合、その MCP は Coast 内で動作しているサービスには機能しません。ホストの Docker デーモンからは Coast インスタンスごとに 1 つのコンテナ(DinD コンテナ)しか見えず、そのログは内側の Docker デーモンの起動出力にすぎません。\n\n実際のサービスログを取得するには、エージェントに次を使用するよう指示してください:\n\n```bash\ncoast logs --service --tail \n```\n\nたとえば、バックエンドサービスが失敗している理由をエージェントが調査する必要がある場合:\n\n```bash\ncoast logs dev-1 --service backend --tail 100\n```\n\nこれは `docker compose logs` と同等ですが、Coast デーモン経由で内側の DinD コンテナにルーティングされます。logging MCP を参照するエージェントルールや system prompt がある場合、Coast 内で作業するときにこの挙動を上書きする指示を追加する必要があります。\n\n## `coast logs`\n\nCLI は Coast インスタンスからログを読むためのいくつかの方法を提供します:\n\n```bash\ncoast logs dev-1 # last 200 lines, all services\ncoast logs dev-1 --service web # last 200 lines, web only\ncoast logs dev-1 --tail 50 # last 50 lines, then follow\ncoast logs dev-1 --tail # all lines, then follow\ncoast logs dev-1 --service backend -f # follow mode (stream new entries)\ncoast logs dev-1 --service web --tail 100 # last 100 lines + follow\n```\n\n`--tail` または `-f` がない場合、コマンドは最後の 200 行を返して終了します。`--tail` を付けると、指定した行数をストリームし、その後も新しい出力をリアルタイムで追従し続けます。`-f` / `--follow` は単独で follow モードを有効にします。\n\n出力は compose のログ形式を使用し、各行にサービスのプレフィックスが付きます:\n\n```text\nweb | 2026/02/28 01:49:34 Listening on :3000\nbackend | 2026/02/28 01:49:34 [INFO] Server started on :8080\nbackend | 2026/02/28 01:49:34 [ProcessCreditsJob] starting at 2026-02-28T01:49:34Z\nredis | 1:M 28 Feb 2026 01:49:30.123 * Ready to accept connections\n```\n\nレガシーな位置引数の構文(`coast logs dev-1 web`)でもサービスでフィルタできますが、`--service` フラグの使用が推奨されます。\n\n## Coastguard の Logs タブ\n\nCoastguard の Web UI は、WebSocket 経由のリアルタイムストリーミングを備えた、よりリッチなログ閲覧体験を提供します。\n\n![Logs tab in Coastguard](../../assets/coastguard-logs.png)\n*サービスフィルタと検索を備え、バックエンドサービス出力をストリーミングしている Coastguard の Logs タブ。*\n\nLogs タブが提供する機能:\n\n- **リアルタイムストリーミング** — ログは生成されると同時に WebSocket 接続を通じて到着し、接続状態を示すステータスインジケータがあります。\n- **サービスフィルタ** — ログストリームのサービスプレフィックスから生成されるドロップダウン。単一サービスを選択してその出力に集中できます。\n- **検索** — 表示されている行をテキストまたは正規表現でフィルタ(アスタリスクボタンで正規表現モードを切り替え)。一致した用語はハイライトされます。\n- **行数** — フィルタ後の行数と総行数を表示(例: \"200 / 971 lines\")。\n- **Clear** — 内側コンテナのログファイルを切り詰め、ビューアをリセットします。\n- **Fullscreen** — ログビューアを画面いっぱいに拡大します。\n\nログ行は ANSI カラーに対応して描画され、ログレベルの強調表示(ERROR は赤、WARN は琥珀色、INFO は青、DEBUG は灰色)、タイムスタンプの減光、サービス間の視覚的な区別のための色付きサービスバッジが提供されます。\n\nホストデーモン上で動作する共有サービスは、Shared Services タブからアクセスできる専用のログビューアを持ちます。詳細は [Shared Services](SHARED_SERVICES.md) を参照してください。\n\n## 仕組み\n\n`coast logs` を実行すると、デーモンは `docker exec` を介して DinD コンテナ内で `docker compose logs` を実行し、出力を端末(または Coastguard UI へ WebSocket 経由)にストリームで返します。\n\n```text\ncoast logs dev-1 --service web --tail 50\n │\n ├── CLI sends LogsRequest to daemon (Unix socket)\n │\n ├── Daemon resolves instance → container ID\n │\n ├── Daemon exec's into DinD container:\n │ docker compose logs --tail 50 --follow web\n │\n └── Output streams back chunk by chunk\n └── CLI prints to stdout / Coastguard renders in UI\n```\n\n[bare services](BARE_SERVICES.md) の場合、デーモンは `docker compose logs` を呼び出す代わりに `/var/log/coast-services/` のログファイルを tail します。出力形式は同じ(`service | line`)なので、どちらの場合もサービスフィルタリングは同様に機能します。\n\n## 関連コマンド\n\n- `coast ps ` — 実行中のサービスとそのステータスを確認します。[Runtimes and Services](RUNTIMES_AND_SERVICES.md) を参照してください。\n- [`coast exec `](EXEC_AND_DOCKER.md) — 手動デバッグのために Coast コンテナ内でシェルを開きます。\n", "concepts_and_terminology/LOOKUP.md": "# Lookup\n\n`coast lookup` は、呼び出し元の現在の作業ディレクトリに対して、どの Coast インスタンスが稼働しているかを検出します。これはホスト側エージェントが状況把握のために最初に実行すべきコマンドです — 「ここでコードを編集しているが、どの Coast とやり取りすべきか?」\n\n```bash\ncoast lookup\n```\n\nLookup は、あなたが [worktree](ASSIGN.md) の内側にいるのか、あるいはプロジェクトルートにいるのかを検出し、該当するインスタンスをデーモンに問い合わせ、ポート、URL、サンプルコマンド付きで結果を表示します。\n\n## Why This Exists\n\nホスト上で動作する AI コーディングエージェント(Cursor、Claude Code、Codex など)は、[shared filesystem](FILESYSTEM.md) を通じてファイルを編集し、実行時の操作のために Coast CLI コマンドを呼び出します。しかしその前に、エージェントは基本的な質問に答える必要があります: **自分が作業しているディレクトリに対応する Coast インスタンスはどれか?**\n\n`coast lookup` がない場合、エージェントは `coast ls` を実行し、インスタンス表全体を解析し、どの worktree にいるのかを突き止め、照合しなければなりません。`coast lookup` はそれらを 1 ステップで行い、エージェントが直接消費できる構造化出力を返します。\n\nこのコマンドは、Coast を使うエージェントワークフロー向けのトップレベル SKILL.md、AGENTS.md、またはルールファイルに含めるべきです。これは、エージェントが実行時コンテキストを発見するための入口です。\n\n## Output Modes\n\n### Default (human-readable)\n\n```bash\ncoast lookup\n```\n\n```text\nCoast instances for worktree feature/oauth (my-app):\n\n dev-1 running ★ checked out\n\n Primary URL: http://dev-1.localhost:62217\n\n SERVICE CANONICAL DYNAMIC\n ★ web 3000 62217\n api 8080 63889\n postgres 5432 55681\n\n Examples (exec starts at the workspace root where your Coastfile is, cd to your target directory first):\n coast exec dev-1 -- sh -c \"cd && \"\n coast logs dev-1 --service \n coast ps dev-1\n```\n\nexamples セクションは、`coast exec` がワークスペースルート — Coastfile が存在するディレクトリ — から開始されることを、エージェント(および人間)に思い出させます。サブディレクトリでコマンドを実行するには、exec 内でそのディレクトリへ `cd` します。\n\n### Compact (`--compact`)\n\nインスタンス名の JSON 配列を返します。どのインスタンスを対象にすべきかだけを知りたいスクリプトやエージェントツール向けです。\n\n```bash\ncoast lookup --compact\n```\n\n```text\n[\"dev-1\"]\n```\n\n同じ worktree 上に複数のインスタンスがある場合:\n\n```text\n[\"dev-1\",\"dev-2\"]\n```\n\n一致なし:\n\n```text\n[]\n```\n\n### JSON (`--json`)\n\n完全な構造化レスポンスを整形済み JSON として返します。ポート、URL、ステータスを機械可読形式で必要とするエージェント向けです。\n\n```bash\ncoast lookup --json\n```\n\n```json\n{\n \"project\": \"my-app\",\n \"worktree\": \"feature/oauth\",\n \"project_root\": \"/Users/dev/my-app\",\n \"instances\": [\n {\n \"name\": \"dev-1\",\n \"status\": \"Running\",\n \"checked_out\": true,\n \"branch\": \"feature/oauth\",\n \"primary_url\": \"http://dev-1.localhost:62217\",\n \"ports\": [\n { \"logical_name\": \"web\", \"canonical_port\": 3000, \"dynamic_port\": 62217, \"is_primary\": true },\n { \"logical_name\": \"api\", \"canonical_port\": 8080, \"dynamic_port\": 63889, \"is_primary\": false }\n ]\n }\n ]\n}\n```\n\n## How It Resolves\n\nLookup は、現在の作業ディレクトリから上位へ辿って最も近い Coastfile を見つけ、その後、あなたがどの worktree にいるのかを判定します:\n\n1. cwd が `{project_root}/{worktree_dir}/{name}/...` の配下にある場合、lookup はその worktree に割り当てられたインスタンスを見つけます。\n2. cwd がプロジェクトルート(または worktree の内側ではない任意のディレクトリ)の場合、lookup は **worktree が割り当てられていない** インスタンス — まだプロジェクトルートを指しているもの — を見つけます。\n\nこれは、lookup がサブディレクトリからでも機能することを意味します。`my-app/.worktrees/feature-oauth/src/api/` にいる場合でも、lookup は `feature-oauth` を worktree として解決します。\n\n## Exit Codes\n\n| Code | Meaning |\n|------|---------|\n| 0 | 1 つ以上の一致するインスタンスが見つかった |\n| 1 | 一致するインスタンスがない(空の結果) |\n\nこれにより、lookup をシェルの条件分岐で利用できます:\n\n```bash\nif coast lookup > /dev/null 2>&1; then\n coast exec dev-1 -- sh -c \"cd src && npm test\"\nfi\n```\n\n## For Agent Workflows\n\n典型的なエージェント統合パターン:\n\n1. エージェントは worktree ディレクトリで作業を開始する。\n2. エージェントは `coast lookup` を実行して、インスタンス名、ポート、URL、サンプルコマンドを発見する。\n3. エージェントは以後のすべての Coast コマンドでインスタンス名を使用する: `coast exec`、`coast logs`、`coast ps`。\n\n```text\n┌─── Agent (host machine) ────────────────────────────┐\n│ │\n│ 1. coast lookup │\n│ → instance names, ports, URLs, examples │\n│ 2. coast exec dev-1 -- sh -c \"cd src && npm test\" │\n│ 3. coast logs dev-1 --service web --tail 50 │\n│ 4. coast ps dev-1 │\n│ │\n└──────────────────────────────────────────────────────┘\n```\n\nエージェントが複数の worktree にまたがって作業している場合、各 worktree ディレクトリから `coast lookup` を実行して、それぞれのコンテキストに対する正しいインスタンスを解決します。\n\nホストエージェントが Coast とどのようにやり取りするかについては [Filesystem](FILESYSTEM.md) を、worktree の概念については [Assign and Unassign](ASSIGN.md) を、Coast 内でコマンドを実行する方法については [Exec & Docker](EXEC_AND_DOCKER.md) を参照してください。\n", @@ -1216,13 +1233,20 @@ "concepts_and_terminology/SHARED_SERVICES.md": "# 共有サービス\n\n共有サービスは、Coast の内部ではなく、ホストの Docker デーモン上で実行されるデータベースおよびインフラ用コンテナ(Postgres、Redis、MongoDB など)です。Coast インスタンスはブリッジネットワーク経由でそれらに接続するため、すべての Coast が同じホストボリューム上の同じサービスと通信します。\n\n![Shared services in Coastguard](../../assets/coastguard-shared-services.png)\n*ホスト管理の Postgres、Redis、MongoDB を表示している Coastguard の共有サービスタブ。*\n\n## 仕組み\n\nCoastfile で共有サービスを宣言すると、Coast はそれをホストデーモン上で起動し、各 Coast コンテナ内で実行される compose スタックからは取り除きます。その後、Coast はサービス名宛てのトラフィックを共有コンテナへ戻すように設定され、同時に Coast 内ではそのサービスのコンテナ側ポートが維持されます。\n\n```text\nHost Docker daemon\n |\n +--> postgres (host volume: infra_postgres_data)\n +--> redis (host volume: infra_redis_data)\n +--> mongodb (host volume: infra_mongodb_data)\n |\n +--> Coast: dev-1 --bridge network--> host postgres, redis, mongodb\n +--> Coast: dev-2 --bridge network--> host postgres, redis, mongodb\n```\n\n共有サービスは既存のホストボリュームを再利用するため、ローカルで `docker-compose up` を実行してすでに存在しているデータは、すぐに Coasts から利用できます。\n\nこの違いは、マップされたポートを使用する場合に重要になります。\n\n```toml\n[shared_services.postgis]\nimage = \"ghcr.io/baosystems/postgis:12-3.3\"\nports = [\"5433:5432\"]\n```\n\n- ホスト上では、共有サービスは `localhost:5433` で公開されます。\n- 各 Coast の内部では、アプリコンテナは引き続き `postgis:5432` に接続します。\n- `5432` のような単独の整数は、同一マッピング `\"5432:5432\"` の省略記法です。\n\n## 共有サービスを使うべきタイミング\n\n- プロジェクトにローカルデータベースへ接続する MCP 統合がある場合、共有サービスを使うことで動的なポート検出なしでもそれらを引き続き利用できます。共有サービスを、ツールがすでに使用しているのと同じホストポートで公開する場合(たとえば `ports = [5432]`)、それらのツールは変更なしで動作し続けます。別のホストポートで公開する場合(たとえば `\"5433:5432\"`)、ホスト側ツールはそのホストポートを使用し、Coasts は引き続きコンテナポートを使用します。\n- 各 Coast インスタンスが独自のデータベースコンテナを実行する必要がないため、より軽量な Coast インスタンスにしたい場合。\n- Coast インスタンス間でデータ分離が不要な場合(すべてのインスタンスが同じデータを参照します)。\n- ホスト上でコーディングエージェントを実行していて([Filesystem](FILESYSTEM.md) を参照)、[`coast exec`](EXEC_AND_DOCKER.md) を経由せずにそれらからデータベースの状態へアクセスしたい場合。共有サービスを使えば、エージェントの既存のデータベースツールや MCP は変更なしで動作します。\n\n分離が必要な場合の代替手段については、[Volume Topology](VOLUMES.md) ページを参照してください。\n\n## ボリュームの曖昧性に関する警告\n\nDocker のボリューム名は、常にグローバルに一意であるとは限りません。複数の異なるプロジェクトから `docker-compose up` を実行している場合、Coast が共有サービスに接続するホストボリュームが、想定しているものではない可能性があります。\n\n共有サービス付きで Coasts を起動する前に、最後に実行した `docker-compose up` が、Coasts で使用するつもりのプロジェクトからのものであることを確認してください。これにより、ホストボリュームが Coastfile の想定と一致するようになります。\n\n## トラブルシューティング\n\n共有サービスが誤ったホストボリュームを参照しているように見える場合:\n\n1. [Coastguard](COASTGUARD.md) UI(`coast ui`)を開きます。\n2. **Shared Services** タブに移動します。\n3. 影響を受けているサービスを選択し、**Remove** をクリックします。\n4. **Refresh Shared Services** をクリックして、現在の Coastfile 設定からそれらを再作成します。\n\nこれにより、共有サービスコンテナが停止・再作成され、正しいホストボリュームに再接続されます。\n", "concepts_and_terminology/TROUBLESHOOTING.md": "# トラブルシューティング\n\nCoasts の問題の多くは、古い状態、孤立した Docker リソース、または同期がずれたデーモンに起因します。このページでは、軽度から最終手段までのエスカレーション手順を説明します。\n\n## Doctor\n\n何かがおかしいと感じる場合 — インスタンスが実行中と表示されるのに何も応答しない、ポートが詰まっているように見える、または UI が古いデータを表示している — まずは `coast doctor` から始めてください:\n\n```bash\ncoast doctor\n```\n\nDoctor は状態データベースと Docker をスキャンし、不整合を検出します: コンテナが欠落している孤立したインスタンスレコード、状態レコードのない宙ぶらりんのコンテナ、実際には死んでいるのに実行中とマークされた共有サービス。見つかったものは自動的に修復します。\n\n何も変更せずに、実行した場合に何をするかをプレビューするには:\n\n```bash\ncoast doctor --dry-run\n```\n\n## Daemon Restart\n\nデーモン自体が応答しないように見える、または不正な状態にある疑いがある場合は、再起動してください:\n\n```bash\ncoast daemon restart\n```\n\nこれは穏やかなシャットダウンシグナルを送信し、デーモンの終了を待ってから、新しいプロセスを起動します。インスタンスと状態は保持されます。\n\n## Removing a Single Project\n\n問題が 1 つのプロジェクトに限定されている場合は、他に影響を与えずに、そのビルド成果物と関連する Docker リソースを削除できます:\n\n```bash\ncoast rm-build my-project\n```\n\nこれはプロジェクトの成果物ディレクトリ、Docker イメージ、ボリューム、コンテナを削除します。最初に確認を求めます。プロンプトをスキップするには `--force` を渡してください。\n\n## Missing Shared Service Images\n\n`coast run` が共有サービスの作成中に `No such image: postgres:15` のようなエラーで失敗する場合、そのイメージがホストの Docker デーモンに存在しません。\n\nこれは、`Coastfile` で Postgres や Redis のような `shared_services` を定義しているものの、Docker がそれらのイメージをまだ pull していない場合に最もよく起こります。\n\n不足しているイメージを pull してから、インスタンスをもう一度実行してください:\n\n```bash\ndocker pull postgres:15\ndocker pull redis:7\ncoast run my-instance\n```\n\nどのイメージが不足しているかわからない場合、失敗した `coast run` の出力に、Docker のエラー内でイメージ名が含まれます。プロビジョニングの試行が失敗した後、Coasts は部分的なインスタンスを自動的にクリーンアップするため、インスタンスが `stopped` に戻るのは想定どおりです。\n\n## Factory Reset with Nuke\n\n他の方法では解決しない場合 — あるいは完全にクリーンな状態からやり直したい場合 — `coast nuke` はフルの工場出荷状態リセットを実行します:\n\n```bash\ncoast nuke\n```\n\nこれにより、次が実行されます:\n\n1. `coastd` デーモンを停止する。\n2. coast が管理する Docker コンテナを **すべて** 削除する。\n3. coast が管理する Docker ボリュームを **すべて** 削除する。\n4. coast が管理する Docker ネットワークを **すべて** 削除する。\n5. coast の Docker イメージを **すべて** 削除する。\n6. `~/.coast/` ディレクトリ全体(状態データベース、ビルド、ログ、シークレット、イメージキャッシュ)を削除する。\n7. `~/.coast/` を再作成し、デーモンを再起動して、coast をすぐに再び使えるようにする。\n\nこれはすべてを破壊するため、確認プロンプトで `nuke` と入力する必要があります:\n\n```text\n$ coast nuke\nWARNING: This will permanently destroy ALL coast data:\n\n - Stop the coastd daemon\n - Remove all coast-managed Docker containers\n - Remove all coast-managed Docker volumes\n - Remove all coast-managed Docker networks\n - Remove all coast Docker images\n - Delete ~/.coast/ (state DB, builds, logs, secrets, image cache)\n\nType \"nuke\" to confirm:\n```\n\nプロンプトをスキップするには `--force` を渡してください(スクリプトで便利です):\n\n```bash\ncoast nuke --force\n```\n\nnuke の後、coast は使用可能な状態になっています — デーモンは稼働しており、ホームディレクトリも存在します。あとはプロジェクトを再度 `coast build` して `coast run` するだけです。\n\n## Reporting Bugs\n\n上記のいずれでも解決しない問題に遭遇した場合は、報告時にデーモンログを含めてください:\n\n```bash\ncoast daemon logs\n```\n", "concepts_and_terminology/VOLUMES.md": "# ボリュームトポロジー\n\nCoast は、データ量の多いサービス(データベース、キャッシュなど)が Coast インスタンス間でデータをどのように保存・共有するかを制御する 3 つのボリューム戦略を提供します。適切な戦略の選択は、どれだけの分離(アイソレーション)が必要か、そしてどれだけのオーバーヘッドを許容できるかに依存します。\n\n## 共有サービス\n\n[共有サービス](SHARED_SERVICES.md) は、いかなる Coast コンテナの外側、つまりホストの Docker デーモン上で動作します。Postgres、MongoDB、Redis などのサービスはホストマシン上に留まり、Coast インスタンスはブリッジネットワーク経由でホストへ呼び出しをルーティングして戻します。\n\n```text\nHost machine\n |\n +--> Postgres (host daemon, existing volume)\n +--> Redis (host daemon, existing volume)\n |\n +--> Coast: dev-1 --connects to--> host Postgres, host Redis\n +--> Coast: dev-2 --connects to--> host Postgres, host Redis\n```\n\nインスタンス間のデータ分離はありません — すべての Coast が同じデータベースと通信します。その代わり、次の利点があります:\n\n- 自前のデータベースコンテナを起動しないため、Coast インスタンスが軽量になります。\n- 既存のホストボリュームがそのまま直接再利用されるため、すでにあるデータは即座に利用できます。\n- ローカルデータベースに接続する MCP 統合は、追加設定なしですぐに動作し続けます。\n\nこれは [Coastfile](COASTFILE_TYPES.md) の `[shared_services]` で設定します。\n\n## 共有ボリューム\n\n共有ボリュームは、すべての Coast インスタンスで共有される単一の Docker ボリュームをマウントします。サービス自体(Postgres、Redis など)は各 Coast コンテナ内で動作しますが、全員が同じ基盤となるボリュームに対して読み書きします。\n\n```text\nCoast: dev-1 --mounts--> shared volume \"my-project-postgres\"\nCoast: dev-2 --mounts--> shared volume \"my-project-postgres\"\n```\n\nこれにより、ホストマシン上のものから Coast のデータを分離できますが、インスタンス同士では引き続きデータを共有します。ホストの開発環境から明確に切り離したい一方で、インスタンスごとのボリュームによるオーバーヘッドは避けたい場合に有用です。\n\n```toml\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## 分離ボリューム\n\n分離ボリュームは、各 Coast インスタンスに独立した専用ボリュームを提供します。インスタンス間でもホストとも、データは一切共有されません。各インスタンスは空の状態(またはスナップショットから — 下記参照)で開始し、それぞれ独立に分岐していきます。\n\n```text\nCoast: dev-1 --mounts--> volume \"dev-1-postgres\"\nCoast: dev-2 --mounts--> volume \"dev-2-postgres\"\n```\n\nこれは、統合テストが多く、並列環境間で真のボリューム分離が必要なプロジェクトにとって最適な選択です。トレードオフとして、各インスタンスがデータのコピーを保持するため、起動が遅くなり Coast のビルドも大きくなります。\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## スナップショット\n\n共有および分離の両戦略は、デフォルトでは空のボリュームから開始します。既存のホストボリュームのコピーを使ってインスタンスを開始したい場合は、`snapshot_source` をコピー元の Docker ボリューム名に設定してください:\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\nスナップショットは [ビルド時](BUILDS.md) に取得されます。作成後は各インスタンスのボリュームが独立に分岐し — 変更はソースにも他のインスタンスにも反映(伝播)されません。\n\nCoast はまだランタイムでのスナップショット(例: 実行中インスタンスからのボリュームスナップショット)をサポートしていません。これは将来のリリースで予定されています。\n", - "harnesses/README.md": "# Harnesses\n\n各 harness は異なる場所に git worktree を作成します。Coasts では、\n[`worktree_dir`](../coastfiles/WORKTREE_DIR.md) 配列によって、どこを探すかを指定します --\nこれには、追加の bind mount を必要とする `~/.codex/worktrees` のような\n外部パスも含まれます。\n\n各 harness には、プロジェクトレベルの instructions、skills、commands について、それぞれ独自の慣習もあります。以下のマトリクスは各 harness が何をサポートしているかを示しており、Coasts のガイダンスをどこに置けばよいかが分かります。各ページでは、Coastfile の設定、推奨されるファイルレイアウト、その harness に固有の注意点を扱います。\n\n1 つのリポジトリを複数の harness から使用する場合は、[Multiple Harnesses](MULTIPLE_HARNESSES.md) を参照してください。\n\n| Harness | Worktree location | Project instructions | Skills | Commands | Page |\n|---------|-------------------|----------------------|--------|----------|------|\n| OpenAI Codex | `~/.codex/worktrees` | `AGENTS.md` | `.agents/skills/` | Skills surface as `/` commands | [Codex](CODEX.md) |\n| Claude Code | `.claude/worktrees` | `CLAUDE.md` | `.claude/skills/` | `.claude/commands/` | [Claude Code](CLAUDE_CODE.md) |\n| Cursor | `~/.cursor/worktrees/` | `AGENTS.md` or `.cursor/rules/` | `.cursor/skills/` or `.agents/skills/` | `.cursor/commands/` | [Cursor](CURSOR.md) |\n| Conductor | `~/conductor/workspaces/` | `CLAUDE.md` | -- | -- | [Conductor](CONDUCTOR.md) |\n| T3 Code | `~/.t3/worktrees/` | `AGENTS.md` | `.agents/skills/` | -- | [T3 Code](T3_CODE.md) |\n\n## Skills vs Commands\n\nSkills と commands はどちらも、再利用可能な `/coasts` ワークフローを定義できます。使っている harness が何をサポートしているかに応じて、どちらか一方、または両方を使えます。\n\nharness が commands をサポートしていて、明示的な `/coasts`\nentrypoint が欲しい場合、簡単な方法の 1 つは、skill を再利用する command を追加することです。\nCommands は名前で明示的に呼び出されるため、\n`/coasts` ワークフローがいつ実行されるかを正確に把握できます。Skills は agent によって\nコンテキストに応じて自動的に読み込まれることもあり、\nこれは便利ですが、その instructions がいつ取り込まれるかについての制御は少なくなります。\n\n両方を使うこともできます。その場合は、ワークフローの別コピーを\n個別に管理するのではなく、command から skill を再利用するようにしてください。\n\nharness が skills のみをサポートしている場合(T3 Code)は、skill を使ってください。どちらもサポートしていない場合(Conductor)は、\n`/coasts` ワークフローをプロジェクトの instructions ファイルに直接記述してください。\n", - "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) は\n`.claude/worktrees/` にあるプロジェクト内で worktree を作成します。そのディレクトリは\nリポジトリ内に存在するため、Coasts は外部の bind mount なしで Claude Code の worktree を\n検出して割り当てることができます。\n\nClaude Code はまた、このドキュメントにおいて Coasts 向けの3つのレイヤーが最も明確に\n分かれているハーネスでもあります:\n\n- Coasts を操作するための短く常時有効なルールには `CLAUDE.md`\n- 再利用可能な `/coasts` ワークフローには `.claude/skills/coasts/SKILL.md`\n- 追加のエントリポイントとしてコマンドファイルを使いたい場合のみ `.claude/commands/coasts.md`\n\n## Setup\n\n`worktree_dir` に `.claude/worktrees` を追加します:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n`.claude/worktrees` はプロジェクト相対であるため、外部 bind mount は\n必要ありません。\n\n## Where Coasts guidance goes\n\n### `CLAUDE.md`\n\nすべてのタスクに適用されるべき Coasts のルールはここに置きます。短く、\n運用的な内容にしてください:\n\n- セッション内で最初のランタイムコマンドを実行する前に `coast lookup` を実行する\n- テスト、ビルド、サービスコマンドには `coast exec` を使う\n- ランタイムのフィードバックには `coast ps` と `coast logs` を使う\n- 一致するものが存在しない場合、Coast の作成または再割り当ての前に確認する\n\n### `.claude/skills/coasts/SKILL.md`\n\n再利用可能な `/coasts` ワークフローはここに置きます。これは次のようなフローに\n適した場所です:\n\n1. `coast lookup` を実行し、一致する Coast を再利用する\n2. 一致するものがない場合は `coast ls` にフォールバックする\n3. `coast run`, `coast assign`, `coast unassign`, `coast checkout`, および\n `coast ui` を提示する\n4. ラップするのではなく、契約として Coast CLI を直接使う\n\nこのリポジトリが Codex、T3 Code、または Cursor も使う場合は、\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) を参照し、正規の skill を\n`.agents/skills/coasts/` に置いてから、それを Claude Code に公開してください。\n\n### `.claude/commands/coasts.md`\n\nClaude Code はプロジェクトコマンドファイルもサポートしています。Coasts のドキュメントでは、\nこれは任意のものとして扱ってください:\n\n- 明確にコマンドファイルが必要な場合にのみ使う\n- 単純な選択肢の1つは、そのコマンドに同じ skill を再利用させること\n- コマンドに独自の別個の指示を持たせる場合、保守すべきワークフローの\n 2つ目のコピーを抱えることになります\n\n## Example layout\n\n### Claude Code only\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\nこのリポジトリが Codex、T3 Code、または Cursor も使う場合は、ここで重複させるのではなく\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) の共有パターンを使ってください。\nプロバイダ固有のガイダンスを重複させると、別のハーネスを追加するたびに同期を保つのが\n難しくなるためです。\n\n## What Coasts does\n\n- **Run** — `coast run ` は最新のビルドから新しい Coast インスタンスを作成します。`coast run -w ` を使うと、Claude Code の worktree を作成して1ステップで割り当てられます。[Run](../concepts_and_terminology/RUN.md) を参照してください。\n- **Discovery** — Coasts は他のローカル worktree ディレクトリと同様に `.claude/worktrees` を読み取ります。\n- **Naming** — Claude Code の worktree は、Coasts UI および CLI において、他のリポジトリ内 worktree と同じローカル worktree 命名動作に従います。\n- **Assign** — `coast assign` は、外部 bind-mount の間接層なしで `/workspace` を Claude Code の worktree に切り替えられます。\n- **Gitignored sync** — worktree はリポジトリツリー内に存在するため、通常どおり動作します。\n- **Orphan detection** — Claude Code が worktree を削除した場合、Coasts は不足している gitdir を検出し、必要に応じてその割り当てを解除できます。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code の worktree\n- `~/.codex/worktrees/` — このリポジトリで Codex も使う場合の Codex worktree\n\n## Limitations\n\n- `/coasts` ワークフローを `CLAUDE.md`、`.claude/skills`、および `.claude/commands` にまたがって重複させると、それらのコピーは乖離していきます。`CLAUDE.md` は短く保ち、再利用可能なワークフローは1つの skill にまとめてください。\n- 1つのリポジトリを複数のハーネスで適切に動作させたい場合は、[Multiple Harnesses](MULTIPLE_HARNESSES.md) の共有パターンを優先してください。\n", - "harnesses/CODEX.md": "# Codex\n\n[Codex](https://developers.openai.com/codex/app/worktrees/) は `$CODEX_HOME/worktrees`(通常は `~/.codex/worktrees`)に worktree を作成します。各 worktree は `~/.codex/worktrees/a0db/project-name` のような不透明なハッシュのディレクトリ配下に存在し、detached HEAD で開始され、Codex の保持ポリシーに基づいて自動的にクリーンアップされます。\n\n[Codex docs](https://developers.openai.com/codex/app/worktrees/) より:\n\n> worktree が作成される場所を制御できますか?\n> 現時点ではできません。Codex は一貫して管理できるように、`$CODEX_HOME/worktrees` 配下に worktree を作成します。\n\nこれらの worktree はプロジェクトルートの外側に存在するため、Coasts がそれらを検出してマウントするには明示的な\n設定が必要です。\n\n## Setup\n\n`worktree_dir` に `~/.codex/worktrees` を追加します:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nCoasts は実行時に `~` を展開し、`~/` または `/` で始まるパスを外部として扱います。詳細は [Worktree Directories](../coastfiles/WORKTREE_DIR.md) を\n参照してください。\n\n`worktree_dir` を変更した後は、バインドマウントを有効にするために既存のインスタンスを**再作成**する必要があります:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree の一覧はすぐに更新されます(Coasts は新しい Coastfile を読み込みます)が、\nCodex worktree への割り当てにはコンテナ内のバインドマウントが必要です。\n\n## Where Coasts guidance goes\n\nCoasts を扱うには、Codex のプロジェクト指示ファイルと共有スキルレイアウトを使用します:\n\n- 短い Coast Runtime ルールは `AGENTS.md` に置く\n- 再利用可能な `/coasts` ワークフローは `.agents/skills/coasts/SKILL.md` に置く\n- Codex はそのスキルを `/coasts` コマンドとして表示する\n- Codex 固有のメタデータを使う場合は、スキルの横の\n `.agents/skills/coasts/agents/openai.yaml` に置く\n- Coasts に関するドキュメントのためだけに別のプロジェクトコマンドファイルを作らないこと。スキルが再利用可能な公開面です\n- このリポジトリが Cursor や Claude Code も使う場合は、正規のスキルを\n `.agents/skills/` に置き、そこから公開します。詳細は\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) と\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md) を参照してください。\n\nたとえば、最小限の `.agents/skills/coasts/agents/openai.yaml` は次のようになります:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\nこれにより、Codex でそのスキルがよりわかりやすいラベルで表示され、`/coasts` が明示的な\nコマンドになります。スキルが MCP\nサーバーやその他の OpenAI 管理のツール配線も必要とする場合にのみ `dependencies.tools` を追加してください。\n\n## What Coasts does\n\n- **Run** -- `coast run ` は最新のビルドから新しい Coast インスタンスを作成します。`coast run -w ` を使うと、Codex worktree の作成と割り当てを 1 ステップで行えます。詳細は [Run](../concepts_and_terminology/RUN.md) を参照してください。\n- **Bind mount** -- コンテナ作成時に、Coasts は\n `~/.codex/worktrees` をコンテナ内の `/host-external-wt/{index}` にマウントします。\n- **Discovery** -- `git worktree list --porcelain` はリポジトリスコープであるため、そのディレクトリに多くのプロジェクトの worktree が含まれていても、現在のプロジェクトに属する Codex worktree のみが表示されます。\n- **Naming** -- Detached HEAD の worktree は外部ディレクトリ内での相対パス(`a0db/my-app`, `eca7/my-app`)として表示されます。ブランチベースの worktree はブランチ名として表示されます。\n- **Assign** -- `coast assign` は外部バインドマウントパスから `/workspace` を再マウントします。\n- **Gitignored sync** -- ホストファイルシステム上で絶対パスを使って実行されるため、バインドマウントなしでも動作します。\n- **Orphan detection** -- git watcher は外部ディレクトリを\n 再帰的にスキャンし、`.git` の gitdir ポインタでフィルタします。Codex が\n worktree を削除した場合、Coasts はインスタンスの割り当てを自動的に解除します。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code(ローカル、特別な処理なし)\n- `~/.codex/worktrees/` -- Codex(外部、バインドマウントされる)\n\n## Limitations\n\n- Codex はいつでも worktree をクリーンアップする可能性があります。Coasts の orphan detection は\n これを適切に処理します。\n", - "harnesses/CONDUCTOR.md": "# Conductor\n\n[Conductor](https://conductor.build/) は、並列の Claude Code エージェントを実行し、それぞれが独自の分離されたワークスペースを持ちます。ワークスペースは `~/conductor/workspaces//` に保存された git worktree です。各ワークスペースは名前付きブランチでチェックアウトされます。\n\nこれらの worktree はプロジェクトルートの外側に存在するため、Coasts がそれらを検出してマウントするには明示的な\n設定が必要です。\n\n## Setup\n\n`~/conductor/workspaces/` を `worktree_dir` に追加します。Codex(すべてのプロジェクトを 1 つのフラットなディレクトリ配下に保存する)とは異なり、Conductor は worktree をプロジェクトごとのサブディレクトリ配下にネストするため、パスにはプロジェクト名を含める必要があります。以下の例では、`my-app` はあなたのリポジトリに対応する `~/conductor/workspaces/` 配下の実際のフォルダ名と一致している必要があります。\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nConductor ではリポジトリごとにワークスペースパスを設定できるため、デフォルトの `~/conductor/workspaces` があなたの設定と一致しない場合があります。実際のパスを確認するには Conductor のリポジトリ設定を確認し、それに応じて調整してください — ディレクトリがどこにあっても原則は同じです。\n\nCoasts は実行時に `~` を展開し、`~/` または `/` で始まるパスを\n外部として扱います。詳細は [Worktree Directories](../coastfiles/WORKTREE_DIR.md) を参照して\nください。\n\n`worktree_dir` を変更した後は、bind mount を有効にするために既存のインスタンスを**再作成**する必要があります。\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree の一覧はすぐに更新されます(Coasts は新しい Coastfile を読み込みます)が、\nConductor worktree への割り当てにはコンテナ内の bind mount が必要です。\n\n## Where Coasts guidance goes\n\nConductor は、Coasts と連携するための独自のハーネスとして扱ってください。\n\n- 短い Coast Runtime のルールは `CLAUDE.md` に置く\n- セットアップや実行時の挙動のうち、実際に Conductor 固有のものは\n Conductor Repository Settings のスクリプトを使う\n- ここでは Claude Code の完全な project command や project skill の挙動を前提にしない\n- コマンドを追加しても表示されない場合は、再テストする前に\n Conductor を完全に閉じてから再度開く\n- このリポジトリが他のハーネスも使っている場合は、\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) と\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md) を参照し、\n 共有の `/coasts` ワークフローを 1 か所に保つ方法を確認してください\n\n## What Coasts does\n\n- **Run** — `coast run ` は最新のビルドから新しい Coast インスタンスを作成します。`coast run -w ` を使うと、Conductor worktree の作成と割り当てを 1 ステップで行えます。詳細は [Run](../concepts_and_terminology/RUN.md) を参照してください。\n- **Bind mount** — コンテナ作成時に、Coasts は\n `~/conductor/workspaces/` をコンテナ内の\n `/host-external-wt/{index}` にマウントします。\n- **Discovery** — `git worktree list --porcelain` はリポジトリスコープであるため、現在のプロジェクトに属する worktree のみが表示されます。\n- **Naming** — Conductor の worktree は名前付きブランチを使用するため、Coasts UI と CLI ではブランチ\n 名で表示されます(例: `scroll-to-bottom-btn`)。1 つのブランチは\n 同時に 1 つの Conductor ワークスペースでしかチェックアウトできません。\n- **Assign** — `coast assign` は `/workspace` を外部 bind mount パスから再マウントします。\n- **Gitignored sync** — ホストファイルシステム上で絶対パスを使って実行されるため、bind mount なしでも動作します。\n- **Orphan detection** — git watcher は外部ディレクトリを\n 再帰的にスキャンし、`.git` の gitdir ポインタでフィルタリングします。Conductor がワークスペースをアーカイブまたは\n 削除した場合、Coasts はインスタンスの割り当てを自動的に解除します。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor(外部、bind-mounted; `my-app` はあなたのリポジトリフォルダ名に置き換えてください)\n\n## Conductor Env Vars\n\n- Coasts 内のランタイム設定で Conductor 固有の環境変数(例:\n `CONDUCTOR_PORT`, `CONDUCTOR_WORKSPACE_PATH`)に依存するのは避けてください。Coasts はポート、ワークスペースパス、サービスディスカバリを\n 独立して管理します — 代わりに Coastfile の `[ports]` と `coast exec` を使用してください。\n", - "harnesses/CURSOR.md": "# Cursor\n\n[Cursor](https://cursor.com/docs/agent/overview) は現在のチェックアウト内で直接作業でき、さらにその Parallel Agents 機能は `~/.cursor/worktrees//` 配下に git\nworktree を作成することもできます。\n\nCoasts に関するドキュメントでは、これは 2 つのセットアップケースがあることを意味します:\n\n- 現在のチェックアウトで Cursor を使うだけであれば、Cursor 固有の\n `worktree_dir` エントリは不要です\n- Cursor Parallel Agents を使う場合は、Coasts がそれらの worktree を検出して割り当てできるように、Cursor の worktree ディレクトリを\n `worktree_dir` に追加してください\n\n## Setup\n\n### Current checkout only\n\nCursor がすでに開いているチェックアウトを編集しているだけであれば、Coasts は\nCursor 固有の特別な worktree パスを必要としません。Coasts はそのチェックアウトを、他の任意のローカルリポジトリルートと同様に扱います。\n\n### Cursor Parallel Agents\n\nParallel Agents を使用する場合は、`~/.cursor/worktrees/` を\n`worktree_dir` に追加してください:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nCursor は各エージェントの worktree を、そのプロジェクトごとのディレクトリ配下に保存します。Coasts は実行時に `~` を展開し、そのパスを外部パスとして扱うため、バインドマウントを有効にするには既存のインスタンスを再作成する必要があります:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nCoastfile の変更後、worktree 一覧は即座に更新されますが、Cursor Parallel Agent の worktree への割り当てには、コンテナ内の外部バインドマウントが必要です。\n\n## Where Coasts guidance goes\n\n### `AGENTS.md` or `.cursor/rules/coast.md`\n\n短く、常時有効な Coast Runtime ルールはここに置いてください:\n\n- 最も移植性の高いプロジェクト指示にしたい場合は `AGENTS.md` を使ってください\n- Cursor ネイティブのプロジェクトルールと設定 UI サポートが必要な場合は `.cursor/rules/coast.md` を使ってください\n- 明確な理由がない限り、同じ Coast Runtime ブロックを両方に重複して置かないでください\n\n### `.cursor/skills/coasts/SKILL.md` or shared `.agents/skills/coasts/SKILL.md`\n\n再利用可能な `/coasts` ワークフローはここに置いてください:\n\n- Cursor 専用のリポジトリであれば、`.cursor/skills/coasts/SKILL.md` は自然な配置先です\n- 複数ハーネス対応のリポジトリであれば、正本となる skill は\n `.agents/skills/coasts/SKILL.md` に置いてください。Cursor はそれを直接読み込めます\n- skill は実際の `/coasts` ワークフロー、すなわち `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout`, および `coast ui` を担当するべきです\n\n### `.cursor/commands/coasts.md`\n\nCursor はプロジェクトコマンドもサポートしています。Coasts に関するドキュメントでは、コマンドはオプションとして扱ってください:\n\n- 明示的な `/coasts` エントリポイントが欲しい場合にのみコマンドを追加してください\n- シンプルな選択肢の 1 つは、そのコマンドで同じ skill を再利用することです\n- コマンドに独自の別個の指示を持たせる場合、保守すべきワークフローのコピーを 2 つ持つことになります\n\n### `.cursor/worktrees.json`\n\n`.cursor/worktrees.json` は、Coasts のポリシーではなく Cursor 自身の worktree ブートストラップのために使ってください:\n\n- 依存関係のインストール\n- `.env` ファイルのコピーまたはシンボリックリンク作成\n- データベースマイグレーションやその他の一度限りのブートストラップ手順の実行\n\nCoast Runtime ルールや Coast CLI ワークフローを\n`.cursor/worktrees.json` に移さないでください。\n\n## Example layout\n\n### Cursor only\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # optional\n.cursor/rules/coast.md # optional alternative to AGENTS.md\n.cursor/worktrees.json # optional, for Parallel Agents bootstrap\n```\n\n### Cursor plus other harnesses\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional\n```\n\n## What Coasts does\n\n- **Run** — `coast run ` は最新のビルドから新しい Coast インスタンスを作成します。`coast run -w ` を使うと、Cursor の worktree を 1 ステップで作成して割り当てできます。[Run](../concepts_and_terminology/RUN.md) を参照してください。\n- **Current checkout** — Cursor が開いたリポジトリ内で直接作業している場合、特別な Cursor 対応は不要です。\n- **Bind mount** — Parallel Agents の場合、Coasts は\n `~/.cursor/worktrees/` をコンテナ内の\n `/host-external-wt/{index}` にマウントします。\n- **Discovery** — `git worktree list --porcelain` は引き続きリポジトリスコープであるため、Coasts は現在のプロジェクトに属する Cursor worktree のみを表示します。\n- **Naming** — Cursor Parallel Agent の worktree は、Coasts の CLI および UI ではブランチ名で表示されます。\n- **Assign** — `coast assign` は、Cursor worktree が選択されると、外部バインドマウントパスから `/workspace` を再マウントします。\n- **Gitignored sync** — 絶対パスを使ってホストファイルシステム上で引き続き動作します。\n- **Orphan detection** — Cursor が古い worktree をクリーンアップした場合、Coasts は不足している gitdir を検出し、必要に応じてそれらの割り当てを解除できます。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code の worktree\n- `~/.codex/worktrees/` — Codex の worktree\n- `~/.cursor/worktrees/my-app/` — Cursor Parallel Agent の worktree\n\n## Limitations\n\n- Cursor Parallel Agents を使っていない場合は、たまたま Cursor で編集しているからという理由だけで\n `~/.cursor/worktrees/` を追加しないでください。\n- Coast Runtime ルールは、常時有効な 1 つの場所、つまり `AGENTS.md` または\n `.cursor/rules/coast.md` に置いてください。両方に重複させると乖離を招きます。\n- 再利用可能な `/coasts` ワークフローは skill に置いてください。`.cursor/worktrees.json` は\n Cursor のブートストラップ用であり、Coasts のポリシー用ではありません。\n- 1 つのリポジトリを Cursor、Codex、Claude Code、または T3 Code で共有する場合は、\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) の共有レイアウトを優先してください。\n", + "harnesses/README.md": "# Harnesses\n\n各 harness は異なる場所に git worktree を作成します。Coasts では、\n[`worktree_dir`](../coastfiles/WORKTREE_DIR.md) 配列によって、どこを探すかを指定します --\nこれには、追加の bind mount を必要とする `~/.codex/worktrees` のような\n外部パスも含まれます。\n\n各 harness には、プロジェクトレベルの instructions、skills、commands について、それぞれ独自の慣習もあります。以下のマトリクスは各 harness が何をサポートしているかを示しており、Coasts のガイダンスをどこに置けばよいかが分かります。各ページでは、Coastfile の設定、推奨されるファイルレイアウト、その harness に固有の注意点を扱います。\n\n1 つのリポジトリを複数の harness から使用する場合は、[Multiple Harnesses](MULTIPLE_HARNESSES.md) を参照してください。\n\n| Harness | Worktree location | Project instructions | Skills | Commands | Page |\n|---------|-------------------|----------------------|--------|----------|------|\n| OpenAI Codex | `~/.codex/worktrees` | `AGENTS.md` | `.agents/skills/` | Skills surface as `/` commands | [Codex](CODEX.md) |\n| Claude Code | `.claude/worktrees` | `CLAUDE.md` | `.claude/skills/` | `.claude/commands/` | [Claude Code](CLAUDE_CODE.md) |\n| Cursor | `~/.cursor/worktrees/` | `AGENTS.md` or `.cursor/rules/` | `.cursor/skills/` or `.agents/skills/` | `.cursor/commands/` | [Cursor](CURSOR.md) |\n| Conductor | `~/conductor/workspaces/` | `CLAUDE.md` | -- | -- | [Conductor](CONDUCTOR.md) |\n| T3 Code | `~/.t3/worktrees/` | `AGENTS.md` | `.agents/skills/` | -- | [T3 Code](T3_CODE.md) |\n| Shep | `~/.shep/repos/*/wt` | `CLAUDE.md` | `.agents/skills/` or `.claude/skills/` | -- | [Shep](SHEP.md) |\n\n## Skills vs Commands\n\nSkills と commands はどちらも、再利用可能な `/coasts` ワークフローを定義できます。使っている harness が何をサポートしているかに応じて、どちらか一方、または両方を使えます。\n\nharness が commands をサポートしていて、明示的な `/coasts`\nentrypoint が欲しい場合、簡単な方法の 1 つは、skill を再利用する command を追加することです。\nCommands は名前で明示的に呼び出されるため、\n`/coasts` ワークフローがいつ実行されるかを正確に把握できます。Skills は agent によって\nコンテキストに応じて自動的に読み込まれることもあり、\nこれは便利ですが、その instructions がいつ取り込まれるかについての制御は少なくなります。\n\n両方を使うこともできます。その場合は、ワークフローの別コピーを\n個別に管理するのではなく、command から skill を再利用するようにしてください。\n\nharness が skills のみをサポートしている場合(T3 Code)は、skill を使ってください。どちらもサポートしていない場合(Conductor)は、\n`/coasts` ワークフローをプロジェクトの instructions ファイルに直接記述してください。\n", + "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n## Quick setup\n\n[Coast CLI](../GETTING_STARTED.md) が必要です。Coasts を自動的にセットアップするには、\nこのプロンプトをエージェントのチャットにコピーしてください:\n\n```prompt-copy\nclaude_code_setup_prompt.txt\n```\n\nCLI から skill の内容を取得することもできます: `coast skills-prompt`。\n\nセットアップ後、**新しい Claude Code セッションを開始してください** — skill と\n`CLAUDE.md` の変更はセッション開始時に読み込まれます。\n\n---\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) は\n`.claude/worktrees/` にあるプロジェクト内で worktree を作成します。そのディレクトリは\nリポジトリ内に存在するため、Coasts は外部の bind mount なしで Claude Code の worktree を\n検出して割り当てることができます。\n\nClaude Code はまた、このドキュメントにおいて Coasts 向けの3つのレイヤーが最も明確に\n分かれているハーネスでもあります:\n\n- Coasts を操作するための短く常時有効なルールには `CLAUDE.md`\n- 再利用可能な `/coasts` ワークフローには `.claude/skills/coasts/SKILL.md`\n- 追加のエントリポイントとしてコマンドファイルを使いたい場合のみ `.claude/commands/coasts.md`\n\n## Setup\n\n`worktree_dir` に `.claude/worktrees` を追加します:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n`.claude/worktrees` はプロジェクト相対であるため、外部 bind mount は\n必要ありません。\n\n## Where Coasts guidance goes\n\n### `CLAUDE.md`\n\nすべてのタスクに適用されるべき Coasts のルールはここに置きます。短く、\n運用的な内容にしてください:\n\n- セッション内で最初のランタイムコマンドを実行する前に `coast lookup` を実行する\n- テスト、ビルド、サービスコマンドには `coast exec` を使う\n- ランタイムのフィードバックには `coast ps` と `coast logs` を使う\n- 一致するものが存在しない場合、Coast の作成または再割り当ての前に確認する\n\n### `.claude/skills/coasts/SKILL.md`\n\n再利用可能な `/coasts` ワークフローはここに置きます。これは次のようなフローに\n適した場所です:\n\n1. `coast lookup` を実行し、一致する Coast を再利用する\n2. 一致するものがない場合は `coast ls` にフォールバックする\n3. `coast run`, `coast assign`, `coast unassign`, `coast checkout`, および\n `coast ui` を提示する\n4. ラップするのではなく、契約として Coast CLI を直接使う\n\nこのリポジトリが Codex、T3 Code、または Cursor も使う場合は、\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) を参照し、正規の skill を\n`.agents/skills/coasts/` に置いてから、それを Claude Code に公開してください。\n\n### `.claude/commands/coasts.md`\n\nClaude Code はプロジェクトコマンドファイルもサポートしています。Coasts のドキュメントでは、\nこれは任意のものとして扱ってください:\n\n- 明確にコマンドファイルが必要な場合にのみ使う\n- 単純な選択肢の1つは、そのコマンドに同じ skill を再利用させること\n- コマンドに独自の別個の指示を持たせる場合、保守すべきワークフローの\n 2つ目のコピーを抱えることになります\n\n## Example layout\n\n### Claude Code only\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\nこのリポジトリが Codex、T3 Code、または Cursor も使う場合は、ここで重複させるのではなく\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) の共有パターンを使ってください。\nプロバイダ固有のガイダンスを重複させると、別のハーネスを追加するたびに同期を保つのが\n難しくなるためです。\n\n## What Coasts does\n\n- **Run** — `coast run ` は最新のビルドから新しい Coast インスタンスを作成します。`coast run -w ` を使うと、Claude Code の worktree を作成して1ステップで割り当てられます。[Run](../concepts_and_terminology/RUN.md) を参照してください。\n- **Discovery** — Coasts は他のローカル worktree ディレクトリと同様に `.claude/worktrees` を読み取ります。\n- **Naming** — Claude Code の worktree は、Coasts UI および CLI において、他のリポジトリ内 worktree と同じローカル worktree 命名動作に従います。\n- **Assign** — `coast assign` は、外部 bind-mount の間接層なしで `/workspace` を Claude Code の worktree に切り替えられます。\n- **Gitignored sync** — worktree はリポジトリツリー内に存在するため、通常どおり動作します。\n- **Orphan detection** — Claude Code が worktree を削除した場合、Coasts は不足している gitdir を検出し、必要に応じてその割り当てを解除できます。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code の worktree\n- `~/.codex/worktrees/` — このリポジトリで Codex も使う場合の Codex worktree\n\n## Limitations\n\n- `/coasts` ワークフローを `CLAUDE.md`、`.claude/skills`、および `.claude/commands` にまたがって重複させると、それらのコピーは乖離していきます。`CLAUDE.md` は短く保ち、再利用可能なワークフローは1つの skill にまとめてください。\n- 1つのリポジトリを複数のハーネスで適切に動作させたい場合は、[Multiple Harnesses](MULTIPLE_HARNESSES.md) の共有パターンを優先してください。\n", + "harnesses/CODEX.md": "# Codex\n\n## Quick setup\n\n[Coast CLI](../GETTING_STARTED.md) が必要です。このプロンプトをエージェントのチャットにコピーすると、Coasts を自動的にセットアップできます:\n\n```prompt-copy\ncodex_setup_prompt.txt\n```\n\nCLI からスキル内容を取得することもできます: `coast skills-prompt`。\n\nセットアップ後、新しいスキルと `AGENTS.md` を有効にするために、**Codex を終了して再度開いてください**。\n\n---\n\n[Codex](https://developers.openai.com/codex/app/worktrees/) は `$CODEX_HOME/worktrees`(通常は `~/.codex/worktrees`)に worktree を作成します。各 worktree は `~/.codex/worktrees/a0db/project-name` のような不透明なハッシュのディレクトリ配下に存在し、detached HEAD で開始され、Codex の保持ポリシーに基づいて自動的にクリーンアップされます。\n\n[Codex docs](https://developers.openai.com/codex/app/worktrees/) より:\n\n> worktree が作成される場所を制御できますか?\n> 現時点ではできません。Codex は一貫して管理できるように、`$CODEX_HOME/worktrees` 配下に worktree を作成します。\n\nこれらの worktree はプロジェクトルートの外側に存在するため、Coasts がそれらを検出してマウントするには明示的な\n設定が必要です。\n\n## Setup\n\n`worktree_dir` に `~/.codex/worktrees` を追加します:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nCoasts は実行時に `~` を展開し、`~/` または `/` で始まるパスを外部として扱います。詳細は [Worktree Directories](../coastfiles/WORKTREE_DIR.md) を\n参照してください。\n\n`worktree_dir` を変更した後は、バインドマウントを有効にするために既存のインスタンスを**再作成**する必要があります:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree の一覧はすぐに更新されます(Coasts は新しい Coastfile を読み込みます)が、\nCodex worktree への割り当てにはコンテナ内のバインドマウントが必要です。\n\n## Where Coasts guidance goes\n\nCoasts を扱うには、Codex のプロジェクト指示ファイルと共有スキルレイアウトを使用します:\n\n- 短い Coast Runtime ルールは `AGENTS.md` に置く\n- 再利用可能な `/coasts` ワークフローは `.agents/skills/coasts/SKILL.md` に置く\n- Codex はそのスキルを `/coasts` コマンドとして表示する\n- Codex 固有のメタデータを使う場合は、スキルの横の\n `.agents/skills/coasts/agents/openai.yaml` に置く\n- Coasts に関するドキュメントのためだけに別のプロジェクトコマンドファイルを作らないこと。スキルが再利用可能な公開面です\n- このリポジトリが Cursor や Claude Code も使う場合は、正規のスキルを\n `.agents/skills/` に置き、そこから公開します。詳細は\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) と\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md) を参照してください。\n\nたとえば、最小限の `.agents/skills/coasts/agents/openai.yaml` は次のようになります:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\nこれにより、Codex でそのスキルがよりわかりやすいラベルで表示され、`/coasts` が明示的な\nコマンドになります。スキルが MCP\nサーバーやその他の OpenAI 管理のツール配線も必要とする場合にのみ `dependencies.tools` を追加してください。\n\n## What Coasts does\n\n- **Run** -- `coast run ` は最新のビルドから新しい Coast インスタンスを作成します。`coast run -w ` を使うと、Codex worktree の作成と割り当てを 1 ステップで行えます。詳細は [Run](../concepts_and_terminology/RUN.md) を参照してください。\n- **Bind mount** -- コンテナ作成時に、Coasts は\n `~/.codex/worktrees` をコンテナ内の `/host-external-wt/{index}` にマウントします。\n- **Discovery** -- `git worktree list --porcelain` はリポジトリスコープであるため、そのディレクトリに多くのプロジェクトの worktree が含まれていても、現在のプロジェクトに属する Codex worktree のみが表示されます。\n- **Naming** -- Detached HEAD の worktree は外部ディレクトリ内での相対パス(`a0db/my-app`, `eca7/my-app`)として表示されます。ブランチベースの worktree はブランチ名として表示されます。\n- **Assign** -- `coast assign` は外部バインドマウントパスから `/workspace` を再マウントします。\n- **Gitignored sync** -- ホストファイルシステム上で絶対パスを使って実行されるため、バインドマウントなしでも動作します。\n- **Orphan detection** -- git watcher は外部ディレクトリを\n 再帰的にスキャンし、`.git` の gitdir ポインタでフィルタします。Codex が\n worktree を削除した場合、Coasts はインスタンスの割り当てを自動的に解除します。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code(ローカル、特別な処理なし)\n- `~/.codex/worktrees/` -- Codex(外部、バインドマウントされる)\n\n## Limitations\n\n- Codex はいつでも worktree をクリーンアップする可能性があります。Coasts の orphan detection は\n これを適切に処理します。\n", + "harnesses/CONDUCTOR.md": "# Conductor\n\n## Quick setup\n\n[Coast CLI](../GETTING_STARTED.md) が必要です。Coasts を自動的にセットアップするには、このプロンプトをエージェントのチャットにコピーしてください:\n\n```prompt-copy\nconductor_setup_prompt.txt\n```\n\nCLI から skill の内容を取得することもできます: `coast skills-prompt`。\n\n> **Important:** Conductor は各セッションを分離された git worktree で実行します。セットアッププロンプトは現在のワークスペースにしか存在しないファイルを作成するため、それらをメインブランチにコミットしてマージしないと、新しいセッションでは利用できません。\n\nセットアップ後、変更を反映するには **Conductor を完全に閉じて再度開いてください**。`/coasts` コマンドが表示されない場合は、もう一度閉じて開き直してください。\n\n## Setup\n\n`~/conductor/workspaces/` を `worktree_dir` に追加します。Codex(すべてのプロジェクトを 1 つのフラットなディレクトリ配下に保存する)とは異なり、Conductor は worktree をプロジェクトごとのサブディレクトリ配下にネストするため、パスにはプロジェクト名を含める必要があります。以下の例では、`my-app` はあなたのリポジトリに対応する `~/conductor/workspaces/` 配下の実際のフォルダ名と一致している必要があります。\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nConductor ではリポジトリごとにワークスペースパスを設定できるため、デフォルトの `~/conductor/workspaces` があなたの設定と一致しない場合があります。実際のパスを確認するには Conductor のリポジトリ設定を確認し、それに応じて調整してください — ディレクトリがどこにあっても原則は同じです。\n\nCoasts は実行時に `~` を展開し、`~/` または `/` で始まるパスを\n外部として扱います。詳細は [Worktree Directories](../coastfiles/WORKTREE_DIR.md) を参照して\nください。\n\n`worktree_dir` を変更した後は、bind mount を有効にするために既存のインスタンスを**再作成**する必要があります。\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree の一覧はすぐに更新されます(Coasts は新しい Coastfile を読み込みます)が、\nConductor worktree への割り当てにはコンテナ内の bind mount が必要です。\n\n## Where Coasts guidance goes\n\nConductor は、Coasts と連携するための独自のハーネスとして扱ってください。\n\n- 短い Coast Runtime のルールは `CLAUDE.md` に置く\n- セットアップや実行時の挙動のうち、実際に Conductor 固有のものは\n Conductor Repository Settings のスクリプトを使う\n- ここでは Claude Code の完全な project command や project skill の挙動を前提にしない\n- コマンドを追加しても表示されない場合は、再テストする前に\n Conductor を完全に閉じてから再度開く\n- このリポジトリが他のハーネスも使っている場合は、\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) と\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md) を参照し、\n 共有の `/coasts` ワークフローを 1 か所に保つ方法を確認してください\n\n## What Coasts does\n\n- **Run** — `coast run ` は最新のビルドから新しい Coast インスタンスを作成します。`coast run -w ` を使うと、Conductor worktree の作成と割り当てを 1 ステップで行えます。詳細は [Run](../concepts_and_terminology/RUN.md) を参照してください。\n- **Bind mount** — コンテナ作成時に、Coasts は\n `~/conductor/workspaces/` をコンテナ内の\n `/host-external-wt/{index}` にマウントします。\n- **Discovery** — `git worktree list --porcelain` はリポジトリスコープであるため、現在のプロジェクトに属する worktree のみが表示されます。\n- **Naming** — Conductor の worktree は名前付きブランチを使用するため、Coasts UI と CLI ではブランチ\n 名で表示されます(例: `scroll-to-bottom-btn`)。1 つのブランチは\n 同時に 1 つの Conductor ワークスペースでしかチェックアウトできません。\n- **Assign** — `coast assign` は `/workspace` を外部 bind mount パスから再マウントします。\n- **Gitignored sync** — ホストファイルシステム上で絶対パスを使って実行されるため、bind mount なしでも動作します。\n- **Orphan detection** — git watcher は外部ディレクトリを\n 再帰的にスキャンし、`.git` の gitdir ポインタでフィルタリングします。Conductor がワークスペースをアーカイブまたは\n 削除した場合、Coasts はインスタンスの割り当てを自動的に解除します。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor(外部、bind-mounted; `my-app` はあなたのリポジトリフォルダ名に置き換えてください)\n\n## Conductor Env Vars\n\n- Coasts 内のランタイム設定で Conductor 固有の環境変数(例:\n `CONDUCTOR_PORT`, `CONDUCTOR_WORKSPACE_PATH`)に依存するのは避けてください。Coasts はポート、ワークスペースパス、サービスディスカバリを\n 独立して管理します — 代わりに Coastfile の `[ports]` と `coast exec` を使用してください。\n", + "harnesses/CURSOR.md": "# Cursor\n\n## Quick setup\n\n[Coast CLI](../GETTING_STARTED.md) が必要です。Coasts を自動的にセットアップするには、このプロンプトをエージェントのチャットにコピーしてください:\n\n```prompt-copy\ncursor_setup_prompt.txt\n```\n\nCLI から skill の内容を取得することもできます: `coast skills-prompt`。\n\nセットアップ後、skill とルールの変更を反映するために、**Cursor を再起動**してください。\n\n---\n\n[Cursor](https://cursor.com/docs/agent/overview) は現在のチェックアウト内で直接作業でき、さらにその Parallel Agents 機能は `~/.cursor/worktrees//` 配下に git\nworktree を作成することもできます。\n\nCoasts に関するドキュメントでは、これは 2 つのセットアップケースがあることを意味します:\n\n- 現在のチェックアウトで Cursor を使うだけであれば、Cursor 固有の\n `worktree_dir` エントリは不要です\n- Cursor Parallel Agents を使う場合は、Coasts がそれらの worktree を検出して割り当てできるように、Cursor の worktree ディレクトリを\n `worktree_dir` に追加してください\n\n## Setup\n\n### Current checkout only\n\nCursor がすでに開いているチェックアウトを編集しているだけであれば、Coasts は\nCursor 固有の特別な worktree パスを必要としません。Coasts はそのチェックアウトを、他の任意のローカルリポジトリルートと同様に扱います。\n\n### Cursor Parallel Agents\n\nParallel Agents を使用する場合は、`~/.cursor/worktrees/` を\n`worktree_dir` に追加してください:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nCursor は各エージェントの worktree を、そのプロジェクトごとのディレクトリ配下に保存します。Coasts は実行時に `~` を展開し、そのパスを外部パスとして扱うため、バインドマウントを有効にするには既存のインスタンスを再作成する必要があります:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nCoastfile の変更後、worktree 一覧は即座に更新されますが、Cursor Parallel Agent の worktree への割り当てには、コンテナ内の外部バインドマウントが必要です。\n\n## Where Coasts guidance goes\n\n### `AGENTS.md` or `.cursor/rules/coast.md`\n\n短く、常時有効な Coast Runtime ルールはここに置いてください:\n\n- 最も移植性の高いプロジェクト指示にしたい場合は `AGENTS.md` を使ってください\n- Cursor ネイティブのプロジェクトルールと設定 UI サポートが必要な場合は `.cursor/rules/coast.md` を使ってください\n- 明確な理由がない限り、同じ Coast Runtime ブロックを両方に重複して置かないでください\n\n### `.cursor/skills/coasts/SKILL.md` or shared `.agents/skills/coasts/SKILL.md`\n\n再利用可能な `/coasts` ワークフローはここに置いてください:\n\n- Cursor 専用のリポジトリであれば、`.cursor/skills/coasts/SKILL.md` は自然な配置先です\n- 複数ハーネス対応のリポジトリであれば、正本となる skill は\n `.agents/skills/coasts/SKILL.md` に置いてください。Cursor はそれを直接読み込めます\n- skill は実際の `/coasts` ワークフロー、すなわち `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout`, および `coast ui` を担当するべきです\n\n### `.cursor/commands/coasts.md`\n\nCursor はプロジェクトコマンドもサポートしています。Coasts に関するドキュメントでは、コマンドはオプションとして扱ってください:\n\n- 明示的な `/coasts` エントリポイントが欲しい場合にのみコマンドを追加してください\n- シンプルな選択肢の 1 つは、そのコマンドで同じ skill を再利用することです\n- コマンドに独自の別個の指示を持たせる場合、保守すべきワークフローのコピーを 2 つ持つことになります\n\n### `.cursor/worktrees.json`\n\n`.cursor/worktrees.json` は、Coasts のポリシーではなく Cursor 自身の worktree ブートストラップのために使ってください:\n\n- 依存関係のインストール\n- `.env` ファイルのコピーまたはシンボリックリンク作成\n- データベースマイグレーションやその他の一度限りのブートストラップ手順の実行\n\nCoast Runtime ルールや Coast CLI ワークフローを\n`.cursor/worktrees.json` に移さないでください。\n\n## Example layout\n\n### Cursor only\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # optional\n.cursor/rules/coast.md # optional alternative to AGENTS.md\n.cursor/worktrees.json # optional, for Parallel Agents bootstrap\n```\n\n### Cursor plus other harnesses\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional\n```\n\n## What Coasts does\n\n- **Run** — `coast run ` は最新のビルドから新しい Coast インスタンスを作成します。`coast run -w ` を使うと、Cursor の worktree を 1 ステップで作成して割り当てできます。[Run](../concepts_and_terminology/RUN.md) を参照してください。\n- **Current checkout** — Cursor が開いたリポジトリ内で直接作業している場合、特別な Cursor 対応は不要です。\n- **Bind mount** — Parallel Agents の場合、Coasts は\n `~/.cursor/worktrees/` をコンテナ内の\n `/host-external-wt/{index}` にマウントします。\n- **Discovery** — `git worktree list --porcelain` は引き続きリポジトリスコープであるため、Coasts は現在のプロジェクトに属する Cursor worktree のみを表示します。\n- **Naming** — Cursor Parallel Agent の worktree は、Coasts の CLI および UI ではブランチ名で表示されます。\n- **Assign** — `coast assign` は、Cursor worktree が選択されると、外部バインドマウントパスから `/workspace` を再マウントします。\n- **Gitignored sync** — 絶対パスを使ってホストファイルシステム上で引き続き動作します。\n- **Orphan detection** — Cursor が古い worktree をクリーンアップした場合、Coasts は不足している gitdir を検出し、必要に応じてそれらの割り当てを解除できます。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code の worktree\n- `~/.codex/worktrees/` — Codex の worktree\n- `~/.cursor/worktrees/my-app/` — Cursor Parallel Agent の worktree\n\n## Limitations\n\n- Cursor Parallel Agents を使っていない場合は、たまたま Cursor で編集しているからという理由だけで\n `~/.cursor/worktrees/` を追加しないでください。\n- Coast Runtime ルールは、常時有効な 1 つの場所、つまり `AGENTS.md` または\n `.cursor/rules/coast.md` に置いてください。両方に重複させると乖離を招きます。\n- 再利用可能な `/coasts` ワークフローは skill に置いてください。`.cursor/worktrees.json` は\n Cursor のブートストラップ用であり、Coasts のポリシー用ではありません。\n- 1 つのリポジトリを Cursor、Codex、Claude Code、または T3 Code で共有する場合は、\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) の共有レイアウトを優先してください。\n", "harnesses/MULTIPLE_HARNESSES.md": "# 複数のハーネス\n\n1 つのリポジトリが複数のハーネスから使われる場合、Coasts のセットアップを統合する 1 つの方法は、\n共有の `/coasts` ワークフローを 1 か所に置き、ハーネス固有の常時有効ルールは各ハーネス用の\nファイルに保持することです。\n\n## 推奨レイアウト\n\n```text\nAGENTS.md\nCLAUDE.md\n.cursor/rules/coast.md # optional Cursor-native always-on rules\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional, thin, harness-specific\n.claude/commands/coasts.md # optional, thin, harness-specific\n```\n\nこのレイアウトは次のように使います:\n\n- `AGENTS.md` — Codex と T3\n Code で Coasts を扱うための短い常時有効ルール\n- `.cursor/rules/coast.md` — オプションの Cursor ネイティブな常時有効ルール\n- `CLAUDE.md` — Claude Code\n と Conductor で Coasts を扱うための短い常時有効ルール\n- `.agents/skills/coasts/SKILL.md` — 正式な再利用可能 `/coasts` ワークフロー\n- `.agents/skills/coasts/agents/openai.yaml` — オプションの Codex/OpenAI メタデータ\n- `.claude/skills/coasts` — Claude Code\n でも同じスキルが必要な場合の、Claude 向けのミラーまたはシンボリックリンク\n- `.cursor/commands/coasts.md` — オプションの Cursor コマンドファイル。単純な\n 選択肢の 1 つは、これに同じスキルを再利用させることです\n- `.claude/commands/coasts.md` — オプションの明示的なコマンドファイル。単純な\n 選択肢の 1 つは、これに同じスキルを再利用させることです\n\n## 手順\n\n1. Coast Runtime ルールを常時有効の指示ファイルに入れます。\n - `AGENTS.md`、`CLAUDE.md`、または `.cursor/rules/coast.md` は、\n 「すべてのタスク」でのルールに答えるべきです: まず `coast lookup` を実行する、\n `coast exec` を使う、`coast logs` でログを読む、一致がない場合は\n `coast assign` または `coast run` の前に確認する。\n2. Coasts 用の正式な単一スキルを 1 つ作成します。\n - 再利用可能な `/coasts` ワークフローを `.agents/skills/coasts/SKILL.md` に置きます。\n - そのスキルの中で Coast CLI を直接使います: `coast lookup`、\n `coast ls`、`coast run`、`coast assign`、`coast unassign`、\n `coast checkout`、および `coast ui`。\n3. ハーネスが別のパスを必要とする場所にだけ、そのスキルを公開します。\n - Codex、T3 Code、Cursor はすべて `.agents/skills/` を直接使えます。\n - Claude Code には `.claude/skills/` が必要なので、正式な\n スキルをその場所にミラーするかシンボリックリンクします。\n4. 明示的な `/coasts` エントリポイントが欲しい場合にのみ、コマンドファイルを追加します。\n - `.claude/commands/coasts.md` または\n `.cursor/commands/coasts.md` を作成する場合、単純な選択肢の 1 つは、そのコマンドに\n 同じスキルを再利用させることです。\n - コマンドに独自の別個の指示を与える場合、保守すべきワークフローの\n 2 つ目のコピーを持つことになります。\n5. Conductor 固有のセットアップは、スキルではなく Conductor に保持します。\n - Conductor 自体に属するブートストラップや実行動作には、\n Conductor Repository Settings スクリプトを使います。\n - Coasts のポリシーと `coast` CLI の使用は、`CLAUDE.md` と\n 共有スキルに保持します。\n\n## 具体的な `/coasts` の例\n\n良い共有 `coasts` スキルは、次の 3 つの仕事を行うべきです:\n\n1. `Use Existing Coast`\n - `coast lookup` を実行する\n - 一致が存在する場合は、`coast exec`、`coast ps`、および `coast logs` を使う\n2. `Manage Assignment`\n - `coast ls` を実行する\n - `coast run`、`coast assign`、`coast unassign`、または\n `coast checkout` を提示する\n - 既存のスロットを再利用したり妨げたりする前に確認する\n3. `Open UI`\n - `coast ui` を実行する\n\nこれが `/coasts` ワークフローにとって正しい場所です。常時有効ファイルには、\nスキルが一度も呼び出されない場合でも適用されなければならない短いルールだけを\n保持するべきです。\n\n## シンボリックリンクのパターン\n\nClaude Code に Codex、T3 Code、または Cursor と同じスキルを再利用させたい場合、\n1 つの選択肢はシンボリックリンクです:\n\n```bash\nmkdir -p .claude/skills\nln -s ../../.agents/skills/coasts .claude/skills/coasts\n```\n\nチームがシンボリックリンクを使いたくない場合は、リポジトリにチェックインされた\nミラーでも問題ありません。主な目標は、コピー間の不要な乖離を避けることです。\n\n## ハーネス固有の注意点\n\n- Claude Code: プロジェクトスキルとオプションのプロジェクトコマンドはどちらも有効ですが、\n ロジックはスキル内に保持してください。\n- Cursor: 短い Coast\n Runtime ルールには `AGENTS.md` または `.cursor/rules/coast.md` を使い、再利用可能なワークフローにはスキルを使い、\n `.cursor/commands` はオプションのままにしてください。\n- Conductor: まず `CLAUDE.md` と Conductor スクリプトおよび設定として扱ってください。\n コマンドを追加しても表示されない場合は、再確認する前にアプリを完全に閉じてから開き直してください。\n- T3 Code: これはここで最も薄いハーネスの表面です。Codex スタイルの\n `AGENTS.md` と `.agents/skills` パターンを使い、Coasts に関するドキュメントのために\n 別個の T3 固有コマンドレイアウトを作らないでください。\n- Codex: `AGENTS.md` は短く保ち、再利用可能なワークフローは\n `.agents/skills` に置いてください。\n", - "harnesses/T3_CODE.md": "# T3 Code\n\n[T3 Code](https://github.com/pingdotgg/t3code) は `~/.t3/worktrees//` に git worktree を作成し、名前付きブランチにチェックアウトします。\n\nT3 Code では、常時有効な Coast Runtime ルールを `AGENTS.md` に置き、再利用可能な `/coasts` ワークフローを `.agents/skills/coasts/SKILL.md` に置きます。\n\nこれらの worktree はプロジェクトルートの外に存在するため、Coasts がそれらを検出してマウントするには明示的な設定が必要です。\n\n## Setup\n\n`~/.t3/worktrees/` を `worktree_dir` に追加します。T3 Code は worktree をプロジェクトごとのサブディレクトリ配下にネストするため、パスにはプロジェクト名を含める必要があります。以下の例では、`my-app` はあなたのリポジトリに対する `~/.t3/worktrees/` 配下の実際のフォルダ名と一致している必要があります。\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nCoasts は実行時に `~` を展開し、`~/` または `/` で始まる任意のパスを外部として扱います。詳細は [Worktree Directories](../coastfiles/WORKTREE_DIR.md) を参照してください。\n\n`worktree_dir` を変更した後、バインドマウントを有効にするには既存のインスタンスを**再作成**する必要があります。\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree の一覧は即座に更新されます(Coasts は新しい Coastfile を読み取ります)が、T3 Code の worktree への割り当てにはコンテナ内のバインドマウントが必要です。\n\n## Where Coasts guidance goes\n\nT3 Code では次のレイアウトを使用してください。\n\n- 短い Coast Runtime ルールは `AGENTS.md` に置く\n- 再利用可能な `/coasts` ワークフローは `.agents/skills/coasts/SKILL.md` に置く\n- Coasts 用に T3 固有の別個のプロジェクトコマンドまたはスラッシュコマンド層を追加しない\n- このリポジトリが複数のハーネスを使用している場合は、\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) と\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md) を参照してください。\n\n## What Coasts does\n\n- **Run** — `coast run ` は最新のビルドから新しい Coast インスタンスを作成します。`coast run -w ` を使うと、T3 Code の worktree を作成して 1 ステップで割り当てられます。詳細は [Run](../concepts_and_terminology/RUN.md) を参照してください。\n- **Bind mount** — コンテナ作成時に、Coasts は\n `~/.t3/worktrees/` をコンテナ内の\n `/host-external-wt/{index}` にマウントします。\n- **Discovery** — `git worktree list --porcelain` はリポジトリスコープであるため、現在のプロジェクトに属する worktree のみが表示されます。\n- **Naming** — T3 Code の worktree は名前付きブランチを使用するため、Coasts の UI と CLI ではブランチ名で表示されます。\n- **Assign** — `coast assign` は `/workspace` を外部バインドマウントパスから再マウントします。\n- **Gitignored sync** — ホストファイルシステム上で絶対パスを使って実行され、バインドマウントなしで動作します。\n- **Orphan detection** — git watcher は外部ディレクトリを再帰的にスキャンし、`.git` の gitdir ポインタでフィルタリングします。T3 Code がワークスペースを削除した場合、Coasts はインスタンスの割り当てを自動的に解除します。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code(ローカル、特別な処理なし)\n- `~/.codex/worktrees/` — Codex(外部、バインドマウントされる)\n- `~/.t3/worktrees/my-app/` — T3 Code(外部、バインドマウントされる。`my-app` はあなたのリポジトリフォルダ名に置き換えてください)\n\n## Limitations\n\n- Coasts 内のランタイム設定に T3 Code 固有の環境変数へ依存することは避けてください。Coasts はポート、ワークスペースパス、サービスディスカバリを独立して管理します — 代わりに Coastfile の `[ports]` と `coast exec` を使用してください。\n", + "harnesses/SHEP.md": "# Shep\n\n## クイックセットアップ\n\n[Coast CLI](../GETTING_STARTED.md) が必要です。Coasts を自動的にセットアップするには、このプロンプトを\nエージェントのチャットにコピーしてください:\n\n```prompt-copy\nshep_setup_prompt.txt\n```\n\nCLI からスキルの内容を取得することもできます: `coast skills-prompt`。\n\nセットアップ後、新しいスキルとプロジェクト\n命令を有効にするために、**エディタを終了して再度開いてください**。\n\n---\n\n[Shep](https://shep-ai.github.io/cli/) は `~/.shep/repos/{hash}/wt/{branch-slug}` に worktree を作成します。ハッシュはリポジトリの絶対パスの SHA-256 の先頭 16 桁の 16 進文字であるため、リポジトリごとに決定的ですが中身はわかりにくくなっています。特定のリポジトリのすべての worktree は同じハッシュを共有し、`wt/{branch-slug}` サブディレクトリによって区別されます。\n\nShep CLI からは、`shep feat show ` で worktree パスが表示されます。あるいは、\n`ls ~/.shep/repos` でリポジトリごとのハッシュディレクトリを一覧表示できます。\n\nハッシュはリポジトリごとに異なるため、Coasts はユーザーがハッシュをハードコードしなくても\nshep worktree を検出できるように **glob パターン** を使用します。\n\n## セットアップ\n\n`worktree_dir` に `~/.shep/repos/*/wt` を追加します:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n`*` はリポジトリごとのハッシュディレクトリに一致します。実行時に Coasts は glob を展開し、\n一致するディレクトリ(例: `~/.shep/repos/a21f0cda9ab9d456/wt`)を見つけて、\nそれをコンテナに bind mount します。glob\nパターンの詳細については、\n[Worktree Directories](../coastfiles/WORKTREE_DIR.md) を参照してください。\n\n`worktree_dir` を変更した後は、bind mount を有効にするために既存のインスタンスを **再作成** する必要があります:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree の一覧はすぐに更新されます(Coasts は新しい Coastfile を読み取るため)が、\nShep worktree への割り当てにはコンテナ内の bind mount が必要です。\n\n## Coasts のガイダンスの配置先\n\nShep は内部で Claude Code をラップしているため、Claude Code の慣習に従ってください:\n\n- 短い Coast Runtime ルールは `CLAUDE.md` に置く\n- 再利用可能な `/coasts` ワークフローは `.claude/skills/coasts/SKILL.md` または\n 共通の `.agents/skills/coasts/SKILL.md` に置く\n- このリポジトリが他の harness も使用している場合は、\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) および\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md) を参照してください\n\n## Coasts が行うこと\n\n- **実行** -- `coast run ` は最新のビルドから新しい Coast インスタンスを作成します。`coast run -w ` を使用すると、Shep worktree の作成と割り当てを 1 ステップで行えます。[Run](../concepts_and_terminology/RUN.md) を参照してください。\n- **Bind mount** -- コンテナ作成時に、Coasts は glob\n `~/.shep/repos/*/wt` を解決し、一致する各ディレクトリをコンテナ内の\n `/host-external-wt/{index}` にマウントします。\n- **検出** -- `git worktree list --porcelain` はリポジトリスコープであるため、\n 現在のプロジェクトに属する worktree のみが表示されます。\n- **命名** -- Shep worktree は名前付きブランチを使用するため、Coasts UI および CLI では\n ブランチ名で表示されます(例: `feat-green-background`)。\n- **割り当て** -- `coast assign` は外部 bind mount パスから `/workspace` を再マウントします。\n- **Gitignore されたファイルの同期** -- ホストファイルシステム上で絶対パスを使って実行されるため、bind mount なしで動作します。\n- **孤立検出** -- git watcher は外部ディレクトリを\n 再帰的にスキャンし、`.git` gitdir ポインタでフィルタリングします。Shep が\n worktree を削除すると、Coasts はインスタンスの割り当てを自動的に解除します。\n\n## 例\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/.shep/repos/*/wt` -- Shep(外部、glob 展開によって bind mount)\n\n## Shep パス構造\n\n```\n~/.shep/repos/\n {sha256-of-repo-path-first-16-chars}/\n wt/\n {branch-slug}/ <-- git worktree\n {branch-slug}/\n```\n\n重要なポイント:\n- 同じリポジトリ = 毎回同じハッシュ(決定的であり、ランダムではない)\n- 異なるリポジトリ = 異なるハッシュ\n- パス区切り文字はハッシュ化の前に `/` に正規化される\n- ハッシュは `shep feat show ` または `ls ~/.shep/repos` で確認できる\n", + "harnesses/T3_CODE.md": "# T3 Code\n\n## Quick setup\n\n[Coast CLI](../GETTING_STARTED.md) が必要です。Coasts を自動的にセットアップするには、このプロンプトをエージェントのチャットにコピーしてください。\n\n```prompt-copy\nt3_code_setup_prompt.txt\n```\n\nCLI からスキル内容を取得することもできます: `coast skills-prompt`。\n\nセットアップ後、スキルとルールの変更を反映するには **T3 Code を再起動** してください。\n\n**Note:** T3 Code はまだ `.agents/skills/` または `.claude/skills/` からプロジェクトレベルのスキルを読み込めない場合があります。セットアッププロンプトはスキルを `~/.codex/skills/coasts/` にも配置するため、Codex プロバイダでグローバルに利用できます。`AGENTS.md` と `CLAUDE.md` の Coast Runtime ルールは、いずれの場合もすべてのタスクに適用されます。\n\n---\n\n[T3 Code](https://github.com/pingdotgg/t3code) は `~/.t3/worktrees//` に git worktree を作成し、名前付きブランチにチェックアウトします。\n\nT3 Code は Codex をラップしているため、常時有効なルールには `AGENTS.md` を使用し、再利用可能な `/coasts` ワークフローには `.agents/skills/coasts/SKILL.md` を使用します。\n\nこれらの worktree はプロジェクトルートの外に存在するため、Coasts がそれらを検出してマウントするには明示的な設定が必要です。\n\n## Setup\n\n`~/.t3/worktrees/` を `worktree_dir` に追加します。T3 Code は worktree をプロジェクトごとのサブディレクトリ配下にネストするため、パスにはプロジェクト名を含める必要があります。以下の例では、`my-app` はあなたのリポジトリに対する `~/.t3/worktrees/` 配下の実際のフォルダ名と一致している必要があります。\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nCoasts は実行時に `~` を展開し、`~/` または `/` で始まる任意のパスを外部として扱います。詳細は [Worktree Directories](../coastfiles/WORKTREE_DIR.md) を参照してください。\n\n`worktree_dir` を変更した後、バインドマウントを有効にするには既存のインスタンスを**再作成**する必要があります。\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree の一覧は即座に更新されます(Coasts は新しい Coastfile を読み取ります)が、T3 Code の worktree への割り当てにはコンテナ内のバインドマウントが必要です。\n\n## Where Coasts guidance goes\n\nT3 Code では次のレイアウトを使用してください。\n\n- 短い Coast Runtime ルールは `AGENTS.md` に置く\n- 再利用可能な `/coasts` ワークフローは `.agents/skills/coasts/SKILL.md` に置く\n- Coasts 用に T3 固有の別個のプロジェクトコマンドまたはスラッシュコマンド層を追加しない\n- このリポジトリが複数のハーネスを使用している場合は、\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) と\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md) を参照してください。\n\n## What Coasts does\n\n- **Run** — `coast run ` は最新のビルドから新しい Coast インスタンスを作成します。`coast run -w ` を使うと、T3 Code の worktree を作成して 1 ステップで割り当てられます。詳細は [Run](../concepts_and_terminology/RUN.md) を参照してください。\n- **Bind mount** — コンテナ作成時に、Coasts は\n `~/.t3/worktrees/` をコンテナ内の\n `/host-external-wt/{index}` にマウントします。\n- **Discovery** — `git worktree list --porcelain` はリポジトリスコープであるため、現在のプロジェクトに属する worktree のみが表示されます。\n- **Naming** — T3 Code の worktree は名前付きブランチを使用するため、Coasts の UI と CLI ではブランチ名で表示されます。\n- **Assign** — `coast assign` は `/workspace` を外部バインドマウントパスから再マウントします。\n- **Gitignored sync** — ホストファイルシステム上で絶対パスを使って実行され、バインドマウントなしで動作します。\n- **Orphan detection** — git watcher は外部ディレクトリを再帰的にスキャンし、`.git` の gitdir ポインタでフィルタリングします。T3 Code がワークスペースを削除した場合、Coasts はインスタンスの割り当てを自動的に解除します。\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code(ローカル、特別な処理なし)\n- `~/.codex/worktrees/` — Codex(外部、バインドマウントされる)\n- `~/.t3/worktrees/my-app/` — T3 Code(外部、バインドマウントされる。`my-app` はあなたのリポジトリフォルダ名に置き換えてください)\n\n## Limitations\n\n- Coasts 内のランタイム設定に T3 Code 固有の環境変数へ依存することは避けてください。Coasts はポート、ワークスペースパス、サービスディスカバリを独立して管理します — 代わりに Coastfile の `[ports]` と `coast exec` を使用してください。\n", + "harnesses/claude_code_setup_prompt.txt": "このプロジェクトで Claude Code 用の Coasts スキルをセットアップしています。すべての\nコマンドはプロジェクトルートから実行してください。\n\n## Step 1: Coast CLI を確認する\n\n次のコマンドを実行します:\n\n coast --version\n\n`coast` コマンドが見つからない場合は、ここで停止してユーザーに次のように伝えてください:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nCLI が利用可能になるまで続行しないでください。\n\n## Step 2: スキル内容を取得する\n\n次のコマンドを実行します:\n\n coast skills-prompt\n\n出力には 2 つの部分があります:\n\n- **Coast Runtime rules** — 先頭から `---` で始まる行の直前までのすべて\n- **Coasts skill** — `---` のフロントマターブロック以降のすべて(`---` の行とその後のすべてを含む)\n\n以下の手順のために、両方の部分を保存してください。\n\n## Step 3: ユーザーに確認する\n\nユーザーに尋ねてください: これを **グローバルに**(このマシン上のすべてのプロジェクトで利用可能)設定しますか、それとも **このプロジェクトのみ** に設定しますか?\n\n## Step 4: ファイルを配置する\n\n対象ファイルがすでに存在する場合は、上書きするのではなく Coast Runtime セクションを追記してください。ただし、最初に `# Coast Runtime` セクションがすでに存在するか確認し、存在する場合はスキップしてください。\n\n**Global setup:**\n- Coast Runtime rules を `~/.claude/CLAUDE.md` に追記する\n- Coasts skill を `~/.claude/skills/coasts/SKILL.md` に書き込む\n\n**Project setup:**\n- Coast Runtime rules をプロジェクトルートの `CLAUDE.md` に追記する\n- Coasts skill を `.claude/skills/coasts/SKILL.md` に書き込む\n\n## Step 5: Coastfile を更新する\n\nプロジェクトルートの `Coastfile` を読み取ってください。`[coast]` セクション内の\n`worktree_dir` フィールドを確認します。\n\n`.claude/worktrees` がまだ `worktree_dir` に含まれて**いない**場合:\n\n- `worktree_dir` が単一の文字列であれば、配列に変換して\n `.claude/worktrees` を追加します。たとえば、`worktree_dir = \".worktrees\"` は\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]` になります。\n- `worktree_dir` がすでに配列であれば、`.claude/worktrees` をそれに追加します。\n- `worktree_dir` がまったく存在しない場合は、\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]` を追加します。\n\nこれは相対パス(プロジェクトルート内)なので、コンテナの再作成は\n不要です — 変更は worktree の一覧表示に即時反映されます。\n\n## Step 6: 確認する\n\nファイルを配置した後、何が作成され、どこに作成されたかの要約をユーザーに示してください。\n\nユーザーに伝えてください: スキルと CLAUDE.md の\n変更を反映させるには、**新しい Claude Code セッションを開始してください**。\n", + "harnesses/codex_setup_prompt.txt": "このプロジェクトで OpenAI Codex 向けの Coasts スキルを設定しています。すべての\nコマンドはプロジェクトルートから実行してください。\n\n## Step 1: Coast CLI を確認する\n\n次のコマンドを実行してください:\n\n coast --version\n\n`coast` コマンドが見つからない場合は、ここで停止し、ユーザーに次のように伝えてください:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nCLI が利用可能になるまで続行しないでください。\n\n## Step 2: スキルの内容を取得する\n\n次のコマンドを実行してください:\n\n coast skills-prompt\n\n出力には 2 つの部分があります:\n\n- **Coast Runtime rules** — 先頭から `---` で始まる行の直前までのすべて\n- **Coasts skill** — `---` の frontmatter ブロック以降のすべて(`---` の行とそれ以降のすべてを含む)\n\n以下の手順のために、両方の部分を保存してください。\n\n## Step 3: ファイルを配置する\n\nCodex の設定は常にプロジェクトレベルです。対象ファイルがすでに存在する場合は、上書きするのではなく Coast Runtime セクションを追記してください。ただし、まず `# Coast Runtime` セクションがすでに存在するか確認し、存在する場合はスキップしてください。\n\n- プロジェクトルートの `AGENTS.md` に Coast Runtime rules を追記する\n- Coasts skill を `.agents/skills/coasts/SKILL.md` に書き込む\n- 次の内容で `.agents/skills/coasts/agents/openai.yaml` を作成する:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## Step 4: Coastfile を更新する\n\nプロジェクトルートにある `Coastfile` を読んでください。`[coast]` セクションの\n`worktree_dir` フィールドを確認します。\n\n`~/.codex/worktrees` が `worktree_dir` に**まだ**含まれていない場合:\n\n- `worktree_dir` が単一の文字列である場合は、配列に変換して\n `~/.codex/worktrees` を追加してください。たとえば、`worktree_dir = \".worktrees\"` は\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]` になります。\n- `worktree_dir` がすでに配列である場合は、そこに `~/.codex/worktrees` を追加してください。\n- `worktree_dir` がまったく存在しない場合は、\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]` を追加してください。\n\nこれは外部パスであるため、このプロジェクトですでに Coast インスタンスが実行中の場合、\n新しいバインドマウントを有効にするには `coast run` で再作成する必要があります。\nこのことをユーザーに伝えてください。\n\n## Step 5: 確認\n\nファイルを配置した後、何がどこに作成されたかの要約をユーザーに示してください。\n\nスキルと AGENTS.md の変更を有効にするには、**Codex を終了して再度開く**よう\nユーザーに伝えてください。\n", + "harnesses/conductor_setup_prompt.txt": "このプロジェクトで Conductor 用の Coasts スキルをセットアップします。すべての\nコマンドはプロジェクトルートから実行してください。\n\n## Step 1: Coast CLI の確認\n\nこのコマンドを実行します:\n\n coast --version\n\n`coast` コマンドが見つからない場合は、ここで停止し、ユーザーに次のように伝えてください:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nCLI が利用可能になるまで続行しないでください。\n\n## Step 2: スキル内容の取得\n\nこのコマンドを実行します:\n\n coast skills-prompt\n\n出力には 2 つの部分があります:\n\n- **Coast Runtime ルール** — 先頭から、`---` で始まる行の直前までのすべて\n- **Coasts スキル** — `---` の frontmatter ブロック以降のすべて(`---` の行およびその後のすべてを含む)\n\n以下の手順のために、両方の部分を保存してください。\n\n## Step 3: ユーザーに確認\n\nユーザーに質問してください: Conductor ではどのプロバイダーを使っていますか?\n\n- **Claude** (Anthropic)\n- **Codex** (OpenAI)\n- **Both**\n- **Other** — ユーザーが別のプロバイダー名を挙げた場合は、\n `coast docs --path SKILLS_FOR_HOST_AGENTS.md` および\n `coast docs --path harnesses/README.md` を実行して、そのプロバイダーが\n プロジェクト指示とスキルをどこに置くことを期待しているかを確認し、その後は同じパターンに従ってください\n\n## Step 4: ファイルの配置\n\nConductor のセットアップは常にプロジェクトレベルです。対象ファイルがすでに存在する場合は、上書きするのではなく\nCoast Runtime セクションを追記してください。ただし最初に\n`# Coast Runtime` セクションがすでに存在するか確認し、存在する場合はスキップしてください。\n\n**ユーザーが Claude(または両方)を選択した場合:**\n- プロジェクトルートの `CLAUDE.md` に Coast Runtime ルールを追記\n- Coasts スキルを `.claude/skills/coasts/SKILL.md` に書き込む\n\n**ユーザーが Codex(または両方)を選択した場合:**\n- プロジェクトルートの `AGENTS.md` に Coast Runtime ルールを追記\n- Coasts スキルを `.agents/skills/coasts/SKILL.md` に書き込む\n- `.agents/skills/coasts/agents/openai.yaml` を次の内容で作成する:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## Step 5: 確認\n\nファイルを配置した後、何が作成され、どこに配置されたかの要約をユーザーに表示してください。\n\n変更を反映させるために、ユーザーに次のように伝えてください: **Conductor を完全に閉じてから再度開いてください**。\n`/coasts` コマンドがすぐに表示されない場合は、もう一度閉じて再度開いてください。\n\n## Step 6: Coastfile の更新\n\nプロジェクトルートにある `Coastfile` を読んでください。`[coast]` セクション内の\n`worktree_dir` フィールドを確認します。また、worktree パスの構築に必要なので\n`name` フィールドも読んでください。\n\nConductor の worktree ディレクトリは `~/conductor/workspaces/` です。ここで\n`` は Coastfile の `name` フィールドの値です。\n\nそのパスがまだ `worktree_dir` に記載されて**いない**場合:\n\n- `worktree_dir` が単一の文字列であれば、配列に変換して\n Conductor のパスを追加します。たとえば、`worktree_dir = \".worktrees\"` は\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]` になります。\n- `worktree_dir` がすでに配列であれば、そこに Conductor のパスを追加します。\n- `worktree_dir` がまったく存在しない場合は、\n 実際のプロジェクト名を使って\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/\"]` を追加します。\n\nこれは外部パスであるため、このプロジェクト用の Coast インスタンスがすでに実行中の場合は、\n新しいバインドマウントを有効にするために `coast run` で再作成する必要があります。\nこのことをユーザーに伝えてください。\n\n## Step 7: 新しいファイルをコミット\n\nConductor は各セッションを分離された git worktree で実行します。コミットされていないファイルは\n新しいセッションに引き継がれません。今作成したファイルをコミットして、今後のすべてのワークスペースで\n利用できるようにしてください:\n\n git add CLAUDE.md .claude/ AGENTS.md .agents/ 2>/dev/null; git status\n\nどのファイルがステージされているかをユーザーに表示し、コミット前に確認を求めてください。\nコミットメッセージには `[dh] feat: add Coasts skill for Conductor` のようなものを使用してください。\n", + "harnesses/cursor_setup_prompt.txt": "このプロジェクトで Cursor 用の Coasts スキルを設定しています。すべての\nコマンドはプロジェクトルートから実行してください。\n\n## Step 1: Coast CLI を確認する\n\nこのコマンドを実行してください:\n\n coast --version\n\n`coast` コマンドが見つからない場合は、ここで停止してユーザーに次のように伝えてください:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nCLI が利用可能になるまで続行しないでください。\n\n## Step 2: スキルの内容を取得する\n\nこのコマンドを実行してください:\n\n coast skills-prompt\n\n出力には 2 つの部分があります:\n\n- **Coast Runtime ルール** — 先頭から `---` で始まる行の直前までのすべて\n- **Coasts スキル** — `---` の frontmatter ブロック以降のすべて(`---` の行とそれ以降のすべてを含む)\n\n以下の手順のために、両方の部分を保存してください。\n\n## Step 3: ユーザーに尋ねる\n\nユーザーに尋ねてください: これを **グローバルに**(このマシン上のすべてのプロジェクトで利用可能)設定しますか、それとも **このプロジェクトのみ** に設定しますか?\n\n## Step 4: ファイルを配置する\n\n対象ファイルがすでに存在する場合は、上書きするのではなく Coast Runtime セクションを追記してください。ただし、最初に `# Coast Runtime` セクションがすでに存在するか確認し、存在する場合はスキップしてください。\n\n**グローバル設定:**\n- Coast Runtime ルールをユーザーのグローバル Cursor ルールに追記する\n- Coasts スキルを `~/.cursor/skills/coasts/SKILL.md` に書き込む\n\n**プロジェクト設定:**\n- Coast Runtime ルールをプロジェクトルートの `AGENTS.md` に追記する(または、ユーザーが Cursor ネイティブのルールを希望する場合は `.cursor/rules/coast.md` に追記する — ユーザーに尋ねてください)\n- Coasts スキルを `.cursor/skills/coasts/SKILL.md` に書き込む\n\n## Step 5: Coastfile を更新する\n\nプロジェクトルートにある `Coastfile` を読んでください。`[coast]` セクションの\n`worktree_dir` フィールドを確認してください。また、`name` フィールドも読んでください — これを\nworktree パスの構築に使用します。\n\nCursor の worktree ディレクトリは `~/.cursor/worktrees/` で、`` は\nCoastfile 内の `name` フィールドの値です。\n\nそのパスが `worktree_dir` に**まだ**記載されていない場合:\n\n- `worktree_dir` が単一の文字列である場合は、配列に変換して\n Cursor のパスを追記してください。たとえば、`worktree_dir = \".worktrees\"` は\n `worktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]` になります。\n- `worktree_dir` がすでに配列である場合は、Cursor のパスをそれに追記してください。\n- `worktree_dir` がまったく存在しない場合は、\n `worktree_dir = [\".worktrees\", \"~/.cursor/worktrees/\"]` を\n 実際のプロジェクト名で追加してください。\n\nこれは外部パスなので、この\nプロジェクト用の Coast インスタンスがすでに実行中である場合は、新しい bind mount を有効にするために\n`coast run` で再作成する必要があります。これをユーザーに伝えてください。\n\n## Step 6: 確認する\n\nファイルを配置した後、何が作成され、どこに作成されたかの要約をユーザーに表示してください。\n\nスキルとルールの変更を有効にするために、ユーザーに次のように伝えてください: **Cursor を再起動してください**。\n", + "harnesses/shep_setup_prompt.txt": "このプロジェクトで Shep 用の Coasts スキルをセットアップしています。すべての\nコマンドはプロジェクトルートから実行してください。\n\n## Step 1: Coast CLI を確認する\n\nこのコマンドを実行します:\n\n coast --version\n\n`coast` コマンドが見つからない場合は、ここで停止してユーザーに次のように伝えてください:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nCLI が利用可能になるまで続行しないでください。\n\n## Step 2: スキルの内容を取得する\n\nこのコマンドを実行します:\n\n coast skills-prompt\n\n出力は 2 つの部分に分かれています:\n\n- **Coast Runtime ルール** — 先頭から、`---` で始まる行の直前までのすべて\n- **Coasts スキル** — `---` の frontmatter ブロック以降のすべて(`---` の行とその後のすべてを含む)\n\n以下の手順のために、両方の部分を保存してください。\n\n## Step 3: ファイルを配置する\n\nShep は Claude Code をラップしているため、Claude Code のファイルレイアウトを使用してください。対象ファイルが\nすでに存在する場合は、上書きするのではなく Coast Runtime セクションを追記してください。ただし、\n最初に `# Coast Runtime` セクションがすでに存在するか確認し、存在する場合はスキップしてください。\n\n- Coast Runtime ルールをプロジェクトルートの `CLAUDE.md` に追記する\n- Coasts スキルを `.agents/skills/coasts/SKILL.md` に書き込む(または、\n プロジェクトがすでにそのレイアウトを使用している場合は `.claude/skills/coasts/SKILL.md`)\n\n## Step 4: Coastfile を更新する\n\nプロジェクトルートの `Coastfile` を読み取ってください。`[coast]` セクション内の\n`worktree_dir` フィールドを確認します。\n\n`~/.shep/repos/*/wt` が `worktree_dir` に**まだ**含まれていない場合:\n\n- `worktree_dir` が単一の文字列である場合は、配列に変換して\n `~/.shep/repos/*/wt` を追加します。たとえば、`worktree_dir = \".worktrees\"` は\n `worktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]` になります。\n- `worktree_dir` がすでに配列である場合は、そこに `~/.shep/repos/*/wt` を追加します。\n- `worktree_dir` がまったく存在しない場合は、\n `worktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]` を追加します。\n\n`*` はリポジトリごとのハッシュディレクトリに一致する glob パターンです。Coasts は\n実行時にこれを展開します。\n\nこれは外部パスであるため、この\nプロジェクト用の Coast インスタンスがすでに実行中の場合、新しいバインドマウントを有効にするには\n`coast run` で再作成する必要があります。これをユーザーに伝えてください。\n\n## Step 5: 確認する\n\nファイルを配置した後、何が作成され、どこに配置されたかの要約をユーザーに表示します。\n\nスキルと CLAUDE.md の\n変更を有効にするには、ユーザーに次のように伝えてください: **エディタを終了して再度開いてください**。\n", + "harnesses/t3_code_setup_prompt.txt": "このプロジェクトで T3 Code 用の Coasts スキルを設定します。すべての\nコマンドはプロジェクトルートから実行してください。\n\n## Step 1: Coast CLI を確認する\n\nこのコマンドを実行します:\n\n coast --version\n\n`coast` コマンドが見つからない場合は、ここで停止してユーザーに次のように伝えてください:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nCLI が利用可能になるまで続行しないでください。\n\n## Step 2: スキルの内容を取得する\n\nこのコマンドを実行します:\n\n coast skills-prompt\n\n出力は 2 つの部分に分かれています:\n\n- **Coast Runtime rules** — 先頭から `---` で始まる行の直前までのすべて\n- **Coasts skill** — `---` の frontmatter ブロック以降のすべて(`---` の行とその後のすべてを含む)\n\n以下のステップのために、両方の部分を保存してください。\n\n## Step 3: ユーザーに確認する\n\nT3 Code は複数のプロバイダーをサポートしています。ユーザーに質問してください: T3 Code では\nどのプロバイダーを使っていますか?\n\n- **Codex** (OpenAI)\n- **Claude** (Anthropic)\n- **Both**\n- **Other** — ユーザーが別のプロバイダー名を挙げた場合は、\n `coast docs --path SKILLS_FOR_HOST_AGENTS.md` と\n `coast docs --path harnesses/README.md` を実行して、そのプロバイダーが\n プロジェクト指示とスキルをどこに期待しているかを確認し、その後は同じパターンに従ってください\n\n## Step 4: ファイルを配置する\n\nT3 Code のセットアップは常にプロジェクトレベルです。対象ファイルがすでに存在する場合は、\n上書きするのではなく Coast Runtime セクションを追記してください。ただしまず\n`# Coast Runtime` セクションがすでに存在するかを確認し、存在する場合はスキップしてください。\n\n**ユーザーが Codex(または両方)を選択した場合:**\n- Coast Runtime rules をプロジェクトルートの `AGENTS.md` に追記する\n- Coasts skill を `.agents/skills/coasts/SKILL.md` に書き込む(プロジェクトレベル)\n- さらに Coasts skill を `~/.codex/skills/coasts/SKILL.md` にも書き込む(グローバルな\n フォールバック — T3 Code はまだプロジェクトレベルの `.agents/skills/` をスキャンしない可能性があります)\n- `.agents/skills/coasts/agents/openai.yaml` を以下の内容で作成する:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n**ユーザーが Claude(または両方)を選択した場合:**\n- Coast Runtime rules をプロジェクトルートの `CLAUDE.md` に追記する\n- Coasts skill を `.claude/skills/coasts/SKILL.md` に書き込む(プロジェクトレベル)\n- さらに Coasts skill を `~/.claude/skills/coasts/SKILL.md` にも書き込む(グローバルな\n フォールバック — T3 Code はまだプロジェクトレベルの `.claude/skills/` を確実にスキャンしない可能性があります)\n\n**Note:** T3 Code はまだ `.agents/skills/` または\n`.claude/skills/` のプロジェクトレベルスキルを読み込まない可能性があります。`AGENTS.md` と `CLAUDE.md` のルールは、\nそれに関係なくすべてのタスクに毎回適用されます。グローバルな `~/.codex/skills/coasts/` フォールバックにより、\nCodex プロバイダーがスキルを見つけられるようになります。\n\n## Step 5: Coastfile を更新する\n\nプロジェクトルートの `Coastfile` を読んでください。`[coast]` セクション内の\n`worktree_dir` フィールドを確認します。また、`name` フィールドも読んでください — これを\nworktree パスの構築に使用します。\n\nT3 Code の worktree ディレクトリは `~/.t3/worktrees/` です。ここで `` は\nCoastfile 内の `name` フィールドの値です。\n\nそのパスがまだ `worktree_dir` に含まれて**いない**場合:\n\n- `worktree_dir` が単一の文字列であれば、配列に変換して\n T3 Code のパスを追加します。たとえば、`worktree_dir = \".worktrees\"` は\n `worktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]` になります。\n- `worktree_dir` がすでに配列であれば、そこに T3 Code のパスを追加します。\n- `worktree_dir` がまったく存在しない場合は、\n 実際のプロジェクト名を使って\n `worktree_dir = [\".worktrees\", \"~/.t3/worktrees/\"]` を追加します。\n\nこれは外部パスのため、このプロジェクトですでに Coast インスタンスが実行中の場合は、\n新しい bind mount を有効にするために `coast run` で再作成する必要があります。\nこのことをユーザーに伝えてください。\n\n## Step 6: 確認する\n\nファイルを配置した後、何が作成され、どこに作成されたかの概要をユーザーに示してください。\nグローバルな `~/.codex/skills/coasts/` コピーは、\nT3 Code がまだプロジェクトレベルのスキルを読み込まないことへの回避策であると説明してください。\n\nユーザーに次のように伝えてください: 変更したスキルとルールを有効にするには、\n**T3 Code を再起動**してください。\n", "learn-coasts-videos/README.md": "# Coasts ビデオコース\n\nCoasts の中核となる考え方を扱う短いビデオコースです。各レッスンは 3 分未満です。全体像を把握するには順番に視聴するか、必要なトピックに直接進んでください。\n\n```youtube\nMBGKSKau4sU\n```\n\n## レッスン\n\n1. [Coasts](coasts.md) — Coast とは何か、そして中核モデルがどのように機能するか。\n2. [Ports](ports.md) — Coasts がポートの分離と並列ランタイムアクセスをどのように扱うか。\n3. [Assign](assign.md) — 実行中の Coast をワークツリー間で切り替えること。\n4. [Checkout](checkout.md) — アクティブに使用するために Coast を正規ポートに配置すること。\n5. [Volumes](volumes.md) — Coasts がボリュームと永続的なサービス状態をどのように扱うか。\n6. [Secrets](secrets.md) — Coast 内でシークレットを管理すること。\n7. [Getting Started](getting-started.md) — 実際のプロジェクトで Coasts を試すための実践的なウォークスルー。\n8. [Coast UI](coast-ui.md) — Coastguard UI と、それが公開するランタイム情報。\n", "learn-coasts-videos/assign.md": "# Assign\n\n```youtube\nLYCeequ54nk\n```\n\nAssign は、ランタイムを停止することなく、実行中の Coast をある worktree から別の worktree へ移動します。この動画では、assignment の仕組みと、Coast を別のブランチに引き渡すためにそれをいつ使用するかを説明します。\n\n完全なリファレンスについては、[Assign and Unassign](../concepts_and_terminology/ASSIGN.md) を参照してください。\n", "learn-coasts-videos/checkout.md": "# Checkout\n\n```youtube\nJRAXkM4U1UE\n```\n\nCheckout は、プロジェクトの正規ポートを特定の Coast インスタンスにマッピングします。この動画では、1 つの Coast を前面に出し、ポート番号を一切変更することなく、ブラウザ、API クライアント、テストスイートのすべてが正しい環境にアクセスする方法を示します。\n\n完全なリファレンスについては、[Checkout](../concepts_and_terminology/CHECKOUT.md) を参照してください。\n", @@ -1502,6 +1526,11 @@ "path": "harnesses/MULTIPLE_HARNESSES.md", "type": "file" }, + { + "name": "SHEP.md", + "path": "harnesses/SHEP.md", + "type": "file" + }, { "name": "T3_CODE.md", "path": "harnesses/T3_CODE.md", @@ -1582,11 +1611,11 @@ "files": { "README.md": "# Coasts 문서\n\n```youtube\nMBGKSKau4sU\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## 설치\n\n- `curl -fsSL https://coasts.dev/install | sh`\n- `coast daemon install`\n\n*`coast daemon install`을 실행하지 않기로 결정한 경우, 매번 `coast daemon start`로 데몬을 수동으로 시작할 책임은 사용자에게 있습니다.*\n\n## Coasts란?\n\nA Coast(**컨테이너화된 호스트**)는 로컬 개발 런타임입니다. Coasts를 사용하면 한 대의 머신에서 동일한 프로젝트에 대해 여러 개의 격리된 환경을 실행할 수 있습니다.\n\nCoasts는 특히 많은 상호의존 서비스가 있는 복잡한 `docker-compose` 스택에 유용하지만, 컨테이너화되지 않은 로컬 개발 셋업에서도 동일하게 효과적입니다. Coasts는 광범위한 [런타임 구성 패턴](concepts_and_terminology/RUNTIMES_AND_SERVICES.md)을 지원하므로, 병렬로 작업하는 여러 에이전트에 대해 이상적인 환경을 구성할 수 있습니다.\n\nCoasts는 호스팅 클라우드 서비스가 아니라 로컬 개발을 위해 만들어졌습니다. 여러분의 환경은 여러분의 머신에서 로컬로 실행됩니다.\n\nCoasts 프로젝트는 무료이며 로컬에서 동작하고, MIT 라이선스를 따르며, 에이전트 제공자에 종속되지 않고, 에이전트 하네스에도 종속되지 않는 소프트웨어로, AI 업셀링이 없습니다.\n\nCoasts는 worktree를 사용하는 어떤 에이전틱 코딩 워크플로우와도 함께 동작합니다. 하네스 측의 특별한 구성은 필요하지 않습니다.\n\n## Worktrees를 위한 Coasts를 사용하는 이유\n\nGit worktree는 코드 변경을 격리하는 데 훌륭하지만, 런타임 격리를 그 자체로 해결하지는 못합니다.\n\n여러 worktree를 병렬로 실행하면, 금방 사용성 문제에 부딪히게 됩니다:\n\n- 동일한 호스트 포트를 기대하는 서비스들 간의 [포트 충돌](concepts_and_terminology/PORTS.md).\n- 관리가 번거로운 worktree별 데이터베이스 및 [볼륨 설정](concepts_and_terminology/VOLUMES.md).\n- worktree마다 커스텀 런타임 배선이 필요한 통합 테스트 환경.\n- worktree를 전환할 때마다 런타임 컨텍스트를 다시 빌드해야 하는, 말 그대로 살아있는 지옥. [할당 및 할당 해제](concepts_and_terminology/ASSIGN.md)를 참고하세요.\n\nGit이 코드에 대한 버전 관리라면, Coasts는 worktree 런타임에 대한 Git과 같습니다.\n\n각 환경은 자체 포트를 가지므로, 어떤 worktree 런타임이든 병렬로 검사할 수 있습니다. worktree 런타임을 [체크아웃](concepts_and_terminology/CHECKOUT.md)하면, Coasts는 해당 런타임을 프로젝트의 표준 포트로 리매핑합니다.\n\nCoasts는 런타임 구성을 worktree 위에 얹는 간단한 모듈식 레이어로 추상화하여, 각 worktree가 복잡한 worktree별 셋업을 손으로 유지보수하지 않고도 필요한 격리 수준으로 실행될 수 있게 합니다.\n\n## 요구 사항\n\n- macOS 또는 Linux\n- macOS에서는 Docker Desktop, Linux에서는 Compose 플러그인이 포함된 Docker Engine\n- Git을 사용하는 프로젝트\n- Node.js\n- `socat` (macOS에서는 `brew install socat`, Ubuntu에서는 `sudo apt install socat`)\n\n```text\nLinux 참고: 동적 포트는 Linux에서 별도 설정 없이 바로 동작합니다.\n`1024` 미만의 표준 포트가 필요하다면, 필요한 호스트 구성을 위해 checkout 문서를 참고하세요.\n```\n\n## 에이전트를 컨테이너화할까요?\n\nCoast로 에이전트를 컨테이너화할 수 있습니다. 처음에는 아주 좋은 아이디어처럼 들릴 수 있지만, 많은 경우 실제로는 코딩 에이전트를 컨테이너 안에서 실행할 필요가 없습니다.\n\nCoasts는 공유 볼륨 마운트를 통해 호스트 머신과 [파일시스템](concepts_and_terminology/FILESYSTEM.md)을 공유하기 때문에, 가장 쉽고 신뢰할 수 있는 워크플로우는 에이전트를 호스트에서 실행하고 [`coast exec`](concepts_and_terminology/EXEC_AND_DOCKER.md)를 사용해 통합 테스트 같은 런타임 부담이 큰 작업을 Coast 인스턴스 내부에서 실행하도록 지시하는 것입니다.\n\n하지만 에이전트를 컨테이너에서 실행하고 싶다면, Coasts는 [Agent Shells](concepts_and_terminology/AGENT_SHELLS.md)를 통해 이를 확실히 지원합니다. [MCP 서버 구성](concepts_and_terminology/MCP_SERVERS.md)을 포함해 이 셋업을 위한 믿을 수 없을 정도로 정교한 리그를 구축할 수도 있지만, 현재 존재하는 오케스트레이션 소프트웨어와 깔끔하게 상호운용되지 않을 수 있습니다. 대부분의 워크플로우에서는 호스트 측 에이전트가 더 단순하고 신뢰할 수 있습니다.\n\n## Coasts vs Dev Containers\n\nCoasts는 dev container가 아니며, 같은 것도 아닙니다.\n\nDev container는 일반적으로 IDE를 단일 컨테이너화된 개발 워크스페이스에 마운트하도록 설계됩니다. Coasts는 헤드리스이며, worktree를 사용하는 병렬 에이전트 사용을 위한 경량 환경으로 최적화되어 있습니다 — 여러 개의 격리된, worktree 인지형 런타임 환경이 나란히 실행되며, 빠른 체크아웃 전환과 각 인스턴스별 런타임 격리 제어를 제공합니다.\n\n## Demo Repo\n\nCoasts로 시험해 볼 수 있는 작은 예제 프로젝트를 원한다면, [`coasts-demo` repository](https://github.com/coast-guard/coasts-demo)로 시작하세요.\n\n## Coasts Video Course\n\n비디오를 선호한다면, [Coasts Video Course](learn-coasts-videos/README.md)에서 각 핵심 개념을 3분 이내로 모두 다룹니다.\n", "GETTING_STARTED.md": "# Coasts 시작하기\n\n```youtube\nJe921fgJ4RY\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## 설치\n\n```bash\ncurl -fsSL https://coasts.dev/install | sh\ncoast daemon install\n```\n\n*`coast daemon install`을 실행하지 않기로 결정했다면, 매번 `coast daemon start`로 데몬을 수동으로 시작할 책임이 있습니다.*\n\n## 요구 사항\n\n- macOS 또는 Linux\n- macOS에서는 Docker Desktop, Linux에서는 Compose 플러그인이 포함된 Docker Engine\n- Git을 사용하는 프로젝트\n- Node.js\n- `socat` (macOS에서는 `brew install socat`, Ubuntu에서는 `sudo apt install socat`)\n\n```text\nLinux 참고: 동적 포트는 Linux에서 별도 설정 없이 바로 동작합니다.\n`1024` 미만의 표준 포트가 필요하다면, 필요한 호스트 설정은 checkout 문서를 참고하세요.\n```\n\n## 프로젝트에서 Coasts 설정하기\n\n프로젝트 루트에 Coastfile을 추가하세요. 설치할 때 worktree 위에 있지 않은지 확인하세요.\n\n```text\nmy-project/\n├── Coastfile <-- Coast가 읽는 파일\n├── docker-compose.yml\n├── Dockerfile\n├── src/\n│ └── ...\n└── ...\n```\n\n`Coastfile`은 기존 로컬 개발 리소스를 가리키고 Coasts 전용 구성을 추가합니다 — 전체 스키마는 [Coastfiles 문서](coastfiles/README.md)를 참고하세요:\n\n```toml\n[coast]\nname = \"my-project\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\ndb = 5432\n```\n\nCoastfile은 *일반적으로* 기존의 `docker-compose.yml`을 가리키는 가벼운 TOML 파일입니다(컨테이너화되지 않은 로컬 개발 설정에서도 동작합니다). 또한 프로젝트를 병렬로 실행하기 위해 필요한 수정 사항(포트 매핑, 볼륨 전략, 시크릿)을 설명합니다. 프로젝트 루트에 배치하세요.\n\n프로젝트용 Coastfile을 만드는 가장 빠른 방법은 코딩 에이전트가 만들도록 하는 것입니다.\n\nCoasts CLI에는 어떤 AI 에이전트에게든 Coastfile 전체 스키마와 CLI를 가르쳐주는 내장 프롬프트가 포함되어 있습니다. 이를 에이전트의 채팅에 복사해 넣으면 프로젝트를 분석하고 Coastfile을 생성합니다.\n\n```prompt-copy\ninstallation_prompt.txt\n```\n\n또한 `coast installation-prompt`를 실행하면 CLI에서 동일한 출력을 얻을 수 있습니다.\n\n## 첫 번째 Coast\n\n첫 번째 Coast를 시작하기 전에, 실행 중인 모든 개발 환경을 내려주세요. Docker Compose를 사용 중이라면 `docker-compose down`을 실행하세요. 로컬 개발 서버가 실행 중이라면 중지하세요. Coasts는 자체 포트를 관리하며 이미 리스닝 중인 항목과 충돌합니다.\n\nCoastfile이 준비되면:\n\n```bash\ncoast build\ncoast run dev-1\n```\n\n인스턴스가 실행 중인지 확인하세요:\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ~/dev/my-project\n```\n\n서비스가 어디에서 리스닝 중인지 확인하세요:\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\n각 인스턴스는 여러 인스턴스가 나란히 실행될 수 있도록 고유한 동적 포트 세트를 받습니다. 인스턴스를 프로젝트의 표준 포트에 매핑하려면 체크아웃하세요:\n\n```bash\ncoast checkout dev-1\n```\n\n이는 런타임이 이제 체크아웃되었음을 의미하며, 프로젝트의 표준 포트(예: `3000`, `5432`)가 이 Coast 인스턴스로 라우팅됩니다.\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ✓ ~/dev/my-project\n```\n\n프로젝트의 Coastguard 관측 UI를 띄우려면:\n\n```bash\ncoast ui\n```\n\n## 다음은?\n\n- Coasts와 상호작용하는 방법을 알 수 있도록 [호스트 에이전트를 위한 skill](SKILLS_FOR_HOST_AGENTS.md)을 설정하세요\n", - "SKILLS_FOR_HOST_AGENTS.md": "# 호스트 에이전트를 위한 스킬\n\n앱이 Coasts 내부에서 실행되는 동안 호스트에서 AI 코딩 에이전트를 사용한다면,\n에이전트에는 보통 Coast 전용 설정이 두 가지 필요합니다:\n\n1. 하네스의 프로젝트 지침 파일 또는 규칙 파일에 항상 적용되는 Coast Runtime 섹션\n2. 하네스가 프로젝트 스킬을 지원할 때 `/coasts` 같은 재사용 가능한 Coast 워크플로 스킬\n\n첫 번째가 없으면 에이전트는 파일을 편집하지만 `coast exec` 사용을 잊습니다.\n두 번째가 없으면 모든 Coast 할당, 로그, UI 흐름을 채팅에서 매번 다시\n설명해야 합니다.\n\n이 가이드는 설정을 구체적이고 Coast에 맞게 유지합니다. 어떤 파일을 만들고,\n그 안에 어떤 텍스트를 넣어야 하는지, 그리고 그것이 하네스에 따라 어떻게\n달라지는지를 설명합니다.\n\n## 에이전트에 이것이 필요한 이유\n\nCoasts는 호스트 머신과 Coast 컨테이너 사이에서\n[filesystem](concepts_and_terminology/FILESYSTEM.md)을 공유합니다. 에이전트는 호스트에서 파일을 편집하고,\nCoast 내부에서 실행 중인 서비스는 그 변경 사항을 즉시 확인합니다. 하지만\n에이전트는 여전히 다음을 해야 합니다:\n\n1. 현재 체크아웃에 맞는 Coast 인스턴스를 찾기\n2. 해당 Coast 내부에서 테스트, 빌드, 런타임 명령 실행하기\n3. Coast에서 로그와 서비스 상태 읽기\n4. 아직 연결된 Coast가 없을 때 worktree 할당을 안전하게 처리하기\n\n## 무엇을 어디에 두어야 하나\n\n- `AGENTS.md`, `CLAUDE.md`, 또는 `.cursor/rules/coast.md` — 어떤 스킬도\n 호출되지 않았더라도 모든 작업에 적용되어야 하는 짧은 Coast 규칙\n- 스킬 (`.agents/skills/...`, `.claude/skills/...`, 또는 `.cursor/skills/...`)\n — `/coasts` 같은 재사용 가능한 Coast 워크플로 자체\n- 명령 파일 (`.claude/commands/...` 또는 `.cursor/commands/...`) — 선택 사항인\n 명시적 진입점으로, 이를 지원하는 하네스에서 사용할 수 있음; 한 가지 단순한\n 방법은 명령이 스킬을 재사용하게 하는 것\n\n하나의 저장소가 둘 이상의 하네스를 사용한다면, 정본 Coast 스킬은 한 곳에\n유지하고 필요한 곳에 노출하세요. 자세한 내용은\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md)를 참고하세요.\n\n## 1. 항상 적용되는 Coast Runtime 규칙\n\n다음 블록을 하네스의 항상 적용되는 프로젝트 지침 파일 또는 규칙 파일\n(`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/coast.md` 또는 이에 준하는 파일)에\n추가하세요:\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\n이 블록은 항상 적용되는 파일에 들어가야 합니다. 규칙은 에이전트가 명시적으로\n`/coasts` 워크플로에 들어갈 때만이 아니라 모든 작업에 적용되어야 하기\n때문입니다.\n\n## 2. 재사용 가능한 `/coasts` 스킬\n\n하네스가 프로젝트 스킬을 지원한다면, 스킬 내용을 스킬 디렉터리의 `SKILL.md`로\n저장하세요. 전체 스킬 텍스트는 [skills_prompt.txt](skills_prompt.txt)에\n있습니다(CLI 모드라면 `coast skills-prompt` 사용) — Coast Runtime 블록 뒤의\n모든 내용이 스킬 콘텐츠이며, `---` 프런트매터부터 시작합니다.\n\nCodex 또는 OpenAI 전용 표면을 사용 중이라면, 표시 메타데이터나 호출 정책을\n위해 스킬 옆에 `agents/openai.yaml`을 선택적으로 추가할 수 있습니다. 그\n메타데이터는 스킬을 대체하는 것이 아니라 스킬 옆에 있어야 합니다.\n\n## 하네스 빠른 시작\n\n| Harness | Always-on file | Reusable Coast workflow | Notes |\n|---------|----------------|-------------------------|-------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Coast 문서를 위해 별도로 권장할 프로젝트 명령 파일은 없습니다. [Codex](harnesses/CODEX.md)를 참고하세요. |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md`는 선택 사항이지만, 로직은 스킬에 유지하세요. [Claude Code](harnesses/CLAUDE_CODE.md)를 참고하세요. |\n| Cursor | `AGENTS.md` or `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` or shared `.agents/skills/coasts/SKILL.md` | `.cursor/commands/coasts.md`는 선택 사항입니다. `.cursor/worktrees.json`은 Cursor worktree 부트스트랩용이지 Coast 정책용이 아닙니다. [Cursor](harnesses/CURSOR.md)를 참고하세요. |\n| Conductor | `CLAUDE.md` | `CLAUDE.md`로 시작하고, Conductor 전용 동작에는 Conductor 스크립트와 설정을 사용하세요 | Claude Code의 전체 프로젝트 명령 동작을 가정하지 마세요. 새 명령이 나타나지 않으면 Conductor를 완전히 종료했다가 다시 여세요. [Conductor](harnesses/CONDUCTOR.md)를 참고하세요. |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | 여기서는 가장 제한적인 하네스 표면입니다. Codex 스타일 레이아웃을 사용하고 Coast 문서를 위한 T3 전용 명령 계층을 새로 만들지 마세요. [T3 Code](harnesses/T3_CODE.md)를 참고하세요. |\n\n## 에이전트가 스스로 설정하게 하기\n\n가장 빠른 방법은 에이전트가 올바른 파일을 직접 쓰게 하는 것입니다. 아래\n프롬프트를 에이전트의 채팅에 복사해 넣으세요 — 여기에는 Coast Runtime 블록,\n`coasts` 스킬 블록, 그리고 각 조각이 어디에 들어가야 하는지에 대한 하네스별\n지침이 포함되어 있습니다.\n\n```prompt-copy\nskills_prompt.txt\n```\n\nCLI에서 `coast skills-prompt`를 실행해도 동일한 출력을 얻을 수 있습니다.\n\n## 수동 설정\n\n- **Codex:** Coast Runtime 섹션을 `AGENTS.md`에 넣고, 그다음 재사용 가능한\n `coasts` 스킬을 `.agents/skills/coasts/SKILL.md`에 넣으세요.\n- **Claude Code:** Coast Runtime 섹션을 `CLAUDE.md`에 넣고, 그다음 재사용\n 가능한 `coasts` 스킬을 `.claude/skills/coasts/SKILL.md`에 넣으세요.\n 명령 파일이 특별히 필요할 때만 `.claude/commands/coasts.md`를 추가하세요.\n- **Cursor:** 가장 이식성 높은 지침을 원한다면 Coast Runtime 섹션을\n `AGENTS.md`에 넣고, Cursor 네이티브 프로젝트 규칙을 원한다면\n `.cursor/rules/coast.md`에 넣으세요. 재사용 가능한 `coasts` 워크플로는\n Cursor 전용 저장소라면 `.cursor/skills/coasts/SKILL.md`에, 다른 하네스와\n 저장소를 공유한다면 `.agents/skills/coasts/SKILL.md`에 넣으세요. 명시적\n 명령 파일이 특별히 필요할 때만 `.cursor/commands/coasts.md`를 추가하세요.\n- **Conductor:** Coast Runtime 섹션을 `CLAUDE.md`에 넣으세요. Conductor 전용\n 부트스트랩 또는 실행 동작에는 Conductor Repository Settings 스크립트를\n 사용하세요. 명령을 추가했는데 나타나지 않으면 앱을 완전히 종료했다가 다시\n 여세요.\n- **T3 Code:** Codex와 동일한 레이아웃을 사용하세요: `AGENTS.md`와\n `.agents/skills/coasts/SKILL.md`. 여기서는 T3 Code를 별도의 Coast 명령\n 표면이 아니라 얇은 Codex 스타일 하네스로 취급하세요.\n- **여러 하네스:** 정본 스킬은 `.agents/skills/coasts/SKILL.md`에\n 유지하세요. Cursor는 그것을 직접 로드할 수 있고, 필요하다면 Claude Code에는\n `.claude/skills/coasts/`를 통해 노출하세요.\n\n## 추가 읽을거리\n\n- 하네스별 매트릭스는 [Harnesses guide](harnesses/README.md)를 읽어보세요\n- 공유 레이아웃 패턴은 [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md)를\n 읽어보세요\n- 전체 구성 스키마를 배우려면 [Coastfiles documentation](coastfiles/README.md)을\n 읽어보세요\n- 인스턴스 관리를 위한 명령은 [Coast CLI](concepts_and_terminology/CLI.md)를\n 익혀두세요\n- Coasts를 관찰하고 제어하는 웹 UI인\n [Coastguard](concepts_and_terminology/COASTGUARD.md)를 살펴보세요\n", + "SKILLS_FOR_HOST_AGENTS.md": "# 호스트 에이전트를 위한 스킬\n\n앱이 Coasts 내부에서 실행되는 동안 호스트에서 AI 코딩 에이전트를 사용한다면,\n에이전트에는 보통 Coast 전용 설정이 두 가지 필요합니다:\n\n1. 하네스의 프로젝트 지침 파일 또는 규칙 파일에 항상 적용되는 Coast Runtime 섹션\n2. 하네스가 프로젝트 스킬을 지원할 때 `/coasts` 같은 재사용 가능한 Coast 워크플로 스킬\n\n첫 번째가 없으면 에이전트는 파일을 편집하지만 `coast exec` 사용을 잊습니다.\n두 번째가 없으면 모든 Coast 할당, 로그, UI 흐름을 채팅에서 매번 다시\n설명해야 합니다.\n\n이 가이드는 설정을 구체적이고 Coast에 맞게 유지합니다. 어떤 파일을 만들고,\n그 안에 어떤 텍스트를 넣어야 하는지, 그리고 그것이 하네스에 따라 어떻게\n달라지는지를 설명합니다.\n\n## 에이전트에 이것이 필요한 이유\n\nCoasts는 호스트 머신과 Coast 컨테이너 사이에서\n[filesystem](concepts_and_terminology/FILESYSTEM.md)을 공유합니다. 에이전트는 호스트에서 파일을 편집하고,\nCoast 내부에서 실행 중인 서비스는 그 변경 사항을 즉시 확인합니다. 하지만\n에이전트는 여전히 다음을 해야 합니다:\n\n1. 현재 체크아웃에 맞는 Coast 인스턴스를 찾기\n2. 해당 Coast 내부에서 테스트, 빌드, 런타임 명령 실행하기\n3. Coast에서 로그와 서비스 상태 읽기\n4. 아직 연결된 Coast가 없을 때 worktree 할당을 안전하게 처리하기\n\n## 무엇을 어디에 두어야 하나\n\n- `AGENTS.md`, `CLAUDE.md`, 또는 `.cursor/rules/coast.md` — 어떤 스킬도\n 호출되지 않았더라도 모든 작업에 적용되어야 하는 짧은 Coast 규칙\n- 스킬 (`.agents/skills/...`, `.claude/skills/...`, 또는 `.cursor/skills/...`)\n — `/coasts` 같은 재사용 가능한 Coast 워크플로 자체\n- 명령 파일 (`.claude/commands/...` 또는 `.cursor/commands/...`) — 선택 사항인\n 명시적 진입점으로, 이를 지원하는 하네스에서 사용할 수 있음; 한 가지 단순한\n 방법은 명령이 스킬을 재사용하게 하는 것\n\n하나의 저장소가 둘 이상의 하네스를 사용한다면, 정본 Coast 스킬은 한 곳에\n유지하고 필요한 곳에 노출하세요. 자세한 내용은\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md)를 참고하세요.\n\n## 1. 항상 적용되는 Coast Runtime 규칙\n\n다음 블록을 하네스의 항상 적용되는 프로젝트 지침 파일 또는 규칙 파일\n(`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/coast.md` 또는 이에 준하는 파일)에\n추가하세요:\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n coast exec --service # service shell\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Use `coast exec --service ` when you need to run inside an app/service container.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\n이 블록은 항상 적용되는 파일에 들어가야 합니다. 규칙은 에이전트가 명시적으로\n`/coasts` 워크플로에 들어갈 때만이 아니라 모든 작업에 적용되어야 하기\n때문입니다.\n\n## 2. 재사용 가능한 `/coasts` 스킬\n\n하네스가 프로젝트 스킬을 지원한다면, 스킬 내용을 스킬 디렉터리의 `SKILL.md`로\n저장하세요. 전체 스킬 텍스트는 [skills_prompt.txt](skills_prompt.txt)에\n있습니다(CLI 모드라면 `coast skills-prompt` 사용) — Coast Runtime 블록 뒤의\n모든 내용이 스킬 콘텐츠이며, `---` 프런트매터부터 시작합니다.\n\nCodex 또는 OpenAI 전용 표면을 사용 중이라면, 표시 메타데이터나 호출 정책을\n위해 스킬 옆에 `agents/openai.yaml`을 선택적으로 추가할 수 있습니다. 그\n메타데이터는 스킬을 대체하는 것이 아니라 스킬 옆에 있어야 합니다.\n\n## 하네스 빠른 시작\n\n| Harness | Always-on file | Reusable Coast workflow | Notes |\n|---------|----------------|-------------------------|-------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Coast 문서를 위해 별도로 권장할 프로젝트 명령 파일은 없습니다. [Codex](harnesses/CODEX.md)를 참고하세요. |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md`는 선택 사항이지만, 로직은 스킬에 유지하세요. [Claude Code](harnesses/CLAUDE_CODE.md)를 참고하세요. |\n| Cursor | `AGENTS.md` or `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` or shared `.agents/skills/coasts/SKILL.md` | `.cursor/commands/coasts.md`는 선택 사항입니다. `.cursor/worktrees.json`은 Cursor worktree 부트스트랩용이지 Coast 정책용이 아닙니다. [Cursor](harnesses/CURSOR.md)를 참고하세요. |\n| Conductor | `CLAUDE.md` | `CLAUDE.md`로 시작하고, Conductor 전용 동작에는 Conductor 스크립트와 설정을 사용하세요 | Claude Code의 전체 프로젝트 명령 동작을 가정하지 마세요. 새 명령이 나타나지 않으면 Conductor를 완전히 종료했다가 다시 여세요. [Conductor](harnesses/CONDUCTOR.md)를 참고하세요. |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | 여기서는 가장 제한적인 하네스 표면입니다. Codex 스타일 레이아웃을 사용하고 Coast 문서를 위한 T3 전용 명령 계층을 새로 만들지 마세요. [T3 Code](harnesses/T3_CODE.md)를 참고하세요. |\n\n## 에이전트가 스스로 설정하게 하기\n\n가장 빠른 방법은 에이전트가 올바른 파일을 직접 쓰게 하는 것입니다. 아래\n프롬프트를 에이전트의 채팅에 복사해 넣으세요 — 여기에는 Coast Runtime 블록,\n`coasts` 스킬 블록, 그리고 각 조각이 어디에 들어가야 하는지에 대한 하네스별\n지침이 포함되어 있습니다.\n\n```prompt-copy\nskills_prompt.txt\n```\n\nCLI에서 `coast skills-prompt`를 실행해도 동일한 출력을 얻을 수 있습니다.\n\n## 수동 설정\n\n- **Codex:** Coast Runtime 섹션을 `AGENTS.md`에 넣고, 그다음 재사용 가능한\n `coasts` 스킬을 `.agents/skills/coasts/SKILL.md`에 넣으세요.\n- **Claude Code:** Coast Runtime 섹션을 `CLAUDE.md`에 넣고, 그다음 재사용\n 가능한 `coasts` 스킬을 `.claude/skills/coasts/SKILL.md`에 넣으세요.\n 명령 파일이 특별히 필요할 때만 `.claude/commands/coasts.md`를 추가하세요.\n- **Cursor:** 가장 이식성 높은 지침을 원한다면 Coast Runtime 섹션을\n `AGENTS.md`에 넣고, Cursor 네이티브 프로젝트 규칙을 원한다면\n `.cursor/rules/coast.md`에 넣으세요. 재사용 가능한 `coasts` 워크플로는\n Cursor 전용 저장소라면 `.cursor/skills/coasts/SKILL.md`에, 다른 하네스와\n 저장소를 공유한다면 `.agents/skills/coasts/SKILL.md`에 넣으세요. 명시적\n 명령 파일이 특별히 필요할 때만 `.cursor/commands/coasts.md`를 추가하세요.\n- **Conductor:** Coast Runtime 섹션을 `CLAUDE.md`에 넣으세요. Conductor 전용\n 부트스트랩 또는 실행 동작에는 Conductor Repository Settings 스크립트를\n 사용하세요. 명령을 추가했는데 나타나지 않으면 앱을 완전히 종료했다가 다시\n 여세요.\n- **T3 Code:** Codex와 동일한 레이아웃을 사용하세요: `AGENTS.md`와\n `.agents/skills/coasts/SKILL.md`. 여기서는 T3 Code를 별도의 Coast 명령\n 표면이 아니라 얇은 Codex 스타일 하네스로 취급하세요.\n- **여러 하네스:** 정본 스킬은 `.agents/skills/coasts/SKILL.md`에\n 유지하세요. Cursor는 그것을 직접 로드할 수 있고, 필요하다면 Claude Code에는\n `.claude/skills/coasts/`를 통해 노출하세요.\n\n## 추가 읽을거리\n\n- 하네스별 매트릭스는 [Harnesses guide](harnesses/README.md)를 읽어보세요\n- 공유 레이아웃 패턴은 [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md)를\n 읽어보세요\n- 전체 구성 스키마를 배우려면 [Coastfiles documentation](coastfiles/README.md)을\n 읽어보세요\n- 인스턴스 관리를 위한 명령은 [Coast CLI](concepts_and_terminology/CLI.md)를\n 익혀두세요\n- Coasts를 관찰하고 제어하는 웹 UI인\n [Coastguard](concepts_and_terminology/COASTGUARD.md)를 살펴보세요\n", "VIDEO_TUTORIALS.md": "# 비디오 튜토리얼\n\n이 페이지는 Coasts YouTube 채널의 공식 Coasts 튜토리얼 비디오를 모아 둡니다.\n\n나머지 문서를 읽기 전에 빠른 비디오 안내를 선호한다면, 개요 및 시작하기 비디오부터 보고, 이후 아래의 기능별 주제로 넘어가세요.\n\n## 링크\n\n- [Coasts YouTube channel](https://www.youtube.com/@coasts-dev) - Coasts 비디오를 위한 공식 채널입니다.\n- [Coasts playlist](https://www.youtube.com/playlist?list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw) - 전체 튜토리얼 재생목록을 한 곳에 모아 둔 것입니다.\n\n## 비디오\n\n- [Coasts Overview](https://www.youtube.com/watch?v=MBGKSKau4sU&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=1&pp=iAQB) (2:42) - Coasts가 무엇이며 왜 사용할 수 있는지에 대한 상위 수준의 소개입니다.\n- [Coasts](https://www.youtube.com/watch?v=kYlB5U9O92E&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=2&pp=iAQB) (1:29) - 핵심 Coasts 모델을 짧게 둘러봅니다.\n- [Ports](https://www.youtube.com/watch?v=pBKkBiJ3o-g&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=3&pp=iAQB) (1:46) - Coasts가 포트 격리 및 병렬 런타임 액세스를 처리하는 방법입니다.\n- [Assign](https://www.youtube.com/watch?v=LYCeequ54nk&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=4&pp=iAQB) (1:57) - 실행 중인 Coast를 worktree 간에 전환하는 방법입니다.\n- [Checkout](https://www.youtube.com/watch?v=JRAXkM4U1UE&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=5&pp=iAQB) (1:46) - 활성 사용을 위해 하나의 Coast를 표준 포트(canonical ports)로 가져오는 방법입니다.\n- [Volumes](https://www.youtube.com/watch?v=k1es1Wf0zp0&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=6&pp=iAQB) (2:00) - Coasts가 볼륨과 영속적인 서비스 상태를 다루는 방법입니다.\n- [Secrets](https://www.youtube.com/watch?v=4lAfHUjqn50&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=7&pp=iAQB) (2:09) - Coast 내부에서 시크릿을 관리하는 방법입니다.\n- [Getting Started](https://www.youtube.com/watch?v=Je921fgJ4RY&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=8&pp=iAQB) (2:40) - Coasts를 사용해 보기 위한 빠른 온보딩 안내입니다.\n- [Coast UI](https://www.youtube.com/watch?v=Ts-YWkhHR8I&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=9&pp=iAQB0gcJCa4KAYcqIYzv) (1:46) - Coastguard UI와 그것이 노출하는 런타임 정보를 둘러봅니다.\n\n이 페이지는 공식 재생목록의 현재 콘텐츠를 반영하며, 새 튜토리얼 비디오가 추가되면 업데이트될 수 있습니다.\n", - "doc_ordering.txt": "# 최상위\nREADME.md\nGETTING_STARTED.md\nSKILLS_FOR_HOST_AGENTS.md\n\n# Learn Coasts\nlearn-coasts-videos/README.md\nlearn-coasts-videos/coasts.md\nlearn-coasts-videos/ports.md\nlearn-coasts-videos/assign.md\nlearn-coasts-videos/checkout.md\nlearn-coasts-videos/volumes.md\nlearn-coasts-videos/secrets.md\nlearn-coasts-videos/getting-started.md\nlearn-coasts-videos/coast-ui.md\n\n# 하네스\nharnesses/README.md\nharnesses/CODEX.md\nharnesses/CONDUCTOR.md\nharnesses/CLAUDE_CODE.md\nharnesses/CURSOR.md\nharnesses/T3_CODE.md\nharnesses/MULTIPLE_HARNESSES.md\n\n# 개념 및 용어\nconcepts_and_terminology/README.md\nconcepts_and_terminology/COASTS.md\nconcepts_and_terminology/RUN.md\nconcepts_and_terminology/REMOVE.md\nconcepts_and_terminology/FILESYSTEM.md\nconcepts_and_terminology/DAEMON.md\nconcepts_and_terminology/CLI.md\nconcepts_and_terminology/COASTGUARD.md\nconcepts_and_terminology/PORTS.md\nconcepts_and_terminology/PRIMARY_PORT_AND_DNS.md\nconcepts_and_terminology/ASSIGN.md\nconcepts_and_terminology/CHECKOUT.md\nconcepts_and_terminology/LOOKUP.md\nconcepts_and_terminology/VOLUMES.md\nconcepts_and_terminology/SHARED_SERVICES.md\nconcepts_and_terminology/SECRETS.md\nconcepts_and_terminology/BUILDS.md\nconcepts_and_terminology/COASTFILE_TYPES.md\nconcepts_and_terminology/RUNTIMES_AND_SERVICES.md\nconcepts_and_terminology/BARE_SERVICES.md\nconcepts_and_terminology/MIXED_SERVICE_TYPES.md\nconcepts_and_terminology/LOGS.md\nconcepts_and_terminology/EXEC_AND_DOCKER.md\nconcepts_and_terminology/AGENT_SHELLS.md\nconcepts_and_terminology/MCP_SERVERS.md\nconcepts_and_terminology/PERFORMANCE_OPTIMIZATIONS.md\nconcepts_and_terminology/TROUBLESHOOTING.md\n\n# Coastfiles\ncoastfiles/README.md\ncoastfiles/PROJECT.md\ncoastfiles/WORKTREE_DIR.md\ncoastfiles/PORTS.md\ncoastfiles/SHARED_SERVICES.md\ncoastfiles/SERVICES.md\ncoastfiles/SECRETS.md\ncoastfiles/VOLUMES.md\ncoastfiles/ASSIGN.md\ncoastfiles/INHERITANCE.md\ncoastfiles/AGENT_SHELL.md\ncoastfiles/MCP.md\n\n# 레시피\nrecipes/README.md\nrecipes/FULLSTACK_MONOREPO.md\n", - "installation_prompt.txt": "이 프로젝트에 Coasts를 설치하고 있습니다. Coast(컨테이너화된 호스트)는 Docker-in-Docker 컨테이너를 사용해 단일 머신에서 여러 개의 격리된 개발 환경을 실행하는 CLI 도구입니다. 각 환경은 자체 포트, 볼륨, 런타임을 가지므로 병렬 worktree 워크플로에 이상적입니다.\n\n당신의 작업: 이 프로젝트를 분석하고 Coastfile(프로젝트 루트에 \"Coastfile\"이라는 이름의 TOML 파일)을 생성하세요.\n\n=== DOCUMENTATION ===\n\nCoast에는 CLI에서 접근 가능한 내장 문서가 있습니다. Coastfile 전체 스키마, 볼륨 전략, assign 동작, 기타 설정 옵션을 이해하기 위해 Coastfile을 생성하기 전에 이를 사용하세요.\n\n문서 트리를 탐색하세요:\n\n coast docs\n\n이는 전체 문서 트리를 출력합니다. README 파일부터 읽기 시작하세요 — 각 주제에 맞는 문서를 찾는 데 도움이 되는 인덱스를 제공합니다:\n\n coast docs --path README.md\n coast docs --path coastfiles/README.md\n coast docs --path concepts_and_terminology/README.md\n\n특정 문서를 읽으세요:\n\n coast docs --path coastfiles/PROJECT.md\n coast docs --path coastfiles/VOLUMES.md\n\n문서를 검색하세요(의미 기반 검색 — 찾고 있는 것을 자연어로 설명):\n\n coast search-docs \"how do volume strategies work\"\n coast search-docs \"shared postgres across instances\"\n coast search-docs \"secret injection from environment variables\"\n\n문서를 사용해 이 프로젝트의 Coastfile 구성에 대해 정보에 기반한 결정을 내리세요. coastfiles/ 섹션은 모든 Coastfile 지시어를 자세히 다룹니다.\n\n=== COASTFILE SCHEMA (quick reference) ===\n\n[coast] — 필수. 프로젝트 메타데이터.\n\n name (string, required) 컨테이너/볼륨 이름 지정에 사용되는 프로젝트 식별자.\n compose (string, optional) Coastfile 기준의 docker-compose.yml 상대 경로.\n runtime (string, optional) \"dind\"(기본값), \"sysbox\", 또는 \"podman\".\n root (string, optional) 프로젝트 루트 오버라이드(상대 또는 절대).\n worktree_dir (string, optional) git worktree를 위한 디렉터리(기본값: \".worktrees\"). 런타임에 기존 worktree에서 자동 감지.\n\n[coast.setup] — 선택. DinD 컨테이너 자체를 커스터마이즈.\n\n packages (array of strings) 설치할 Alpine 패키지(예: [\"nodejs\", \"npm\", \"git\"]).\n run (array of strings) 설정 중 실행할 임의의 명령.\n\n[ports] — 필수(최소 1개). 논리적 이름에서 포트 번호로의 맵.\n 이 포트들은 coast가 체크아웃될 때 호스트로 포워딩됩니다.\n\n 예시:\n [ports]\n web = 3000\n api = 8080\n postgres = 5432\n\n[volumes.*] — 선택. 볼륨별 구성.\n\n strategy \"isolated\"(기본값) 또는 \"shared\"\n service 이 볼륨을 소유하는 Compose 서비스 이름.\n mount 서비스 컨테이너 내부의 마운트 경로.\n snapshot_source (isolated 전용) 기존 볼륨 이름에서 시드.\n\n 예시:\n [volumes.postgres_data]\n strategy = \"isolated\"\n service = \"db\"\n mount = \"/var/lib/postgresql/data\"\n\n[secrets.*] — 선택. 시크릿 추출 및 주입.\n\n extractor \"file\", \"env\", \"command\", 또는 \"macos-keychain\"\n inject \"env:VAR_NAME\" 또는 \"file:/path/in/container\"\n ttl 선택적 만료(예: \"1h\", \"30m\").\n\n extractor별 파라미터:\n file: path = \"./path/to/secret\"\n env: var = \"HOST_ENV_VAR\"\n command: run = \"echo secret-value\"\n macos-keychain: item = \"keychain-item-name\"\n\n 예시:\n [secrets.db_password]\n extractor = \"env\"\n var = \"DB_PASSWORD\"\n inject = \"env:DATABASE_PASSWORD\"\n\n[inject] — 선택. 비시크릿 호스트 파일/환경변수 주입.\n\n env 포워딩할 호스트 환경변수 이름 배열.\n files 마운트할 호스트 파일 경로 배열.\n\n 예시:\n [inject]\n env = [\"NODE_ENV\", \"DEBUG\"]\n files = [\"~/.ssh/id_ed25519\", \"~/.gitconfig\"]\n\n[shared_services.*] — 선택. 인스턴스 간 공유되는 호스트 Docker 데몬의 서비스.\n\n image Docker 이미지.\n ports 포트 번호 배열.\n volumes 볼륨 마운트 배열.\n env 환경변수 인라인 테이블.\n auto_create_db (bool) 인스턴스별 데이터베이스를 자동으로 생성.\n inject coast 컨테이너에 연결 문자열을 주입.\n\n 예시:\n [shared_services.postgres]\n image = \"postgres:16-alpine\"\n ports = [5432]\n volumes = [\"postgres_data:/var/lib/postgresql/data\"]\n env = { POSTGRES_USER = \"dev\", POSTGRES_PASSWORD = \"dev\", POSTGRES_DB = \"app\" }\n auto_create_db = true\n inject = \"env:DATABASE_URL\"\n\n[assign] — 선택. 브랜치 전환 시(coast assign) 동작을 제어.\n\n default \"none\", \"restart\", 또는 \"rebuild\"\n [assign.services] 서비스별 오버라이드.\n [assign.rebuild_triggers] 서비스별 리빌드를 트리거하는 파일 글롭.\n\n 예시:\n [assign]\n default = \"none\"\n [assign.services]\n api = \"restart\"\n worker = \"rebuild\"\n [assign.rebuild_triggers]\n worker = [\"Dockerfile\", \"package.json\"]\n\n[services.*] — 선택. 베어 프로세스 서비스(docker-compose 불필요).\n\n command 실행할 셸 명령.\n port 포트 번호.\n restart \"on-failure\" 또는 \"always\".\n\n 예시:\n [services.web]\n command = \"node server.js\"\n port = 3000\n restart = \"on-failure\"\n\n=== EXAMPLE: Minimal (no compose) ===\n\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[ports]\napp = 3000\n\n=== EXAMPLE: With docker-compose ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\npostgres = 5432\nredis = 6379\n\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n\n=== EXAMPLE: With secrets ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\n\n[secrets.api_key]\nextractor = \"env\"\nvar = \"API_KEY\"\ninject = \"env:API_KEY\"\n\n[secrets.ssh_key]\nextractor = \"file\"\npath = \"~/.ssh/id_ed25519\"\ninject = \"file:/run/secrets/ssh_key\"\n\n=== KEY TRADEOFFS TO DISCUSS WITH THE USER ===\n\nCoastfile을 생성하기 전에 모호한 구성 선택에 대해 사용자에게 물어보세요. 주요 항목은 다음과 같습니다:\n\n데이터베이스 및 인프라 전략 — postgres와 redis 같은 서비스에 대해 세 가지 옵션이 있습니다:\n - 격리된 볼륨(기본값): 각 Coast 인스턴스는 DinD 컨테이너 내부에 자체 데이터 사본을 가집니다. 인스턴스들은 서로 간섭할 수 없습니다. 브랜치별 데이터베이스 상태가 필요할 때 최적입니다.\n - 공유 볼륨: 모든 인스턴스가 DinD 컨테이너 내부에서 동일한 볼륨을 읽고 씁니다. 디스크 공간을 절약하지만 여러 인스턴스의 동시 쓰기는 데이터를 손상시킬 수 있습니다.\n - 공유 서비스: 각 Coast 내부가 아니라 호스트 Docker 데몬에서 데이터베이스를 실행합니다. 모든 인스턴스가 하나의 공유 서버에 연결합니다. 메모리를 가장 적게 사용하고, 단일 postgres에서 인스턴스별 데이터베이스를 위한 auto_create_db를 지원하며, 데이터는 인스턴스 삭제 이후에도 유지됩니다. 대규모 팀 또는 메모리 제약이 있는 머신에 최적입니다.\n - 프로젝트에 데이터베이스가 있다면, 사용자가 어떤 접근을 원하는지 물어보세요. 트레이드오프를 설명하세요 — 격리가 가장 안전하고, 공유 서비스가 메모리 효율이 가장 좋습니다.\n\nAssign 전략 — Coast를 worktree 간 전환할 때 발생하는 일:\n - \"none\": 아무 것도 하지 않음(브랜치 간 변경이 없는 postgres/redis 같은 서비스에 적합).\n - \"restart\": 컨테이너 재시작(프로세스 재시작만 필요한 인터프리터 기반 서비스에 적합).\n - \"rebuild\": Docker 이미지를 재빌드하고 재시작(브랜치 변경이 Dockerfile 또는 빌드 의존성에 영향을 주는 서비스에 적합).\n - 프로젝트에 여러 서비스가 있다면, 브랜치 전환 시 어떤 서비스가 rebuild가 필요하고 어떤 서비스가 restart면 되는지 물어보세요.\n\n=== INSTRUCTIONS ===\n\n1. 이 프로젝트의 구조를 살펴보세요. docker-compose.yml이 있다면, 서비스를 식별하고 포트와 볼륨을 파악하기 위해 이를 읽으세요.\n2. 기존 git worktree 디렉터리를 감지하세요. `git worktree list`를 실행해 프로젝트에 이미 git worktree가 설정되어 있는지 확인하세요.\n - worktree가 존재한다면, 경로를 조사해 공통 부모 디렉터리를 결정하세요(예: worktree가 `../.worktrees/feat-a` 및 `../.worktrees/feat-b`에 있다면 worktree_dir는 `\"../.worktrees\"`).\n - 감지된 디렉터리와 일치하도록 Coastfile의 `worktree_dir`를 설정하세요.\n - worktree가 없다면 `worktree_dir`를 생략하세요(Coast 기본값은 \".worktrees\"). \".coasts\"를 사용하지 마세요 — 프로젝트에 Coast 브랜드 디렉터리를 만들어 오염시킵니다.\n3. 관련 Coast 문서를 읽으세요(`coast docs` 및 `coast search-docs` 사용). 이 프로젝트 스택에 적용되는 볼륨 전략, assign 동작, 및 구성 옵션을 이해하세요.\n4. 모호한 구성 선택에 대해 사용자에게 물어보세요(위 트레이드오프 참조). 추측하지 마세요 — 옵션을 설명하고 사용자가 결정하게 하세요.\n5. 프로젝트 분석 및 사용자 입력을 바탕으로 프로젝트 루트에 Coastfile을 생성하세요.\n6. 프로젝트에 docker-compose.yml이 없다면, 베어 프로세스 정의에는 [services.*]를 사용하거나 의존성 설치에는 [coast.setup]을 사용하세요.\n7. `coast build`를 실행하세요. 실패하면 오류를 확인하고 문서(`coast search-docs \"\"`)를 참고하여 문제를 해결하세요.\n8. `coast run dev-1`을 실행하세요. 실패하면 오류를 확인하고 문서를 참고하세요.\n9. `coast ui`를 실행해 Coastguard 대시보드를 여세요(이 단계는 작업이 끝났을 때 사용자를 위한 것입니다).\n", - "skills_prompt.txt": "# Coast Runtime\n\n이 프로젝트는 서비스, 테스트 및 기타 런타임 명령을 실행하기 위해 Coasts — 컨테이너화된 런타임 — 를 사용합니다. 파일 시스템은 호스트와 컨테이너 사이에 공유되므로, 어느 쪽에서든 파일을 편집하면 양쪽에 즉시 반영됩니다.\n\n## Discovery\n\n세션에서 첫 번째 런타임 명령을 실행하기 전에 다음을 실행하세요:\n\n coast lookup\n\n이 명령은 인스턴스 이름, 포트, 예시 명령을 출력합니다. 이후의 모든 명령에는 출력에 나온 인스턴스 이름을 사용하세요.\n\n## What runs where\n\n파일 시스템은 공유되므로, 컨테이너 런타임(데이터베이스, 서비스, 통합 테스트)이 필요한 작업에만 `coast exec`를 사용하세요. 그 외의 모든 것은 호스트에서 직접 실행합니다.\n\n다음에는 `coast exec`를 사용하세요:\n- 실행 중인 서비스가 필요한 테스트(서비스나 DB와 통합된 단위 테스트, 통합 테스트, API 테스트)\n- 서비스 재시작 또는 compose 작업\n- 데이터베이스, 캐시 또는 기타 컨테이너 서비스와 통신하는 모든 작업\n\n다음은 호스트에서 직접 실행하세요:\n- 린팅, 타입체킹, 포매팅\n- Git 작업\n- Playwright 및 브라우저 테스트\n- 호스트 측 의존성 설치(npm install, pip install)\n- 파일 검색, 코드 생성, 정적 분석\n\n예시:\n\n coast exec -- sh -c \"cd && npm test\" # DB 필요\n npm run lint # 호스트에서 충분\n npx playwright test # 호스트에서 충분\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\n`coast lookup`이 일치하는 항목을 반환하지 않으면, 무엇이 있는지 보기 위해 `coast ls`를 실행하세요.\n\n이 프로젝트에 대해 아직 할당되지 않은 Coast가 이미 실행 중이라면, 새로 만드는 것보다 해당 Coast에 워크트리를 할당하는 것을 우선하세요:\n\n coast assign -w \n\n이미 사용 중인 Coast도 `coast assign`으로 재할당할 수 있지만, 현재 슬롯이 중단되므로 먼저 사용자에게 확인하세요.\n\n실행 중인 Coast가 없다면, 새로 만들기 전에 사용자에게 물어보세요 — Coasts는 메모리를 많이 사용할 수 있습니다:\n\n coast run -w \n\n인스턴스를 생성하려면 먼저 프로젝트가 빌드되어 있어야 합니다. 빌드가 없어서 `coast run`이 실패하면 먼저 `coast build`를 실행하세요.\n\n## Coastfile setup\n\n프로젝트에 아직 Coastfile이 없거나 Coastfile을 수정해야 한다면, 먼저 Coastfile 문서를 읽으세요:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nCoast 동작을 추측하기 전에 문서를 살펴보세요:\n\n coast docs # 모든 문서 페이지 나열\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # 시맨틱 검색\n\n## Rules\n\n- 세션에서 첫 번째 런타임 명령 전에 항상 `coast lookup`을 실행하세요.\n- 컨테이너 런타임이 필요한 작업에만 `coast exec`를 사용하세요.\n- 린팅, 타입체킹, 포매팅, git은 호스트에서 직접 실행하세요.\n- Coast 동작을 추측하기 전에 `coast docs` 또는 `coast search-docs`를 사용하세요.\n- 프로젝트가 Coast를 기대하는 경우 호스트에서 서비스를 직접 실행하지 마세요.\n\n---\nname: coasts\ndescription: 현재 체크아웃에 대한 Coast 인스턴스를 검사하고 제어합니다. 사용자가 \"/coasts\"라고 말하거나, Coast를 할당 또는 재할당해 달라고 요청하거나, 일치하는 Coast에서 명령 실행 또는 로그 읽기를 원하거나, 새 Coast를 만들고 싶어 하거나, Coast UI를 열어 달라고 명시적으로 요청할 때 사용합니다.\n---\n\n# Coasts\n\nCoast CLI를 직접 사용하세요. 래퍼를 추가하지 마세요.\n\n## Orient Yourself\n\n먼저 CLI와 문서를 살펴보세요:\n\n coast # 사용 가능한 모든 명령 보기\n coast docs # 모든 문서 페이지 나열\n coast search-docs \"your question\" # 시맨틱 검색\n\nCoast 동작과 관련해 불분명한 점이 있으면, 추측하기 전에 문서를 읽으세요:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\n요청을 다음 모드 중 하나로 분기하세요:\n\n1. **Use Coast** — `coast lookup`을 실행한 다음, 일치하는 인스턴스에 대해 `coast exec`, `coast ps`, 또는 `coast logs`를 사용합니다.\n2. **Create or Assign** — `coast ls`를 실행한 다음, `coast run`으로 새 Coast를 만들거나 `coast assign`으로 기존 Coast가 가리키는 대상을 변경합니다.\n3. **Open UI** — `coast ui`를 실행합니다.\n\n## What Runs Where\n\n호스트와 Coast는 파일 시스템을 공유합니다. 컨테이너 내부에서 실행 중인 서비스가 필요한 작업에만 `coast exec`를 사용하세요.\n\n**다음에는 `coast exec`를 사용하세요:**\n- 통합 테스트, API 테스트, 데이터베이스나 서비스가 필요한 모든 작업\n- 서비스 재시작, compose 작업\n- 컨테이너에서만 실행되는 프로세스와 통신하는 명령\n\n**다음은 호스트에서 실행하세요:**\n- 린팅 (`eslint`, `rubocop`, `golangci-lint`)\n- 타입체킹 (`tsc --noEmit`, `go vet`)\n- 포매팅 (`prettier`, `gofmt`)\n- Git 작업\n- Playwright 및 브라우저 테스트\n- 정적 분석, 코드 생성\n- 패키지 설치 (`npm install`, `pip install`)\n\n## Create and Assign\n\n`coast lookup`이 일치하는 항목을 반환하지 않을 때:\n\n1. 사용 가능한 슬롯을 보기 위해 `coast ls`를 실행하세요.\n2. 한 번에 생성하고 할당하려면 `coast run -w `를 우선 사용하세요.\n3. 아직 빌드가 없다면 먼저 `coast build`를 실행하세요.\n4. 생성 후 확인을 위해 `coast lookup`을 다시 실행하세요.\n\n기존 Coast를 다른 워크트리로 전환하려는 경우:\n\n coast assign -w \n\n이 방법은 이미 할당되었거나 체크아웃된 Coast에도 동작하지만, 사용 중인 슬롯을 재할당하기 전에는 먼저 사용자에게 물어보세요.\n\n## Coastfile Setup\n\n프로젝트에 새 Coastfile이 필요하거나 기존 Coastfile을 수정해야 한다면, 먼저 문서를 읽으세요:\n\n coast docs --path coastfiles/README.md\n\nCoastfile 문서에는 compose 설정, 포트, 볼륨, 시크릿, 공유 서비스, bare 서비스, 상속이 포함되어 있습니다.\n\n## Safety Rules\n\n- 조치를 취하기 전에 `coast lookup`을 실행하고, 토폴로지가 변경된 후에도 다시 실행하세요.\n- `coast assign`, `coast unassign`, 또는 `coast checkout`이 기존 슬롯을 방해하게 된다면 먼저 물어보세요.\n- 사용자가 기존 슬롯의 재할당을 명시적으로 원하지 않는 한, 체크아웃되었거나 이미 할당된 Coast를 재사용하는 것보다 새 Coast를 만드는 것을 우선하세요.\n- 추측하기 전에 `coast docs` 또는 `coast search-docs`를 사용하세요.\n", + "doc_ordering.txt": "# 최상위\nREADME.md\nGETTING_STARTED.md\nSKILLS_FOR_HOST_AGENTS.md\n\n# Learn Coasts\nlearn-coasts-videos/README.md\nlearn-coasts-videos/coasts.md\nlearn-coasts-videos/ports.md\nlearn-coasts-videos/assign.md\nlearn-coasts-videos/checkout.md\nlearn-coasts-videos/volumes.md\nlearn-coasts-videos/secrets.md\nlearn-coasts-videos/getting-started.md\nlearn-coasts-videos/coast-ui.md\n\n# 하네스\nharnesses/README.md\nharnesses/CODEX.md\nharnesses/CONDUCTOR.md\nharnesses/CLAUDE_CODE.md\nharnesses/CURSOR.md\nharnesses/T3_CODE.md\nharnesses/SHEP.md\nharnesses/MULTIPLE_HARNESSES.md\n\n# 개념 및 용어\nconcepts_and_terminology/README.md\nconcepts_and_terminology/COASTS.md\nconcepts_and_terminology/RUN.md\nconcepts_and_terminology/REMOVE.md\nconcepts_and_terminology/FILESYSTEM.md\nconcepts_and_terminology/DAEMON.md\nconcepts_and_terminology/CLI.md\nconcepts_and_terminology/COASTGUARD.md\nconcepts_and_terminology/PORTS.md\nconcepts_and_terminology/PRIMARY_PORT_AND_DNS.md\nconcepts_and_terminology/ASSIGN.md\nconcepts_and_terminology/CHECKOUT.md\nconcepts_and_terminology/LOOKUP.md\nconcepts_and_terminology/VOLUMES.md\nconcepts_and_terminology/SHARED_SERVICES.md\nconcepts_and_terminology/SECRETS.md\nconcepts_and_terminology/BUILDS.md\nconcepts_and_terminology/COASTFILE_TYPES.md\nconcepts_and_terminology/RUNTIMES_AND_SERVICES.md\nconcepts_and_terminology/BARE_SERVICES.md\nconcepts_and_terminology/MIXED_SERVICE_TYPES.md\nconcepts_and_terminology/LOGS.md\nconcepts_and_terminology/EXEC_AND_DOCKER.md\nconcepts_and_terminology/AGENT_SHELLS.md\nconcepts_and_terminology/MCP_SERVERS.md\nconcepts_and_terminology/PERFORMANCE_OPTIMIZATIONS.md\nconcepts_and_terminology/TROUBLESHOOTING.md\n\n# Coastfiles\ncoastfiles/README.md\ncoastfiles/PROJECT.md\ncoastfiles/WORKTREE_DIR.md\ncoastfiles/PORTS.md\ncoastfiles/SHARED_SERVICES.md\ncoastfiles/SERVICES.md\ncoastfiles/SECRETS.md\ncoastfiles/VOLUMES.md\ncoastfiles/ASSIGN.md\ncoastfiles/INHERITANCE.md\ncoastfiles/AGENT_SHELL.md\ncoastfiles/MCP.md\n\n# 레시피\nrecipes/README.md\nrecipes/FULLSTACK_MONOREPO.md\n", + "installation_prompt.txt": "이 프로젝트에 Coasts를 설치하고 있습니다. Coast(컨테이너화된 호스트)는 Docker-in-Docker 컨테이너를 사용해 단일 머신에서 여러 개의 격리된 개발 환경을 실행하는 CLI 도구입니다. 각 환경은 자체 포트, 볼륨, 런타임을 가지므로 병렬 worktree 워크플로에 이상적입니다.\n\n당신의 작업: 이 프로젝트를 분석하고 Coastfile(프로젝트 루트에 \"Coastfile\"이라는 이름의 TOML 파일)을 생성하세요.\n\n=== DOCUMENTATION ===\n\nCoast에는 CLI에서 접근 가능한 내장 문서가 있습니다. Coastfile 전체 스키마, 볼륨 전략, assign 동작, 기타 설정 옵션을 이해하기 위해 Coastfile을 생성하기 전에 이를 사용하세요.\n\n문서 트리를 탐색하세요:\n\n coast docs\n\n이는 전체 문서 트리를 출력합니다. README 파일부터 읽기 시작하세요 — 각 주제에 맞는 문서를 찾는 데 도움이 되는 인덱스를 제공합니다:\n\n coast docs --path README.md\n coast docs --path coastfiles/README.md\n coast docs --path concepts_and_terminology/README.md\n\n특정 문서를 읽으세요:\n\n coast docs --path coastfiles/PROJECT.md\n coast docs --path coastfiles/VOLUMES.md\n\n문서를 검색하세요(의미 기반 검색 — 찾고 있는 것을 자연어로 설명):\n\n coast search-docs \"how do volume strategies work\"\n coast search-docs \"shared postgres across instances\"\n coast search-docs \"secret injection from environment variables\"\n\n문서를 사용해 이 프로젝트의 Coastfile 구성에 대해 정보에 기반한 결정을 내리세요. coastfiles/ 섹션은 모든 Coastfile 지시어를 자세히 다룹니다.\n\n=== COASTFILE SCHEMA (quick reference) ===\n\n[coast] — 필수. 프로젝트 메타데이터.\n\n name (string, required) 컨테이너/볼륨 이름 지정에 사용되는 프로젝트 식별자.\n compose (string, optional) Coastfile 기준의 docker-compose.yml 상대 경로.\n runtime (string, optional) \"dind\"(기본값), \"sysbox\", 또는 \"podman\".\n root (string, optional) 프로젝트 루트 오버라이드(상대 또는 절대).\n worktree_dir (string or array, optional) git worktree를 위한 디렉터리 하나 또는 여러 개(기본값: \".worktrees\"). 단일 문자열 또는 문자열 배열을 받을 수 있습니다. 런타임에 기존 worktree에서 자동 감지됩니다.\n\n[coast.setup] — 선택. DinD 컨테이너 자체를 커스터마이즈.\n\n packages (array of strings) 설치할 Alpine 패키지(예: [\"nodejs\", \"npm\", \"git\"]).\n run (array of strings) 설정 중 실행할 임의의 명령.\n\n[ports] — 필수(최소 1개). 논리적 이름에서 포트 번호로의 맵.\n 이 포트들은 coast가 체크아웃될 때 호스트로 포워딩됩니다.\n\n 예시:\n [ports]\n web = 3000\n api = 8080\n postgres = 5432\n\n[volumes.*] — 선택. 볼륨별 구성.\n\n strategy \"isolated\"(기본값) 또는 \"shared\"\n service 이 볼륨을 소유하는 Compose 서비스 이름.\n mount 서비스 컨테이너 내부의 마운트 경로.\n snapshot_source (isolated 전용) 기존 볼륨 이름에서 시드.\n\n 예시:\n [volumes.postgres_data]\n strategy = \"isolated\"\n service = \"db\"\n mount = \"/var/lib/postgresql/data\"\n\n[secrets.*] — 선택. 시크릿 추출 및 주입.\n\n extractor \"file\", \"env\", \"command\", 또는 \"macos-keychain\"\n inject \"env:VAR_NAME\" 또는 \"file:/path/in/container\"\n ttl 선택적 만료(예: \"1h\", \"30m\").\n\n extractor별 파라미터:\n file: path = \"./path/to/secret\"\n env: var = \"HOST_ENV_VAR\"\n command: run = \"echo secret-value\"\n macos-keychain: item = \"keychain-item-name\"\n\n 예시:\n [secrets.db_password]\n extractor = \"env\"\n var = \"DB_PASSWORD\"\n inject = \"env:DATABASE_PASSWORD\"\n\n[inject] — 선택. 비시크릿 호스트 파일/환경변수 주입.\n\n env 포워딩할 호스트 환경변수 이름 배열.\n files 마운트할 호스트 파일 경로 배열.\n\n 예시:\n [inject]\n env = [\"NODE_ENV\", \"DEBUG\"]\n files = [\"~/.ssh/id_ed25519\", \"~/.gitconfig\"]\n\n[shared_services.*] — 선택. 인스턴스 간 공유되는 호스트 Docker 데몬의 서비스.\n\n image Docker 이미지.\n ports 포트 번호 배열.\n volumes 볼륨 마운트 배열.\n env 환경변수 인라인 테이블.\n auto_create_db (bool) 인스턴스별 데이터베이스를 자동으로 생성.\n inject coast 컨테이너에 연결 문자열을 주입.\n\n 예시:\n [shared_services.postgres]\n image = \"postgres:16-alpine\"\n ports = [5432]\n volumes = [\"postgres_data:/var/lib/postgresql/data\"]\n env = { POSTGRES_USER = \"dev\", POSTGRES_PASSWORD = \"dev\", POSTGRES_DB = \"app\" }\n auto_create_db = true\n inject = \"env:DATABASE_URL\"\n\n[assign] — 선택. 브랜치 전환 시(coast assign) 동작을 제어.\n\n default \"none\", \"restart\", 또는 \"rebuild\"\n [assign.services] 서비스별 오버라이드.\n [assign.rebuild_triggers] 서비스별 리빌드를 트리거하는 파일 글롭.\n\n 예시:\n [assign]\n default = \"none\"\n [assign.services]\n api = \"restart\"\n worker = \"rebuild\"\n [assign.rebuild_triggers]\n worker = [\"Dockerfile\", \"package.json\"]\n\n[services.*] — 선택. 베어 프로세스 서비스(docker-compose 불필요).\n\n command 실행할 셸 명령.\n port 포트 번호.\n restart \"on-failure\" 또는 \"always\".\n\n 예시:\n [services.web]\n command = \"node server.js\"\n port = 3000\n restart = \"on-failure\"\n\n=== EXAMPLE: Minimal (no compose) ===\n\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[ports]\napp = 3000\n\n=== EXAMPLE: With docker-compose ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\npostgres = 5432\nredis = 6379\n\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n\n=== EXAMPLE: With secrets ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\n\n[secrets.api_key]\nextractor = \"env\"\nvar = \"API_KEY\"\ninject = \"env:API_KEY\"\n\n[secrets.ssh_key]\nextractor = \"file\"\npath = \"~/.ssh/id_ed25519\"\ninject = \"file:/run/secrets/ssh_key\"\n\n=== KEY TRADEOFFS TO DISCUSS WITH THE USER ===\n\nCoastfile을 생성하기 전에 모호한 구성 선택에 대해 사용자에게 물어보세요. 주요 항목은 다음과 같습니다:\n\n데이터베이스 및 인프라 전략 — postgres와 redis 같은 서비스에 대해 세 가지 옵션이 있습니다:\n - 격리된 볼륨(기본값): 각 Coast 인스턴스는 DinD 컨테이너 내부에 자체 데이터 사본을 가집니다. 인스턴스들은 서로 간섭할 수 없습니다. 브랜치별 데이터베이스 상태가 필요할 때 최적입니다.\n - 공유 볼륨: 모든 인스턴스가 DinD 컨테이너 내부에서 동일한 볼륨을 읽고 씁니다. 디스크 공간을 절약하지만 여러 인스턴스의 동시 쓰기는 데이터를 손상시킬 수 있습니다.\n - 공유 서비스: 각 Coast 내부가 아니라 호스트 Docker 데몬에서 데이터베이스를 실행합니다. 모든 인스턴스가 하나의 공유 서버에 연결합니다. 메모리를 가장 적게 사용하고, 단일 postgres에서 인스턴스별 데이터베이스를 위한 auto_create_db를 지원하며, 데이터는 인스턴스 삭제 이후에도 유지됩니다. 대규모 팀 또는 메모리 제약이 있는 머신에 최적입니다.\n - 프로젝트에 데이터베이스가 있다면, 사용자가 어떤 접근을 원하는지 물어보세요. 트레이드오프를 설명하세요 — 격리가 가장 안전하고, 공유 서비스가 메모리 효율이 가장 좋습니다.\n\nAssign 전략 — Coast를 worktree 간 전환할 때 발생하는 일:\n - \"none\": 아무 것도 하지 않음(브랜치 간 변경이 없는 postgres/redis 같은 서비스에 적합).\n - \"restart\": 컨테이너 재시작(프로세스 재시작만 필요한 인터프리터 기반 서비스에 적합).\n - \"rebuild\": Docker 이미지를 재빌드하고 재시작(브랜치 변경이 Dockerfile 또는 빌드 의존성에 영향을 주는 서비스에 적합).\n - 프로젝트에 여러 서비스가 있다면, 브랜치 전환 시 어떤 서비스가 rebuild가 필요하고 어떤 서비스가 restart면 되는지 물어보세요.\n\n=== INSTRUCTIONS ===\n\n1. 이 프로젝트의 구조를 살펴보세요. docker-compose.yml이 있다면, 서비스를 식별하고 포트와 볼륨을 파악하기 위해 이를 읽으세요.\n2. 기존 git worktree 디렉터리를 감지하세요. `git worktree list`를 실행해 프로젝트에 이미 git worktree가 설정되어 있는지 확인하세요.\n - worktree가 존재한다면, 경로를 조사해 공통 부모 디렉터리를 결정하세요(예: worktree가 `../.worktrees/feat-a` 및 `../.worktrees/feat-b`에 있다면 worktree_dir는 `\"../.worktrees\"`).\n - 감지된 디렉터리와 일치하도록 Coastfile의 `worktree_dir`를 설정하세요.\n - worktree가 없다면 `worktree_dir`를 생략하세요(Coast 기본값은 \".worktrees\"). \".coasts\"를 사용하지 마세요 — 프로젝트에 Coast 브랜드 디렉터리를 만들어 오염시킵니다.\n3. 이 프로젝트에서 다음 코딩 하네스들 중 어떤 것을 사용하는지 사용자에게 물어보세요:\n - **Claude Code** — worktree 위치: `.claude/worktrees`\n - **OpenAI Codex** — worktree 위치: `~/.codex/worktrees`\n - **Cursor** — worktree 위치: `~/.cursor/worktrees/` (``은 `[coast] name`의 coast 이름)\n - **Conductor** — worktree 위치: `~/conductor/workspaces/`\n - **T3 Code** — worktree 위치: `~/.t3/worktrees/`\n 사용자가 선택한 각 하네스에 대해 해당 worktree 디렉터리를 `worktree_dir` 배열에 포함하세요. 이를 2단계에서 감지한 디렉터리와 결합하세요. 사용자가 아무것도 선택하지 않았고 2단계에서도 worktree가 감지되지 않았다면 `worktree_dir`를 생략하세요(Coast 기본값은 \".worktrees\").\n4. 관련 Coast 문서를 읽으세요(`coast docs` 및 `coast search-docs` 사용). 이 프로젝트 스택에 적용되는 볼륨 전략, assign 동작, 및 구성 옵션을 이해하세요.\n5. 모호한 구성 선택에 대해 사용자에게 물어보세요(위 트레이드오프 참조). 추측하지 마세요 — 옵션을 설명하고 사용자가 결정하게 하세요.\n6. 프로젝트 분석 및 사용자 입력을 바탕으로 프로젝트 루트에 Coastfile을 생성하세요.\n7. 프로젝트에 docker-compose.yml이 없다면, 베어 프로세스 정의에는 [services.*]를 사용하거나 의존성 설치에는 [coast.setup]을 사용하세요.\n8. `coast build`를 실행하세요. 실패하면 오류를 확인하고 문서(`coast search-docs \"\"`)를 참고하여 문제를 해결하세요.\n9. `coast run dev-1`을 실행하세요. 실패하면 오류를 확인하고 문서를 참고하세요.\n10. `coast ui`를 실행해 Coastguard 대시보드를 여세요(이 단계는 작업이 끝났을 때 사용자를 위한 것입니다).\n", + "skills_prompt.txt": "# Coast Runtime\n\n이 프로젝트는 서비스, 테스트 및 기타 런타임 명령을 실행하기 위해 Coasts — 컨테이너화된 런타임 — 를 사용합니다. 파일 시스템은 호스트와 컨테이너 사이에 공유되므로, 어느 쪽에서든 파일을 편집하면 양쪽에 즉시 반영됩니다.\n\n## Discovery\n\n세션에서 첫 번째 런타임 명령을 실행하기 전에 다음을 실행하세요:\n\n coast lookup\n\n이 명령은 인스턴스 이름, 포트, 예시 명령을 출력합니다. 이후의 모든 명령에는 출력에 나온 인스턴스 이름을 사용하세요.\n\n## What runs where\n\n파일 시스템은 공유되므로, 컨테이너 런타임(데이터베이스, 서비스, 통합 테스트)이 필요한 작업에만 `coast exec`를 사용하세요. 그 외의 모든 것은 호스트에서 직접 실행합니다.\n\n다음에는 `coast exec`를 사용하세요:\n- 실행 중인 서비스가 필요한 테스트(서비스나 DB와 통합된 단위 테스트, 통합 테스트, API 테스트)\n- 서비스 재시작 또는 compose 작업\n- 데이터베이스, 캐시 또는 기타 컨테이너 서비스와 통신하는 모든 작업\n\n다음은 호스트에서 직접 실행하세요:\n- 린팅, 타입체킹, 포매팅\n- Git 작업\n- Playwright 및 브라우저 테스트\n- 호스트 측 의존성 설치(npm install, pip install)\n- 파일 검색, 코드 생성, 정적 분석\n\n예시:\n\n coast exec -- sh -c \"cd && npm test\" # DB 필요\n coast exec --service # 서비스 셸\n npm run lint # 호스트에서 충분\n npx playwright test # 호스트에서 충분\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\n`coast lookup`이 일치하는 항목을 반환하지 않으면, 무엇이 있는지 보기 위해 `coast ls`를 실행하세요.\n\n이 프로젝트에 대해 아직 할당되지 않은 Coast가 이미 실행 중이라면, 새로 만드는 것보다 해당 Coast에 워크트리를 할당하는 것을 우선하세요:\n\n coast assign -w \n\n이미 사용 중인 Coast도 `coast assign`으로 재할당할 수 있지만, 현재 슬롯이 중단되므로 먼저 사용자에게 확인하세요.\n\n실행 중인 Coast가 없다면, 새로 만들기 전에 사용자에게 물어보세요 — Coasts는 메모리를 많이 사용할 수 있습니다:\n\n coast run -w \n\n인스턴스를 생성하려면 먼저 프로젝트가 빌드되어 있어야 합니다. 빌드가 없어서 `coast run`이 실패하면 먼저 `coast build`를 실행하세요.\n\n## Coastfile setup\n\n프로젝트에 아직 Coastfile이 없거나 Coastfile을 수정해야 한다면, 먼저 Coastfile 문서를 읽으세요:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nCoast 동작을 추측하기 전에 문서를 살펴보세요:\n\n coast docs # 모든 문서 페이지 나열\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # 시맨틱 검색\n\n## Rules\n\n- 세션에서 첫 번째 런타임 명령 전에 항상 `coast lookup`을 실행하세요.\n- 컨테이너 런타임이 필요한 작업에만 `coast exec`를 사용하세요.\n- 앱/서비스 컨테이너 내부에서 실행해야 할 때는 `coast exec --service `를 사용하세요.\n- 린팅, 타입체킹, 포매팅, git은 호스트에서 직접 실행하세요.\n- Coast 동작을 추측하기 전에 `coast docs` 또는 `coast search-docs`를 사용하세요.\n- 프로젝트가 Coast를 기대하는 경우 호스트에서 서비스를 직접 실행하지 마세요.\n\n---\nname: coasts\ndescription: 현재 체크아웃에 대한 Coast 인스턴스를 검사하고 제어합니다. 사용자가 \"/coasts\"라고 말하거나, Coast를 할당 또는 재할당해 달라고 요청하거나, 일치하는 Coast에서 명령 실행 또는 로그 읽기를 원하거나, 새 Coast를 만들고 싶어 하거나, Coast UI를 열어 달라고 명시적으로 요청할 때 사용합니다.\n---\n\n# Coasts\n\nCoast CLI를 직접 사용하세요. 래퍼를 추가하지 마세요.\n\n## Orient Yourself\n\n먼저 CLI와 문서를 살펴보세요:\n\n coast # 사용 가능한 모든 명령 보기\n coast docs # 모든 문서 페이지 나열\n coast search-docs \"your question\" # 시맨틱 검색\n\nCoast 동작과 관련해 불분명한 점이 있으면, 추측하기 전에 문서를 읽으세요:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\n요청을 다음 모드 중 하나로 분기하세요:\n\n1. **Use Coast** — `coast lookup`을 실행한 다음, 일치하는 인스턴스에 대해 `coast exec`, `coast ps`, 또는 `coast logs`를 사용합니다.\n2. **Create or Assign** — `coast ls`를 실행한 다음, `coast run`으로 새 Coast를 만들거나 `coast assign`으로 기존 Coast가 가리키는 대상을 변경합니다.\n3. **Open UI** — `coast ui`를 실행합니다.\n\n## What Runs Where\n\n호스트와 Coast는 파일 시스템을 공유합니다. 컨테이너 내부에서 실행 중인 서비스가 필요한 작업에만 `coast exec`를 사용하세요.\n\n**다음에는 `coast exec`를 사용하세요:**\n- 통합 테스트, API 테스트, 데이터베이스나 서비스가 필요한 모든 작업\n- 서비스 재시작, compose 작업\n- 컨테이너에서만 실행되는 프로세스와 통신하는 명령\n\n**다음은 호스트에서 실행하세요:**\n- 린팅 (`eslint`, `rubocop`, `golangci-lint`)\n- 타입체킹 (`tsc --noEmit`, `go vet`)\n- 포매팅 (`prettier`, `gofmt`)\n- Git 작업\n- Playwright 및 브라우저 테스트\n- 정적 분석, 코드 생성\n- 패키지 설치 (`npm install`, `pip install`)\n\n## Create and Assign\n\n`coast lookup`이 일치하는 항목을 반환하지 않을 때:\n\n1. 사용 가능한 슬롯을 보기 위해 `coast ls`를 실행하세요.\n2. 한 번에 생성하고 할당하려면 `coast run -w `를 우선 사용하세요.\n3. 아직 빌드가 없다면 먼저 `coast build`를 실행하세요.\n4. 생성 후 확인을 위해 `coast lookup`을 다시 실행하세요.\n\n기존 Coast를 다른 워크트리로 전환하려는 경우:\n\n coast assign -w \n\n이 방법은 이미 할당되었거나 체크아웃된 Coast에도 동작하지만, 사용 중인 슬롯을 재할당하기 전에는 먼저 사용자에게 물어보세요.\n\n## Coastfile Setup\n\n프로젝트에 새 Coastfile이 필요하거나 기존 Coastfile을 수정해야 한다면, 먼저 문서를 읽으세요:\n\n coast docs --path coastfiles/README.md\n\nCoastfile 문서에는 compose 설정, 포트, 볼륨, 시크릿, 공유 서비스, bare 서비스, 상속이 포함되어 있습니다.\n\n## Safety Rules\n\n- 조치를 취하기 전에 `coast lookup`을 실행하고, 토폴로지가 변경된 후에도 다시 실행하세요.\n- `coast assign`, `coast unassign`, 또는 `coast checkout`이 기존 슬롯을 방해하게 된다면 먼저 물어보세요.\n- 사용자가 기존 슬롯의 재할당을 명시적으로 원하지 않는 한, 체크아웃되었거나 이미 할당된 Coast를 재사용하는 것보다 새 Coast를 만드는 것을 우선하세요.\n- 추측하기 전에 `coast docs` 또는 `coast search-docs`를 사용하세요.\n", "coastfiles/README.md": "# Coastfiles\n\nCoastfile은 프로젝트 루트에 위치하는 TOML 구성 파일입니다. 이 파일은 해당 프로젝트를 위한 격리된 개발 환경을 빌드하고 실행하는 데 Coast가 알아야 하는 모든 정보를 알려줍니다 — 어떤 서비스를 실행할지, 어떤 포트를 포워딩할지, 데이터를 어떻게 처리할지, 시크릿을 어떻게 관리할지 등을 포함합니다.\n\n모든 Coast 프로젝트에는 최소 하나의 Coastfile이 필요합니다. 파일 이름은 항상 `Coastfile`입니다(대문자 C, 확장자 없음). 서로 다른 워크플로를 위한 변형이 필요하다면, `Coastfile.light` 또는 `Coastfile.snap`처럼 타입이 지정된 Coastfile을 만들고 [기본 파일을 상속](INHERITANCE.md)할 수 있습니다.\n\nCoastfile이 Coast의 나머지 부분과 어떤 관계인지 더 깊이 이해하려면 [Coasts](../concepts_and_terminology/COASTS.md) 및 [Builds](../concepts_and_terminology/BUILDS.md)를 참고하세요.\n\n## Quickstart\n\n가장 작은 형태의 Coastfile:\n\n```toml\n[coast]\nname = \"my-app\"\n```\n\n이렇게 하면 `coast exec`으로 들어갈 수 있는 DinD 컨테이너가 제공됩니다. 대부분의 프로젝트는 `compose` 참조 또는 [bare services](SERVICES.md) 중 하나를 원할 것입니다:\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\napi = 8080\n```\n\n또는 compose 없이 bare services를 사용하는 경우:\n\n```toml\n[coast]\nname = \"my-app\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\nrestart = \"on-failure\"\n\n[ports]\nweb = 3000\n```\n\n`coast build`를 실행한 다음 `coast run dev-1`을 실행하면 격리된 환경이 준비됩니다.\n\n## Example Coastfiles\n\n### Simple bare-service project\n\ncompose 파일이 없는 Next.js 앱입니다. Coast가 Node를 설치하고, `npm install`을 실행한 다음, 개발 서버를 직접 시작합니다.\n\n```toml\n[coast]\nname = \"my-crm\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --turbopack --port 3002 --hostname 0.0.0.0\"\nport = 3002\nrestart = \"on-failure\"\n\n[ports]\nweb = 3002\n```\n\n### Full-stack compose project\n\n공유 데이터베이스, 시크릿, 볼륨 전략, 사용자 정의 설정을 갖춘 멀티 서비스 프로젝트입니다.\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./infra/docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"python3\", \"curl\", \"git\", \"bash\", \"ca-certificates\", \"wget\"]\nrun = [\n \"ARCH=$(uname -m | sed 's/aarch64/arm64/' | sed 's/x86_64/amd64/') && wget -qO /tmp/go.tar.gz https://go.dev/dl/go1.24.1.linux-${ARCH}.tar.gz && tar -C /usr/local -xzf /tmp/go.tar.gz && rm /tmp/go.tar.gz\",\n \"GOBIN=/usr/local/bin go install github.com/air-verse/air@v1.61.7\",\n]\n\n[ports]\nweb = 3000\nbackend = 8080\npostgres = 5432\nredis = 6379\n\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\" }\n\n[shared_services.redis]\nimage = \"redis:7\"\nports = [6379]\n\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n\n[secrets.db_password]\nextractor = \"env\"\nvar = \"DB_PASSWORD\"\ninject = \"env:DB_PASSWORD\"\n\n[omit]\nservices = [\"monitoring\", \"admin-panel\", \"nginx-proxy\"]\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### Lightweight test variant (inheritance)\n\n기본 Coastfile을 확장하지만 백엔드 테스트 실행에 필요한 것만 남기도록 축소한 버전입니다. 포트도 없고, 공유 서비스도 없으며, 데이터베이스는 격리됩니다.\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n\n[unset]\nports = [\"web\", \"backend\", \"postgres\", \"redis\"]\nshared_services = [\"postgres\", \"redis\"]\n\n[omit]\nservices = [\"redis\", \"backend\", \"web\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend-test = \"rebuild\"\n```\n\n### Snapshot-seeded variant\n\n각 coast 인스턴스는 호스트의 기존 데이터베이스 볼륨 복사본으로 시작한 뒤, 이후에는 독립적으로 분기됩니다.\n\n```toml\n[coast]\nextends = \"Coastfile\"\n\n[unset]\nshared_services = [\"postgres\", \"redis\", \"mongodb\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_mongodb_data\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n\n## Conventions\n\n- 파일 이름은 반드시 `Coastfile`이어야 하며(대문자 C, 확장자 없음), 프로젝트 루트에 위치해야 합니다.\n- 타입이 지정된 변형은 `Coastfile.{type}` 패턴을 사용합니다 — 예: `Coastfile.light`, `Coastfile.snap`. [Inheritance and Types](INHERITANCE.md)를 참고하세요.\n- 예약된 이름 `Coastfile.default`는 허용되지 않습니다.\n- 전체적으로 TOML 문법을 사용합니다. 모든 섹션 헤더는 `[brackets]`를 사용하고, 이름 있는 항목은 `[section.name]`을 사용합니다(array-of-tables 아님).\n- 같은 Coastfile에서 `compose`와 `[services]`를 동시에 사용할 수 없습니다 — 하나를 선택하세요.\n- 상대 경로(`compose`, `root` 등)는 Coastfile의 상위 디렉터리를 기준으로 해석됩니다.\n\n## Reference\n\n| Page | Sections | What it covers |\n|------|----------|----------------|\n| [Project and Setup](PROJECT.md) | `[coast]`, `[coast.setup]` | 이름, compose 경로, 런타임, worktree 디렉터리, 컨테이너 설정 |\n| [Worktree Directories](WORKTREE_DIR.md) | `worktree_dir`, `default_worktree_dir` | 로컬 및 외부 worktree 디렉터리, 틸드 경로, Codex/Claude 통합 |\n| [Ports](PORTS.md) | `[ports]`, `[egress]` | 포트 포워딩, egress 선언, 기본 포트 |\n| [Volumes](VOLUMES.md) | `[volumes.*]` | 격리, 공유, 스냅샷 시드 볼륨 전략 |\n| [Shared Services](SHARED_SERVICES.md) | `[shared_services.*]` | 호스트 수준 데이터베이스 및 인프라 서비스 |\n| [Secrets](SECRETS.md) | `[secrets.*]`, `[inject]` | 시크릿 추출, 주입, 호스트 env/file 포워딩 |\n| [Bare Services](SERVICES.md) | `[services.*]` | Docker Compose 없이 프로세스를 직접 실행 |\n| [Agent Shell](AGENT_SHELL.md) | `[agent_shell]` | 컨테이너화된 에이전트 TUI 런타임 |\n| [MCP Servers](MCP.md) | `[mcp.*]`, `[mcp_clients.*]` | 내부 및 호스트 프록시 MCP 서버, 클라이언트 커넥터 |\n| [Assign](ASSIGN.md) | `[assign]` | 서비스별 브랜치 전환 동작 |\n| [Inheritance and Types](INHERITANCE.md) | `extends`, `includes`, `[unset]`, `[omit]` | 타입이 지정된 Coastfile, 조합, 오버라이드 |\n", "coastfiles/AGENT_SHELL.md": "# 에이전트 셸\n\n> **대부분의 워크플로우에서는 코딩 에이전트를 컨테이너화할 필요가 없습니다.** Coast는 호스트 머신과 [파일시스템](../concepts_and_terminology/FILESYSTEM.md)을 공유하므로, 가장 간단한 접근은 호스트에서 에이전트를 실행하고 통합 테스트 같은 런타임이 무거운 작업에는 [`coast exec`](../concepts_and_terminology/EXEC_AND_DOCKER.md)를 사용하는 것입니다. 에이전트 셸은 에이전트가 컨테이너 내부에서 실행되기를 특별히 원하는 경우를 위한 것입니다 — 예를 들어 내부 Docker 데몬에 직접 접근하게 하거나, 환경을 완전히 격리하기 위해서입니다.\n\n`[agent_shell]` 섹션은 Claude Code 또는 Codex 같은 에이전트 TUI가 Coast 컨테이너 내부에서 실행되도록 구성합니다. 이 섹션이 존재하면, Coast는 인스턴스가 시작될 때 구성된 명령을 실행하는 영구 PTY 세션을 자동으로 생성합니다.\n\n에이전트 셸이 어떻게 동작하는지 전체 그림 — 활성 에이전트 모델, 입력 전송, 라이프사이클 및 복구 — 은 [에이전트 셸](../concepts_and_terminology/AGENT_SHELLS.md)을 참고하세요.\n\n## 구성\n\n이 섹션에는 필수 필드가 하나 있습니다: `command`.\n\n```toml\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\n### `command` (필수)\n\n에이전트 PTY에서 실행할 셸 명령입니다. 이는 일반적으로 `[coast.setup]`을 통해 설치한 코딩 에이전트 CLI입니다.\n\n이 명령은 DinD 컨테이너 내부의 `/workspace`(프로젝트 루트)에서 실행됩니다. 이는 compose 서비스가 아닙니다 — compose 스택 또는 단독 서비스들과 나란히 실행되며, 그 안에서 실행되는 것이 아닙니다.\n\n## 라이프사이클\n\n- 에이전트 셸은 `coast run` 시 자동으로 생성됩니다.\n- [Coastguard](../concepts_and_terminology/COASTGUARD.md)에서는 닫을 수 없는 영구적인 \"Agent\" 탭으로 표시됩니다.\n- 에이전트 프로세스가 종료되면, Coast가 이를 다시 생성(respawn)할 수 있습니다.\n- `coast agent-shell input`을 통해 실행 중인 에이전트 셸로 입력을 전송할 수 있습니다.\n\n## 예시\n\n### Claude Code\n\n`[coast.setup]`에서 Claude Code를 설치하고, [secrets](SECRETS.md)를 통해 자격 증명을 구성한 다음, 에이전트 셸을 설정합니다:\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"git\", \"bash\"]\nrun = [\n \"npm install -g @anthropic-ai/claude-code\",\n \"mkdir -p /root/.claude\",\n]\n\n[secrets.claude_credentials]\nextractor = \"keychain\"\nservice = \"Claude Code-credentials\"\ninject = \"file:/root/.claude/.credentials.json\"\n\n[agent_shell]\ncommand = \"cd /workspace; exec claude --dangerously-skip-permissions --effort high\"\n```\n\n### 간단한 에이전트 셸\n\n기능이 동작하는지 테스트하기 위한 최소 에이전트 셸:\n\n```toml\n[coast]\nname = \"test-agent\"\n\n[coast.setup]\npackages = [\"bash\"]\n\n[agent_shell]\ncommand = \"exec sh -c 'while true; do echo agent-heartbeat; sleep 5; done'\"\n```\n", "coastfiles/ASSIGN.md": "# Assign\n\n`[assign]` 섹션은 `coast assign`로 브랜치를 전환할 때 Coast 인스턴스 내부의 서비스에 어떤 일이 일어나는지를 제어합니다. 각 서비스는 전체 재빌드, 재시작, 핫 리로드, 또는 아무 작업도 하지 않음 중 무엇이 필요한지에 따라 서로 다른 전략으로 구성할 수 있습니다.\n\n런타임에서 `coast assign` 및 `coast unassign`이 어떻게 동작하는지에 대해서는 [Assign](../concepts_and_terminology/ASSIGN.md)를 참고하세요.\n\n## `[assign]`\n\n### `default`\n\n브랜치 전환 시 모든 서비스에 적용되는 기본 동작입니다. 전체 `[assign]` 섹션이 생략되면 기본값은 `\"restart\"`입니다.\n\n- **`\"none\"`** — 아무 것도 하지 않습니다. 서비스는 현재 상태로 계속 실행됩니다. 코드에 의존하지 않는 데이터베이스와 캐시에 적합합니다.\n- **`\"hot\"`** — 코드는 [filesystem](../concepts_and_terminology/FILESYSTEM.md)을 통해 이미 라이브 마운트되어 있으므로, 서비스가 변경 사항을 자동으로 반영합니다(예: 파일 감시자 또는 핫 리로드를 통해). 컨테이너 재시작이 필요 없습니다.\n- **`\"restart\"`** — 서비스 컨테이너를 재시작합니다. 서비스가 시작 시 코드를 읽지만 전체 이미지 재빌드는 필요하지 않을 때 사용하세요.\n- **`\"rebuild\"`** — 서비스의 Docker 이미지를 재빌드하고 재시작합니다. Dockerfile에서 `COPY` 또는 `ADD`로 코드가 이미지에 포함(bake)되는 경우 필요합니다.\n\n```toml\n[assign]\ndefault = \"none\"\n```\n\n### `[assign.services]`\n\n서비스별 재정의입니다. 각 키는 compose 서비스 이름이고, 값은 위 네 가지 동작 중 하나입니다.\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\n이를 통해 데이터베이스와 캐시는 그대로 두고(기본값으로 `\"none\"`), 변경된 코드에 의존하는 서비스만 재빌드하거나 재시작할 수 있습니다.\n\n### `[assign.rebuild_triggers]`\n\n기본 동작이 더 가벼운 경우라도, 특정 서비스에 대해 재빌드를 강제하는 파일 패턴입니다. 각 키는 서비스 이름이며, 값은 파일 경로 또는 패턴의 목록입니다.\n\n```toml\n[assign]\ndefault = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\", \"package-lock.json\"]\n```\n\n### `exclude_paths`\n\n`coast assign` 중 worktree 동기화에서 제외할 경로 목록입니다. 큰 모노레포에서 특정 디렉터리가 Coast에서 실행 중인 서비스와 무관하여, 그렇지 않으면 assign 작업을 느리게 만들 수 있을 때 유용합니다.\n\n```toml\n[assign]\ndefault = \"none\"\nexclude_paths = [\"apps/ide\", \"apps/extension\", \"apps/ide-extension\"]\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n## Examples\n\n### 앱을 재빌드하고, 나머지는 모두 그대로 두기\n\napp 서비스가 코드를 Docker 이미지에 포함(bake)하지만 데이터베이스는 코드 변경과 독립적일 때:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\n### 프론트엔드와 백엔드 핫 리로드\n\n두 서비스 모두 파일 감시자(예: Next.js dev server, Go air, nodemon)를 사용하고 코드가 라이브 마운트되어 있을 때:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### 트리거를 사용한 서비스별 재빌드\n\nAPI 서비스는 보통 재시작만 하지만, `Dockerfile` 또는 `package.json`이 변경되면 재빌드합니다:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napi = \"restart\"\nworker = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\"]\n```\n\n### 모든 것을 전체 재빌드\n\n모든 서비스가 코드를 이미지에 포함(bake)할 때:\n\n```toml\n[assign]\ndefault = \"rebuild\"\n```\n", @@ -1598,19 +1627,19 @@ "coastfiles/SERVICES.md": "# 베어 서비스\n\n> **참고:** 베어 서비스는 Coast 컨테이너 내부에서 일반 프로세스로 직접 실행되며 — 컨테이너화되지 않습니다. 서비스가 이미 Docker로 컨테이너화되어 있다면 대신 `compose`를 사용하세요. 베어 서비스는 Dockerfile과 docker-compose.yml을 작성하는 오버헤드를 건너뛰고 싶은 단순한 구성에 가장 적합합니다.\n\n`[services.*]` 섹션은 Coast가 Docker Compose 없이 DinD 컨테이너 내부에서 직접 실행하는 프로세스를 정의합니다. 이는 `compose` 파일을 사용하는 것의 대안이며 — 동일한 Coastfile에서 둘 다 사용할 수는 없습니다.\n\n베어 서비스는 로그 캡처와 선택적 재시작 정책을 포함해 Coast가 감독합니다. 베어 서비스가 어떻게 동작하는지, 그 한계, 그리고 언제 compose로 마이그레이션해야 하는지에 대한 더 깊은 배경은 [Bare Services](../concepts_and_terminology/BARE_SERVICES.md)를 참고하세요.\n\n## 서비스 정의하기\n\n각 서비스는 `[services]` 아래의 이름이 있는 TOML 섹션입니다. `command` 필드는 필수입니다.\n\n```toml\n[services.web]\ncommand = \"node server.js\"\nport = 3000\n```\n\n### `command` (필수)\n\n실행할 셸 명령입니다. 비어 있거나 공백만으로 구성되어서는 안 됩니다.\n\n```toml\n[services.web]\ncommand = \"npx next dev --turbopack --port 3000 --hostname 0.0.0.0\"\n```\n\n### `port`\n\n서비스가 수신하는 포트입니다. 헬스 체크 및 포트 포워딩 통합에 사용됩니다. 지정하는 경우 0이 아니어야 합니다.\n\n```toml\n[services.web]\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\n```\n\n### `restart`\n\n프로세스가 종료될 경우의 재시작 정책입니다. 기본값은 `\"no\"`입니다.\n\n- `\"no\"` — 재시작하지 않음\n- `\"on-failure\"` — 프로세스가 0이 아닌 코드로 종료될 때만 재시작\n- `\"always\"` — 항상 재시작\n\n```toml\n[services.web]\ncommand = \"node server.js\"\nport = 3000\nrestart = \"on-failure\"\n```\n\n### `install`\n\n서비스를 시작하기 전에 실행할 명령(예: 의존성 설치)입니다. 단일 문자열 또는 문자열 배열을 받을 수 있습니다.\n\n```toml\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\n```\n\n```toml\n[services.web]\ninstall = [\"npm install\", \"npm run build\"]\ncommand = \"npm start\"\nport = 3000\n```\n\n## compose와의 상호 배타성\n\nCoastfile은 `compose`와 `[services]`를 동시에 정의할 수 없습니다. `[coast]`에 `compose` 필드가 있다면, 어떤 `[services.*]` 섹션을 추가하는 것도 오류입니다. Coastfile마다 한 가지 접근 방식을 선택하세요.\n\n일부 서비스는 compose로 컨테이너화하고 일부는 베어로 실행해야 한다면, 모두에 대해 compose를 사용하세요 — 베어 서비스에서 compose로 이동하는 방법은 [Bare Services의 마이그레이션 가이드](../concepts_and_terminology/BARE_SERVICES.md)를 참고하세요.\n\n## 예시\n\n### 단일 서비스 Next.js 앱\n\n```toml\n[coast]\nname = \"my-frontend\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --turbopack --port 3002 --hostname 0.0.0.0\"\nport = 3002\nrestart = \"on-failure\"\n\n[ports]\nweb = 3002\n```\n\n### 백그라운드 워커가 있는 웹 서버\n\n```toml\n[coast]\nname = \"my-app\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"node server.js\"\nport = 3000\nrestart = \"on-failure\"\n\n[services.worker]\ncommand = \"node worker.js\"\nrestart = \"always\"\n\n[ports]\nweb = 3000\n```\n\n### 다단계 설치가 있는 Python 서비스\n\n```toml\n[coast]\nname = \"ml-service\"\n\n[coast.setup]\npackages = [\"python3\", \"py3-pip\"]\n\n[services.api]\ninstall = [\"pip install -r requirements.txt\", \"python manage.py migrate\"]\ncommand = \"python manage.py runserver 0.0.0.0:8000\"\nport = 8000\nrestart = \"on-failure\"\n\n[ports]\napi = 8000\n```\n", "coastfiles/SHARED_SERVICES.md": "# Shared Services\n\n`[shared_services.*]` 섹션은 개별 Coast 컨테이너 내부가 아니라 호스트 Docker 데몬에서 실행되는 인프라 서비스(데이터베이스, 캐시, 메시지 브로커)를 정의합니다. 여러 Coast 인스턴스가 브리지 네트워크를 통해 동일한 공유 서비스에 연결합니다.\n\n런타임에서 공유 서비스가 동작하는 방식, 라이프사이클 관리, 문제 해결에 대해서는 [Shared Services](../concepts_and_terminology/SHARED_SERVICES.md)를 참고하세요.\n\n## Defining a shared service\n\n각 공유 서비스는 `[shared_services]` 아래의 이름이 있는 TOML 섹션입니다. `image` 필드는 필수이며, 그 외는 모두 선택 사항입니다.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\n```\n\n### `image` (required)\n\n호스트 데몬에서 실행할 Docker 이미지입니다.\n\n### `ports`\n\n서비스가 노출하는 포트 목록입니다. Coast는 컨테이너 포트만 지정하는 형식과 Docker Compose 스타일의 `\"HOST:CONTAINER\"` 매핑 형식을 모두 허용합니다.\n\n```toml\n[shared_services.redis]\nimage = \"redis:7-alpine\"\nports = [6379]\n```\n\n```toml\n[shared_services.postgis]\nimage = \"ghcr.io/baosystems/postgis:12-3.3\"\nports = [\"5433:5432\"]\n```\n\n- `6379` 같은 정수만 있는 값은 `\"6379:6379\"`의 축약형입니다.\n- `\"5433:5432\"` 같은 매핑 문자열은 공유 서비스를 호스트 포트 `5433`에 게시하면서, Coast 내부에서는 `service-name:5432`로 계속 접근 가능하게 합니다.\n- 호스트 포트와 컨테이너 포트는 둘 다 0이 아니어야 합니다.\n\n### `volumes`\n\n데이터 영속성을 위한 Docker 볼륨 바인드 문자열입니다. 이는 Coast가 관리하는 볼륨이 아니라 호스트 수준의 Docker 볼륨입니다.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\n```\n\n### `env`\n\n서비스 컨테이너에 전달되는 환경 변수입니다.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\", POSTGRES_DB = \"mydb\" }\n```\n\n### `auto_create_db`\n\n`true`인 경우, Coast는 각 Coast 인스턴스마다 공유 서비스 내부에 인스턴스별 데이터베이스를 자동으로 생성합니다. 기본값은 `false`입니다.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\nauto_create_db = true\n```\n\n### `inject`\n\n공유 서비스 연결 정보를 환경 변수 또는 파일로 Coast 인스턴스에 주입합니다. [secrets](SECRETS.md)와 동일한 `env:NAME` 또는 `file:/path` 형식을 사용합니다.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\ninject = \"env:DATABASE_URL\"\n```\n\n## Lifecycle\n\n공유 서비스는 이를 참조하는 첫 번째 Coast 인스턴스가 실행될 때 자동으로 시작됩니다. 또한 `coast stop` 및 `coast rm` 이후에도 계속 실행됩니다 — 인스턴스를 제거해도 공유 서비스 데이터에는 영향이 없습니다. 오직 `coast shared rm`만 공유 서비스를 중지하고 제거합니다.\n\n`auto_create_db`로 생성된 인스턴스별 데이터베이스도 인스턴스 삭제 후에도 유지됩니다. 서비스와 그 데이터를 완전히 제거하려면 `coast shared-services rm`을 사용하세요.\n\n## When to use shared services vs volumes\n\n여러 Coast 인스턴스가 동일한 데이터베이스 서버와 통신해야 할 때 공유 서비스를 사용하세요(예: 각 인스턴스가 자체 데이터베이스를 받는 공유 Postgres). compose 내부 서비스의 데이터를 공유하거나 격리하는 방식을 제어하려면 [volume strategies](VOLUMES.md)를 사용하세요.\n\n## Examples\n\n### Postgres, Redis, and MongoDB\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\", POSTGRES_MULTIPLE_DATABASES = \"dev_db,test_db\" }\n\n[shared_services.redis]\nimage = \"redis:7\"\nports = [6379]\nvolumes = [\"infra_redis_data:/data\"]\n\n[shared_services.mongodb]\nimage = \"mongo:latest\"\nports = [27017]\nvolumes = [\"infra_mongodb_data:/data/db\"]\nenv = { MONGO_INITDB_ROOT_USERNAME = \"myapp\", MONGO_INITDB_ROOT_PASSWORD = \"myapp_pass\" }\n```\n\n### Minimal shared Postgres\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16-alpine\"\nports = [5432]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\", POSTGRES_DB = \"coast_demo\" }\n```\n\n### Host/container mapped shared Postgres\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16-alpine\"\nports = [\"5433:5432\"]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\", POSTGRES_DB = \"coast_demo\" }\n```\n\n### Shared services with auto-created databases\n\n```toml\n[shared_services.db]\nimage = \"postgres:16-alpine\"\nports = [5432]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\" }\nauto_create_db = true\n```\n", "coastfiles/VOLUMES.md": "# 볼륨\n\n`[volumes.*]` 섹션은 명명된 Docker 볼륨이 Coast 인스턴스 전반에서 어떻게 처리되는지 제어합니다. 각 볼륨은 인스턴스가 데이터를 공유할지, 아니면 각자 독립적인 복사본을 가질지를 결정하는 전략으로 구성됩니다.\n\n공유 서비스라는 대안을 포함해 Coast에서의 데이터 격리에 대한 더 큰 그림은 [Volumes](../concepts_and_terminology/VOLUMES.md)를 참고하세요.\n\n## 볼륨 정의하기\n\n각 볼륨은 `[volumes]` 아래의 이름이 있는 TOML 섹션입니다. 세 가지 필드가 필요합니다:\n\n- **`strategy`** — `\"isolated\"` 또는 `\"shared\"`\n- **`service`** — 이 볼륨을 사용하는 compose 서비스 이름\n- **`mount`** — 볼륨의 컨테이너 마운트 경로\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## 전략\n\n### `isolated`\n\n각 Coast 인스턴스는 자체적으로 독립된 볼륨을 가집니다. 데이터는 인스턴스 간에 공유되지 않습니다. 볼륨은 `coast run` 시 생성되고 `coast rm` 시 삭제됩니다.\n\n```toml\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n```\n\n대부분의 데이터베이스 볼륨에는 이것이 올바른 선택입니다 — 각 인스턴스는 깨끗한 초기 상태에서 시작하며 다른 인스턴스에 영향을 주지 않고 자유롭게 데이터를 변경할 수 있습니다.\n\n### `shared`\n\n모든 Coast 인스턴스가 단일 Docker 볼륨을 사용합니다. 한 인스턴스가 기록한 모든 데이터는 다른 모든 인스턴스에서 볼 수 있습니다.\n\n```toml\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n```\n\n공유 볼륨은 `coast rm`에 의해 절대 삭제되지 않습니다. 수동으로 제거할 때까지 유지됩니다.\n\nCoast는 데이터베이스 같은 서비스에 연결된 볼륨에서 `shared`를 사용하면 빌드 시 경고를 출력합니다. 하나의 데이터베이스 볼륨을 여러 동시 인스턴스가 공유하면 손상이 발생할 수 있습니다. 공유 데이터베이스가 필요하다면 대신 [shared services](SHARED_SERVICES.md)를 사용하세요.\n\n공유 볼륨의 좋은 사용처: 의존성 캐시(Go modules, npm cache, pip cache), 빌드 산출물 캐시, 그리고 동시 쓰기가 안전하거나 발생 가능성이 낮은 기타 데이터.\n\n## 스냅샷 시딩\n\n격리된 볼륨은 `snapshot_source`를 사용해 인스턴스 생성 시 기존 Docker 볼륨에서 시딩될 수 있습니다. 소스 볼륨의 데이터가 새로운 격리 볼륨으로 복사되며, 이후에는 독립적으로 분기됩니다.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n`snapshot_source`는 `strategy = \"isolated\"`에서만 유효합니다. 공유 볼륨에 설정하면 오류입니다.\n\n이는 각 Coast 인스턴스가 호스트 개발 데이터베이스에서 복사한 현실적인 데이터셋으로 시작하길 원하지만, 인스턴스들이 소스나 서로에게 영향을 주지 않고 해당 데이터를 자유롭게 변경할 수 있어야 할 때 유용합니다.\n\n## 예시\n\n### 격리된 데이터베이스, 공유 의존성 캐시\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n```\n\n### 스냅샷으로 시딩된 풀 스택\n\n각 인스턴스는 호스트에 존재하는 데이터베이스 볼륨의 복사본으로 시작한 뒤, 독립적으로 분기합니다.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_mongodb_data\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n\n### 인스턴스별로 깨끗한 데이터베이스를 사용하는 테스트 러너\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"test-redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n", - "coastfiles/WORKTREE_DIR.md": "# 워크트리 디렉터리\n\n`[coast]`의 `worktree_dir` 필드는 git 워크트리가 위치할 곳을 제어합니다. Coast는 git 워크트리를 사용하여 전체 저장소를 복제하지 않고도 각 인스턴스가 서로 다른 브랜치에서 코드베이스의 자체 복사본을 갖도록 합니다.\n\n## 구문\n\n`worktree_dir`는 단일 문자열 또는 문자열 배열을 받을 수 있습니다:\n\n```toml\n# Single directory (default)\nworktree_dir = \".worktrees\"\n\n# Multiple directories\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\n생략하면 기본값은 `\".worktrees\"`입니다.\n\n## 경로 유형\n\n### 상대 경로\n\n`~/` 또는 `/`로 시작하지 않는 경로는 프로젝트 루트를 기준으로 해석됩니다. 이것이 가장 일반적인 경우이며 별도의 특별한 처리가 필요 없습니다 — 프로젝트 디렉터리 내부에 있으므로 표준 `/host-project` 바인드 마운트를 통해 Coast 컨테이너 내부에서 자동으로 사용할 수 있습니다.\n\n```toml\nworktree_dir = \".worktrees\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### 물결표 경로(외부)\n\n`~/`로 시작하는 경로는 사용자의 홈 디렉터리로 확장되며 **외부** 워크트리 디렉터리로 취급됩니다. Coast는 컨테이너가 해당 경로에 접근할 수 있도록 별도의 바인드 마운트를 추가합니다.\n\n```toml\nworktree_dir = [\"~/.codex/worktrees\", \".worktrees\"]\n```\n\n이것은 OpenAI Codex처럼 프로젝트 루트 외부에 워크트리를 생성하는 도구와 통합하는 방법입니다(Codex는 항상 `$CODEX_HOME/worktrees`에 워크트리를 생성합니다).\n\n### 절대 경로(외부)\n\n`/`로 시작하는 경로도 외부로 취급되며 자체 바인드 마운트를 갖습니다.\n\n```toml\nworktree_dir = [\"/shared/worktrees\", \".worktrees\"]\n```\n\n## 외부 디렉터리가 작동하는 방식\n\nCoast가 외부 워크트리 디렉터리(물결표 또는 절대 경로)를 만나면 세 가지 일이 발생합니다:\n\n1. **컨테이너 바인드 마운트** — 컨테이너 생성 시점(`coast run`)에 해석된 호스트 경로가 `/host-external-wt/{index}`에 바인드 마운트되며, 여기서 `{index}`는 `worktree_dir` 배열에서의 위치입니다. 이렇게 하면 컨테이너 내부에서 외부 파일에 접근할 수 있습니다.\n\n2. **프로젝트 필터링** — 외부 디렉터리에는 여러 프로젝트의 워크트리가 포함될 수 있습니다. Coast는 `git worktree list --porcelain`(본질적으로 현재 저장소 범위로 제한됨)을 사용하여 이 프로젝트에 속한 워크트리만 찾습니다. git watcher는 또한 각 워크트리의 `.git` 파일을 읽고 그 `gitdir:` 포인터가 현재 저장소로 다시 해석되는지 확인하여 소유권을 검증합니다.\n\n3. **워크스페이스 리마운트** — 외부 워크트리에 `coast assign`하면 Coast는 일반적인 `/host-project/{dir}/{name}` 대신 외부 바인드 마운트 경로에서 `/workspace`를 다시 마운트합니다.\n\n## 외부 워크트리의 이름 지정\n\n브랜치가 체크아웃된 외부 워크트리는 로컬 워크트리와 동일하게 브랜치 이름으로 표시됩니다.\n\n**detached HEAD** 상태의 외부 워크트리(Codex에서 흔함)는 외부 디렉터리 내 상대 경로를 사용해 표시됩니다. 예를 들어 `~/.codex/worktrees/a0db/coastguard-platform`에 있는 Codex 워크트리는 UI와 CLI에서 `a0db/coastguard-platform`으로 표시됩니다.\n\n## `default_worktree_dir`\n\nCoast가 **새로운** 워크트리를 생성할 때 어떤 디렉터리를 사용할지 제어합니다(예: 기존 워크트리가 없는 브랜치를 할당할 때). 기본값은 `worktree_dir`의 첫 번째 항목입니다.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\ndefault_worktree_dir = \".worktrees\"\n```\n\n새 워크트리를 생성할 때는 외부 디렉터리를 절대 사용하지 않습니다 — Coast는 항상 로컬(상대) 디렉터리에 워크트리를 생성합니다. `default_worktree_dir` 필드는 기본값(첫 번째 항목)을 재정의하려는 경우에만 필요합니다.\n\n## 예시\n\n### Codex 통합\n\nOpenAI Codex는 `~/.codex/worktrees/{hash}/{project-name}`에 워크트리를 생성합니다. Coast에서 이것들이 보이고 할당 가능하도록 하려면:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\n이것을 추가하면 Codex의 워크트리가 체크아웃 모달과 `coast ls` 출력에 나타납니다. Coast 인스턴스를 Codex 워크트리에 할당하여 전체 개발 환경에서 해당 코드를 실행할 수 있습니다.\n\n참고: 외부 디렉터리를 추가한 후 바인드 마운트가 적용되려면 컨테이너를 다시 생성해야 합니다(`coast run`). 기존 인스턴스를 재시작하는 것만으로는 충분하지 않습니다.\n\n### Claude Code 통합\n\nClaude Code는 프로젝트 내부의 `.claude/worktrees/`에 워크트리를 생성합니다. 이것은 상대 경로이므로(프로젝트 루트 내부) 다른 로컬 워크트리 디렉터리처럼 작동합니다 — 외부 마운트가 필요하지 않습니다:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### 세 가지를 모두 함께 사용\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\n## 라이브 Coastfile 읽기\n\nCoastfile의 `worktree_dir` 변경 사항은 워크트리 **목록 표시**에 즉시 반영됩니다(API와 git watcher는 캐시된 빌드 아티팩트만이 아니라 디스크의 라이브 Coastfile을 읽습니다). 그러나 외부 **바인드 마운트**는 컨테이너 생성 시점에만 만들어지므로, 새로 추가한 외부 디렉터리를 마운트 가능하게 하려면 인스턴스를 다시 생성해야 합니다.\n", + "coastfiles/WORKTREE_DIR.md": "# 워크트리 디렉터리\n\n`[coast]`의 `worktree_dir` 필드는 git 워크트리가 위치할 곳을 제어합니다. Coast는 git 워크트리를 사용하여 전체 저장소를 복제하지 않고도 각 인스턴스가 서로 다른 브랜치에서 코드베이스의 자체 복사본을 갖도록 합니다.\n\n## 구문\n\n`worktree_dir`는 단일 문자열 또는 문자열 배열을 받을 수 있습니다:\n\n```toml\n# Single directory (default)\nworktree_dir = \".worktrees\"\n\n# Multiple directories\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\n생략하면 기본값은 `\".worktrees\"`입니다.\n\n## 경로 유형\n\n### 상대 경로\n\n`~/` 또는 `/`로 시작하지 않는 경로는 프로젝트 루트를 기준으로 해석됩니다. 이것이 가장 일반적인 경우이며 별도의 특별한 처리가 필요 없습니다 — 프로젝트 디렉터리 내부에 있으므로 표준 `/host-project` 바인드 마운트를 통해 Coast 컨테이너 내부에서 자동으로 사용할 수 있습니다.\n\n```toml\nworktree_dir = \".worktrees\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### 물결표 경로(외부)\n\n`~/`로 시작하는 경로는 사용자의 홈 디렉터리로 확장되며 **외부** 워크트리 디렉터리로 취급됩니다. Coast는 컨테이너가 해당 경로에 접근할 수 있도록 별도의 바인드 마운트를 추가합니다.\n\n```toml\nworktree_dir = [\"~/.codex/worktrees\", \".worktrees\"]\n```\n\n이것은 OpenAI Codex처럼 프로젝트 루트 외부에 워크트리를 생성하는 도구와 통합하는 방법입니다(Codex는 항상 `$CODEX_HOME/worktrees`에 워크트리를 생성합니다).\n\n### 절대 경로(외부)\n\n`/`로 시작하는 경로도 외부로 취급되며 자체 바인드 마운트를 갖습니다.\n\n```toml\nworktree_dir = [\"/shared/worktrees\", \".worktrees\"]\n```\n\n### Glob 패턴(외부)\n\n외부 경로에는 glob 메타문자(`*`, `?`, `[...]`)가 포함될 수 있습니다. Coast는 이를 런타임에 호스트 파일시스템에 대해 확장하여, 일치하는 각 디렉터리에 대해 바인드 마운트를 생성합니다.\n\n```toml\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n이는 도구가 프로젝트마다 달라지는 경로 구성 요소(예: 해시) 아래에 워크트리를 생성할 때 유용합니다. `*`는 임의의 단일 디렉터리 이름과 일치하므로, `~/.shep/repos/*/wt`는 `~/.shep/repos/a21f0cda9ab9d456/wt` 및 `wt` 하위 디렉터리를 포함하는 다른 모든 해시 디렉터리와 일치합니다.\n\n지원되는 glob 문법:\n\n- `*` — 단일 경로 구성 요소 내의 임의 길이 문자 시퀀스와 일치\n- `?` — 임의의 단일 문자와 일치\n- `[abc]` — 집합에 포함된 임의의 문자와 일치\n- `[!abc]` — 집합에 포함되지 않은 임의의 문자와 일치\n\nGlob 확장은 워크트리 디렉터리를 해석하는 모든 곳에서 발생합니다: 컨테이너 생성, assign, start, lookup, 그리고 git watcher. 일치 결과는 결정적 순서를 위해 정렬됩니다. glob이 어떤 디렉터리와도 일치하지 않으면 조용히 건너뜁니다.\n\n다른 외부 경로와 마찬가지로, glob 패턴을 추가한 뒤 바인드 마운트가 적용되려면 컨테이너를 다시 생성해야 합니다(`coast run`).\n\n## 외부 디렉터리가 작동하는 방식\n\nCoast가 외부 워크트리 디렉터리(물결표 또는 절대 경로)를 만나면 세 가지 일이 발생합니다:\n\n1. **컨테이너 바인드 마운트** — 컨테이너 생성 시점(`coast run`)에 해석된 호스트 경로가 `/host-external-wt/{index}`에 바인드 마운트되며, 여기서 `{index}`는 `worktree_dir` 배열에서의 위치입니다. 이렇게 하면 컨테이너 내부에서 외부 파일에 접근할 수 있습니다.\n\n2. **프로젝트 필터링** — 외부 디렉터리에는 여러 프로젝트의 워크트리가 포함될 수 있습니다. Coast는 `git worktree list --porcelain`(본질적으로 현재 저장소 범위로 제한됨)을 사용하여 이 프로젝트에 속한 워크트리만 찾습니다. git watcher는 또한 각 워크트리의 `.git` 파일을 읽고 그 `gitdir:` 포인터가 현재 저장소로 다시 해석되는지 확인하여 소유권을 검증합니다.\n\n3. **워크스페이스 리마운트** — 외부 워크트리에 `coast assign`하면 Coast는 일반적인 `/host-project/{dir}/{name}` 대신 외부 바인드 마운트 경로에서 `/workspace`를 다시 마운트합니다.\n\n## 외부 워크트리의 이름 지정\n\n브랜치가 체크아웃된 외부 워크트리는 로컬 워크트리와 동일하게 브랜치 이름으로 표시됩니다.\n\n**detached HEAD** 상태의 외부 워크트리(Codex에서 흔함)는 외부 디렉터리 내 상대 경로를 사용해 표시됩니다. 예를 들어 `~/.codex/worktrees/a0db/coastguard-platform`에 있는 Codex 워크트리는 UI와 CLI에서 `a0db/coastguard-platform`으로 표시됩니다.\n\n## `default_worktree_dir`\n\nCoast가 **새로운** 워크트리를 생성할 때 어떤 디렉터리를 사용할지 제어합니다(예: 기존 워크트리가 없는 브랜치를 할당할 때). 기본값은 `worktree_dir`의 첫 번째 항목입니다.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\ndefault_worktree_dir = \".worktrees\"\n```\n\n새 워크트리를 생성할 때는 외부 디렉터리를 절대 사용하지 않습니다 — Coast는 항상 로컬(상대) 디렉터리에 워크트리를 생성합니다. `default_worktree_dir` 필드는 기본값(첫 번째 항목)을 재정의하려는 경우에만 필요합니다.\n\n## 예시\n\n### Codex 통합\n\nOpenAI Codex는 `~/.codex/worktrees/{hash}/{project-name}`에 워크트리를 생성합니다. Coast에서 이것들이 보이고 할당 가능하도록 하려면:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\n이것을 추가하면 Codex의 워크트리가 체크아웃 모달과 `coast ls` 출력에 나타납니다. Coast 인스턴스를 Codex 워크트리에 할당하여 전체 개발 환경에서 해당 코드를 실행할 수 있습니다.\n\n참고: 외부 디렉터리를 추가한 후 바인드 마운트가 적용되려면 컨테이너를 다시 생성해야 합니다(`coast run`). 기존 인스턴스를 재시작하는 것만으로는 충분하지 않습니다.\n\n### Claude Code 통합\n\nClaude Code는 프로젝트 내부의 `.claude/worktrees/`에 워크트리를 생성합니다. 이것은 상대 경로이므로(프로젝트 루트 내부) 다른 로컬 워크트리 디렉터리처럼 작동합니다 — 외부 마운트가 필요하지 않습니다:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Shep 통합\n\nShep는 `~/.shep/repos/{hash}/wt/{branch-slug}`에 워크트리를 생성하며, 해시는 저장소별로 달라집니다. 해시 디렉터리와 일치시키기 위해 glob 패턴을 사용하세요:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n### 모든 harness를 함께 사용\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n## 라이브 Coastfile 읽기\n\nCoastfile의 `worktree_dir` 변경 사항은 워크트리 **목록 표시**에 즉시 반영됩니다(API와 git watcher는 캐시된 빌드 아티팩트만이 아니라 디스크의 라이브 Coastfile을 읽습니다). 그러나 외부 **바인드 마운트**는 컨테이너 생성 시점에만 만들어지므로, 새로 추가한 외부 디렉터리를 마운트 가능하게 하려면 인스턴스를 다시 생성해야 합니다.\n", "concepts_and_terminology/README.md": "# 개념과 용어\n\n이 섹션에서는 Coasts 전반에서 사용되는 핵심 개념과 어휘를 다룹니다. Coasts가 처음이라면, 설정이나 고급 사용법으로 들어가기 전에 여기서 시작하세요.\n\n- [Coasts](COASTS.md) — 프로젝트의 자체 포함 런타임으로, 각각 고유한 포트, 볼륨, 워크트리 할당을 가집니다.\n- [Run](RUN.md) — 최신 빌드에서 새 Coast 인스턴스를 생성하며, 선택적으로 워크트리를 할당할 수 있습니다.\n- [Remove](REMOVE.md) — 깨끗하게 다시 생성해야 하거나 Coasts를 내려야 할 때 Coast 인스턴스와 그 격리된 런타임 상태를 제거합니다.\n- [Filesystem](FILESYSTEM.md) — 호스트와 Coast 사이의 공유 마운트, 호스트 측 에이전트, 워크트리 전환.\n- [Coast Daemon](DAEMON.md) — 라이프사이클 작업을 실행하는 로컬 `coastd` 컨트롤 플레인.\n- [Coast CLI](CLI.md) — 명령, 스크립트, 에이전트 워크플로를 위한 터미널 인터페이스.\n- [Coastguard](COASTGUARD.md) — 관측성과 제어를 위해 `coast ui`로 실행되는 웹 UI.\n- [Ports](PORTS.md) — 표준 포트와 동적 포트, 그리고 checkout이 이들 사이를 어떻게 스왑하는지.\n- [Primary Port & DNS](PRIMARY_PORT_AND_DNS.md) — 기본 서비스로의 퀵 링크, 쿠키 격리를 위한 서브도메인 라우팅, URL 템플릿.\n- [Assign and Unassign](ASSIGN.md) — Coast를 워크트리 간에 전환하는 방법과 사용 가능한 assign 전략.\n- [Checkout](CHECKOUT.md) — 표준 포트를 Coast 인스턴스에 매핑하는 것과 언제 필요한지.\n- [Lookup](LOOKUP.md) — 에이전트의 현재 워크트리에 매칭되는 Coast 인스턴스를 찾는 방법.\n- [Volume Topology](VOLUMES.md) — 공유 서비스, 공유 볼륨, 격리 볼륨, 스냅샷.\n- [Shared Services](SHARED_SERVICES.md) — 호스트에서 관리되는 인프라 서비스와 볼륨 식별 해소.\n- [Secrets and Extractors](SECRETS.md) — 호스트 시크릿을 추출하여 Coast 컨테이너에 주입하기.\n- [Builds](BUILDS.md) — coast 빌드의 구조, 아티팩트가 위치하는 곳, 자동 정리, 타입드 빌드.\n- [Coastfile Types](COASTFILE_TYPES.md) — extends, unset, omit, autostart를 통한 조합 가능한 Coastfile 변형.\n- [Runtimes and Services](RUNTIMES_AND_SERVICES.md) — DinD 런타임, Docker-in-Docker 아키텍처, 서비스가 Coast 내부에서 실행되는 방식.\n- [Bare Services](BARE_SERVICES.md) — Coast 내부에서 비컨테이너화 프로세스를 실행하는 것과 대신 컨테이너화해야 하는 이유.\n- [Logs](LOGS.md) — Coast 내부에서 서비스 로그를 읽는 방법, MCP 트레이드오프, Coastguard 로그 뷰어.\n- [Exec & Docker](EXEC_AND_DOCKER.md) — Coast 내부에서 명령을 실행하고 내부 Docker 데몬과 통신하기.\n- [Agent Shells](AGENT_SHELLS.md) — 컨테이너화된 에이전트 TUI, OAuth 트레이드오프, 그리고 아마도 호스트에서 에이전트를 실행하는 편이 나은 이유.\n- [MCP Servers](MCP_SERVERS.md) — 컨테이너화된 에이전트를 위해 Coast 내부에서 MCP 도구를 구성하기, 내부 서버 vs 호스트 프록시 서버.\n- [Troubleshooting](TROUBLESHOOTING.md) — doctor, 데몬 재시작, 프로젝트 제거, 그리고 공장 초기화급의 완전 초기화 옵션.\n", "concepts_and_terminology/AGENT_SHELLS.md": "# 에이전트 셸\n\n에이전트 셸은 Coast 내부에 있는 셸로, 에이전트 TUI 런타임(Claude Code, Codex 또는 어떤 CLI 에이전트)이 직접 열리도록 합니다. Coastfile의 `[agent_shell]` 섹션으로 이를 구성하면, Coast가 DinD 컨테이너 내부에서 에이전트 프로세스를 스폰합니다.\n\n**대부분의 사용 사례에서는 이렇게 하지 않는 것이 좋습니다.** 대신 호스트 머신에서 코딩 에이전트를 실행하세요. 공유 [파일시스템](FILESYSTEM.md) 덕분에 호스트 측 에이전트는 일반적으로 코드를 편집하면서도 런타임 정보를 위해 [`coast logs`](LOGS.md), [`coast exec`](EXEC_AND_DOCKER.md), [`coast ps`](RUNTIMES_AND_SERVICES.md)를 호출할 수 있습니다. 에이전트 셸은 자격 증명 마운트, OAuth 복잡성, 라이프사이클 복잡성을 추가하며, 에이전트 자체를 컨테이너화해야 하는 특정한 이유가 없는 한 필요하지 않습니다.\n\n## OAuth 문제\n\nClaude Code, Codex 또는 OAuth로 인증하는 유사 도구를 사용 중이라면, 토큰은 호스트 머신을 대상으로 발급되었습니다. 동일한 토큰을 Linux 컨테이너 내부(다른 사용자 에이전트, 다른 환경)에서 사용하면, 제공자가 이를 플래그 처리하거나 철회할 수 있습니다. 디버깅하기 어려운 간헐적 인증 실패가 발생하게 됩니다.\n\n컨테이너화된 에이전트에는 API 키 기반 인증이 더 안전한 선택입니다. 키를 Coastfile의 [시크릿](SECRETS.md)으로 설정하고 컨테이너 환경에 주입하세요.\n\nAPI 키가 선택지가 아니라면 OAuth 자격 증명을 Coast에 마운트할 수 있습니다(아래 구성 섹션 참고). 다만 불편이 따를 수 있습니다. macOS에서 `keychain` 시크릿 추출기를 사용해 OAuth 토큰을 가져오면, 매번 `coast build` 시 macOS 키체인 비밀번호를 묻게 됩니다. 이는 특히 자주 리빌드할 때 빌드 과정을 번거롭게 만듭니다. 키체인 프롬프트는 macOS 보안 요구사항이며 우회할 수 없습니다.\n\n## 구성\n\nCoastfile에 실행할 커맨드를 포함한 `[agent_shell]` 섹션을 추가하세요:\n\n```toml\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\n이 커맨드는 DinD 컨테이너 내부의 `/workspace`에서 실행됩니다. Coast는 컨테이너 안에 `coast` 사용자를 생성하고, `/root/.claude/`의 자격 증명을 `/home/coast/.claude/`로 복사한 뒤, 해당 사용자로 커맨드를 실행합니다. 에이전트에 컨테이너로 마운트해야 하는 자격 증명이 필요하다면, 파일 주입을 사용하는 `[secrets]`( [Secrets and Extractors](SECRETS.md) 참고 )와 에이전트 CLI를 설치하기 위한 `[coast.setup]`를 사용하세요:\n\n```toml\n[coast.setup]\nrun = [\"npm install -g @anthropic-ai/claude-code\"]\n\n[secrets.claude_credentials]\nextractor = \"keychain\"\nservice = \"Claude Code-credentials\"\ninject = \"file:/root/.claude/.credentials.json\"\n\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\n`[agent_shell]`이 구성되어 있으면, Coast는 인스턴스 시작 시 셸을 자동으로 스폰합니다. 이 구성은 `extends`를 통해 상속되며, [Coastfile type](COASTFILE_TYPES.md)별로 오버라이드할 수 있습니다.\n\n## 활성 에이전트 모델\n\n각 Coast 인스턴스는 여러 에이전트 셸을 가질 수 있지만, 한 번에 **활성(active)** 상태인 것은 하나뿐입니다. 활성 셸은 `--shell` ID를 지정하지 않는 커맨드의 기본 대상입니다.\n\n```bash\ncoast agent-shell dev-1 ls\n\n SHELL STATUS ACTIVE\n 1 running ★\n 2 running\n```\n\n활성 셸을 전환하세요:\n\n```bash\ncoast agent-shell dev-1 activate 2\n```\n\n활성 셸은 닫을 수 없습니다 — 먼저 다른 셸을 활성화하세요. 이는 상호작용 중인 셸을 실수로 종료하는 것을 방지합니다.\n\nCoastguard에서는 에이전트 셸이 Exec 패널의 탭으로 표시되며 활성/비활성 배지가 붙습니다. 탭을 클릭해 터미널을 보고, 드롭다운 메뉴를 사용해 활성화, 스폰, 종료할 수 있습니다.\n\n![Agent shell in Coastguard](../../assets/coastguard-agent-shell.png)\n*Coastguard의 Exec 탭에서 접근 가능한 Coast 인스턴스 내부에서 Claude Code를 실행 중인 에이전트 셸.*\n\n## 입력 보내기\n\n컨테이너화된 에이전트를 프로그래밍 방식으로 구동하는 주요 방법은 `coast agent-shell input`입니다:\n\n```bash\ncoast agent-shell dev-1 input \"fix the failing test in auth.test.ts\"\n```\n\n이 명령은 활성 에이전트의 TUI에 텍스트를 쓰고 Enter를 누릅니다. 에이전트는 터미널에 직접 타이핑한 것처럼 이를 받습니다.\n\n옵션:\n\n- `--no-send` — Enter를 누르지 않고 텍스트만 씁니다. 부분 입력을 쌓거나 TUI 메뉴를 탐색할 때 유용합니다.\n- `--shell ` — 활성 셸 대신 특정 셸을 대상으로 합니다.\n- `--show-bytes` — 디버깅을 위해 전송되는 정확한 바이트를 출력합니다.\n\n내부적으로 입력은 PTY 마스터 파일 디스크립터에 직접 기록됩니다. 일부 TUI 프레임워크가 빠른 입력을 받을 때 보이는 paste-mode 아티팩트를 피하기 위해, 텍스트와 Enter 키스트로크는 25ms 간격을 두고 두 번의 별도 write로 전송됩니다.\n\n## 기타 명령\n\n```bash\ncoast agent-shell dev-1 spawn # 새 셸 생성\ncoast agent-shell dev-1 spawn --activate # 생성 후 즉시 활성화\ncoast agent-shell dev-1 tty # 활성 셸에 대화형 TTY로 붙기\ncoast agent-shell dev-1 tty --shell 2 # 특정 셸에 붙기\ncoast agent-shell dev-1 read-output # 전체 스크롤백 버퍼 읽기\ncoast agent-shell dev-1 read-last-lines 50 # 출력의 마지막 50줄 읽기\ncoast agent-shell dev-1 session-status # 셸 프로세스가 살아있는지 확인\n```\n\n`tty`는 라이브 대화형 세션을 제공합니다 — 에이전트의 TUI에 직접 입력할 수 있습니다. 표준 터미널 이스케이프 시퀀스로 분리(detach)하세요. `read-output`과 `read-last-lines`는 비대화형이며 텍스트를 반환하므로, 스크립팅과 자동화에 유용합니다.\n\n## 라이프사이클 및 복구\n\n에이전트 셸 세션은 Coastguard에서 페이지를 이동해도 유지됩니다. 탭에 다시 연결하면 스크롤백 버퍼(최대 512KB)가 재생됩니다.\n\n`coast stop`으로 Coast 인스턴스를 중지하면, 모든 에이전트 셸 PTY 프로세스가 종료되고 데이터베이스 레코드가 정리됩니다. `[agent_shell]`이 구성되어 있으면 `coast start`는 새로운 에이전트 셸을 자동으로 스폰합니다.\n\n데몬이 재시작된 뒤에는 이전에 실행 중이던 에이전트 셸이 죽은 것으로 표시됩니다. 시스템이 이를 자동으로 감지합니다 — 활성 셸이 죽어 있으면, 첫 번째로 살아있는 셸이 활성으로 승격됩니다. 살아있는 셸이 없다면 `coast agent-shell spawn --activate`로 새 셸을 스폰하세요.\n\n## 이것이 필요한 대상\n\n에이전트 셸은 Coast를 중심으로 **퍼스트파티 통합을 구축하는 제품**을 위해 설계되었습니다 — 오케스트레이션 플랫폼, 에이전트 래퍼, 그리고 `input`, `read-output`, `session-status` API를 통해 컨테이너화된 코딩 에이전트를 프로그래밍 방식으로 관리하려는 도구들입니다.\n\n일반적인 병렬 에이전트 코딩에는 호스트에서 에이전트를 실행하세요. 더 단순하고, OAuth 문제를 피하며, 자격 증명 마운트 복잡성을 우회하고, 공유 파일시스템을 최대한 활용할 수 있습니다. 에이전트 컨테이너화 오버헤드 없이 Coast의 모든 이점(격리된 런타임, 포트 관리, 워크트리 전환)을 얻습니다.\n\n에이전트 셸보다 한 단계 더 복잡한 수준은 컨테이너화된 에이전트가 도구에 접근할 수 있도록 [MCP 서버](MCP_SERVERS.md)를 Coast에 마운트하는 것입니다. 이는 통합 표면을 더 확장하며 별도로 다룹니다. 필요하다면 해당 기능을 사용할 수 있지만, 대부분의 사용자는 사용하지 않는 것이 좋습니다.\n", "concepts_and_terminology/ASSIGN.md": "# 할당 및 할당 해제\n\n할당과 할당 해제는 Coast 인스턴스가 어떤 worktree를 가리키는지 제어합니다. 마운트 레벨에서 worktree 전환이 어떻게 동작하는지에 대해서는 [Filesystem](FILESYSTEM.md)을 참고하세요.\n\n## 할당\n\n`coast assign`은 Coast 인스턴스를 특정 worktree로 전환합니다. Coast는 해당 worktree가 아직 존재하지 않으면 생성하고, Coast 내부의 코드를 업데이트한 다음, 구성된 할당 전략에 따라 서비스를 재시작합니다.\n\n```bash\ncoast assign dev-1 --worktree feature/oauth\n```\n\n```text\nBefore:\n┌─── dev-1 ──────────────────┐\n│ branch: main │\n│ worktree: - │\n└────────────────────────────┘\n\ncoast assign dev-1 --worktree feature/oauth\n\nAfter:\n┌─── dev-1 ──────────────────┐\n│ branch: feature/oauth │\n│ worktree: feature/oauth │\n│ │\n│ postgres → skipped (none) │\n│ web → hot swapped │\n│ api → restarted │\n│ worker → rebuilt │\n└────────────────────────────┘\n```\n\n할당 후에는 `dev-1`이 `feature/oauth` 브랜치를 실행하며 모든 서비스가 올라와 있습니다.\n\n## 할당 해제\n\n`coast unassign`은 Coast 인스턴스를 프로젝트 루트(메인/마스터 브랜치)로 되돌립니다. worktree 연결이 제거되고 Coast는 기본 리포지토리에서 실행 상태로 돌아갑니다.\n\n```text\ncoast unassign dev-1\n\n┌─── dev-1 ──────────────────┐\n│ branch: main │\n│ worktree: - │\n└────────────────────────────┘\n```\n\n## 할당 전략\n\nCoast가 새 worktree에 할당될 때, 각 서비스는 코드 변경을 어떻게 처리할지 알아야 합니다. 이는 [Coastfile](COASTFILE_TYPES.md)의 `[assign]` 아래에서 서비스별로 구성합니다:\n\n```toml\n[assign]\ndefault = \"restart\"\n\n[assign.services]\npostgres = \"none\"\nredis = \"none\"\nweb = \"hot\"\nworker = \"rebuild\"\n```\n\n```text\ncoast assign dev-1 --worktree feature/billing\n\n postgres (strategy: none) → skipped, unchanged between branches\n redis (strategy: none) → skipped, unchanged between branches\n web (strategy: hot) → filesystem swapped, file watcher picks it up\n api (strategy: restart) → container restarted\n worker (strategy: rebuild) → image rebuilt, container restarted\n```\n\n사용 가능한 전략은 다음과 같습니다:\n\n- **none** — 아무것도 하지 않습니다. Postgres나 Redis처럼 브랜치 간에 변경되지 않는 서비스에 사용하세요.\n- **hot** — 파일시스템만 교체합니다. 서비스는 계속 실행 중이며 마운트 전파와 파일 워처를 통해 변경을 반영합니다(예: 핫 리로드가 있는 개발 서버).\n- **restart** — 서비스 컨테이너를 재시작합니다. 프로세스 재시작만 필요로 하는 인터프리터 기반 서비스에 사용하세요. 이것이 기본값입니다.\n- **rebuild** — 서비스 이미지를 다시 빌드한 뒤 재시작합니다. 브랜치 변경이 `Dockerfile` 또는 빌드 타임 의존성에 영향을 줄 때 사용하세요.\n\n또한 특정 파일이 변경될 때만 서비스가 rebuild되도록 rebuild 트리거를 지정할 수 있습니다:\n\n```toml\n[assign.rebuild_triggers]\nworker = [\"Dockerfile\", \"package.json\"]\n```\n\n브랜치 간에 트리거 파일이 하나도 변경되지 않았다면, 전략이 `rebuild`로 설정되어 있더라도 서비스는 rebuild를 건너뜁니다.\n\n## 삭제된 Worktree\n\n할당된 worktree가 삭제되면, `coastd` 데몬이 해당 인스턴스를 자동으로 할당 해제하여 메인 Git 리포지토리 루트로 되돌립니다.\n\n---\n\n> **팁: 대규모 코드베이스에서 할당 지연 시간 줄이기**\n>\n> 내부적으로, 새로운 worktree에 대한 첫 할당은 선택된 gitignored 파일들을 해당 worktree로 부트스트랩하며, `[assign.rebuild_triggers]`가 있는 서비스는 rebuild가 필요한지 결정하기 위해 `git diff --name-only`를 실행할 수 있습니다. 대규모 코드베이스에서는 이 부트스트랩 단계와 불필요한 rebuild가 할당 시간을 지배하는 경향이 있습니다.\n>\n> Coastfile의 `exclude_paths`를 사용해 gitignored 부트스트랩 범위를 줄이고, 파일 워처가 있는 서비스에는 `\"hot\"`을 사용하며, `[assign.rebuild_triggers]`는 진짜 빌드 타임 입력에만 집중시키세요. 기존 worktree에 대해 ignored-file 부트스트랩을 수동으로 새로 고쳐야 한다면 `coast assign --force-sync`를 실행하세요. 전체 가이드는 [Performance Optimizations](PERFORMANCE_OPTIMIZATIONS.md)을 참고하세요.\n", "concepts_and_terminology/BARE_SERVICES.md": "# 베어 서비스\n\n프로젝트를 컨테이너화할 수 있다면, 그렇게 해야 합니다. 베어 서비스는 아직 컨테이너화되지 않았고 단기간에 `Dockerfile`과 `docker-compose.yml`을 추가하는 것이 현실적이지 않은 프로젝트를 위해 존재합니다. 이는 디딤돌이지, 최종 목적지가 아닙니다.\n\n컨테이너화된 서비스를 오케스트레이션하는 `docker-compose.yml` 대신, 베어 서비스는 Coastfile에서 셸 명령을 정의할 수 있게 해주며 Coast는 Coast 컨테이너 내부의 경량 슈퍼바이저로 이를 일반 프로세스로 실행합니다.\n\n## 대신 컨테이너화해야 하는 이유\n\n[Docker Compose](RUNTIMES_AND_SERVICES.md) 서비스가 제공하는 것:\n\n- Dockerfile을 통한 재현 가능한 빌드\n- 시작 중 Coast가 대기할 수 있는 헬스 체크\n- 서비스 간 프로세스 격리\n- Docker가 처리하는 볼륨 및 네트워크 관리\n- CI, 스테이징, 프로덕션에서 동작하는 이식 가능한 정의\n\n베어 서비스는 그 어떤 것도 제공하지 않습니다. 프로세스는 동일한 파일시스템을 공유하고, 크래시 복구는 셸 루프이며, \"내 컴퓨터에서는 되는데\"는 Coast 내부에서도 외부만큼이나 일어날 수 있습니다. 프로젝트에 이미 `docker-compose.yml`이 있다면, 그것을 사용하세요.\n\n## 베어 서비스가 의미가 있는 경우\n\n- 한 번도 컨테이너화된 적 없는 프로젝트에 Coast를 도입하고 있으며, 워크트리 격리와 포트 관리를 통해 즉시 가치를 얻고 싶을 때\n- 프로젝트가 단일 프로세스 도구 또는 CLI이며 Dockerfile이 과할 때\n- 컨테이너화를 점진적으로 진행하고 싶을 때 — 베어 서비스로 시작하고 나중에 compose로 이동\n\n## 구성\n\n베어 서비스는 Coastfile의 `[services.]` 섹션으로 정의됩니다. Coastfile은 베어 서비스만 단독으로 정의할 수도 있고 `compose`와 함께 정의할 수도 있습니다 — 후자의 경우 [Mixed Service Types](MIXED_SERVICE_TYPES.md)를 참고하세요.\n\n```toml\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\nrestart = \"on-failure\"\n\n[services.worker]\ncommand = \"node worker.js\"\nrestart = \"always\"\n\n[ports]\nweb = 3000\n```\n\n각 서비스에는 네 가지 필드가 있습니다:\n\n| Field | Required | Description |\n|---|---|---|\n| `command` | yes | 실행할 셸 명령(예: `\"npm run dev\"`) |\n| `port` | no | 서비스가 리스닝하는 포트로, 포트 매핑에 사용 |\n| `restart` | no | 재시작 정책: `\"no\"`(기본값), `\"on-failure\"`, 또는 `\"always\"` |\n| `install` | no | 시작 전에 실행할 하나 이상의 명령(예: `\"npm install\"` 또는 `[\"npm install\", \"npm run build\"]`) |\n\n### 설정 패키지\n\n베어 서비스는 일반 프로세스로 실행되므로, Coast 컨테이너에 올바른 런타임이 설치되어 있어야 합니다. `[coast.setup]`을 사용해 시스템 패키지를 선언하세요:\n\n```toml\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n```\n\n이들은 어떤 서비스가 시작되기 전에 설치됩니다. 이것이 없으면 컨테이너 내부에서 `npm` 또는 `node` 명령이 실패합니다.\n\n### 설치 명령\n\n`install` 필드는 서비스가 시작되기 전에 실행되며, 모든 [`coast assign`](ASSIGN.md) (브랜치 전환) 때마다 다시 실행됩니다. 의존성 설치는 여기에 넣습니다:\n\n```toml\n[services.api]\ninstall = [\"pip install -r requirements.txt\", \"python manage.py migrate\"]\ncommand = \"python manage.py runserver 0.0.0.0:8000\"\nport = 8000\n```\n\n설치 명령은 순차적으로 실행됩니다. 어떤 설치 명령이든 실패하면 서비스는 시작되지 않습니다.\n\n### 재시작 정책\n\n- **`no`** — 서비스는 한 번 실행됩니다. 종료되면 그대로 죽은 상태로 유지됩니다. 원샷 작업이나 수동으로 관리하고 싶은 서비스에 사용하세요.\n- **`on-failure`** — 비-0 코드로 종료되면 서비스를 재시작합니다. 정상 종료(코드 0)는 그대로 둡니다. 1초에서 최대 30초까지 지수 백오프를 사용하며, 연속 10회 크래시 후에는 포기합니다.\n- **`always`** — 성공을 포함한 어떤 종료에서도 재시작합니다. `on-failure`와 동일한 백오프를 사용합니다. 절대 멈추면 안 되는 장기 실행 서버에 사용하세요.\n\n서비스가 크래시하기 전에 30초 이상 실행되었다면, 재시도 카운터와 백오프는 리셋됩니다 — 한동안은 정상적이었다고 보고 크래시를 새로운 문제로 가정합니다.\n\n## 내부에서 동작하는 방식\n\n```text\n┌─── Coast: dev-1 ──────────────────────────────────────┐\n│ │\n│ /coast-supervisor/ │\n│ ├── web.sh (runs command, tracks PID) │\n│ ├── worker.sh │\n│ ├── start-all.sh (launches all services) │\n│ ├── stop-all.sh (SIGTERM via PID files) │\n│ └── ps.sh (checks PID liveness) │\n│ │\n│ /var/log/coast-services/ │\n│ ├── web.log │\n│ └── worker.log │\n│ │\n│ No inner Docker daemon images are used. │\n│ Processes run directly on the container OS. │\n└───────────────────────────────────────────────────────┘\n```\n\nCoast는 각 서비스에 대한 셸 스크립트 래퍼를 생성하고 DinD 컨테이너 내부의 `/coast-supervisor/`에 배치합니다. 각 래퍼는 PID를 추적하고, 출력을 로그 파일로 리다이렉트하며, 재시작 정책을 셸 루프로 구현합니다. Docker Compose도 없고, 내부 Docker 이미지도 없으며, 서비스 간 컨테이너 수준의 격리도 없습니다.\n\n`coast ps`는 Docker를 조회하는 대신 PID 생존 여부를 확인하고, `coast logs`는 `docker compose logs`를 호출하는 대신 로그 파일을 tail 합니다. 로그 출력 형식은 compose의 `service | line` 형식과 일치하므로 Coastguard의 UI가 변경 없이 동작합니다.\n\n## 포트\n\n포트 구성은 compose 기반 Coast와 완전히 동일하게 동작합니다. 서비스가 리스닝하는 포트를 `[ports]`에 정의하세요:\n\n```toml\n[services.web]\ncommand = \"npm start\"\nport = 3000\n\n[ports]\nweb = 3000\n```\n\n[Dynamic ports](PORTS.md)는 `coast run` 시 할당되며, [`coast checkout`](CHECKOUT.md)는 평소처럼 캐노니컬 포트를 스왑합니다. 유일한 차이는 서비스 간 Docker 네트워크가 없다는 점입니다 — 모두 컨테이너의 루프백 또는 `0.0.0.0`에 직접 바인딩합니다.\n\n## 브랜치 전환\n\n베어 서비스 Coast에서 `coast assign`을 실행하면, 다음이 발생합니다:\n\n1. 실행 중인 모든 서비스가 SIGTERM으로 중지됩니다\n2. 워크트리가 새 브랜치로 전환됩니다\n3. 설치 명령이 재실행됩니다(예: `npm install`이 새 브랜치의 의존성을 반영)\n4. 모든 서비스가 재시작됩니다\n\n이는 compose에서 일어나는 것 — `docker compose down`, 브랜치 전환, 리빌드, `docker compose up` — 과 동일하지만, 컨테이너 대신 셸 프로세스를 사용합니다.\n\n## 제한 사항\n\n- **헬스 체크 없음.** Coast는 헬스 체크를 정의한 compose 서비스처럼 베어 서비스가 \"건강한\" 상태가 될 때까지 기다릴 수 없습니다. 프로세스를 시작하고 잘 되길 바랄 뿐입니다.\n- **서비스 간 격리 없음.** 모든 프로세스는 Coast 컨테이너 내부에서 동일한 파일시스템과 프로세스 네임스페이스를 공유합니다. 문제를 일으키는 서비스가 다른 서비스에 영향을 줄 수 있습니다.\n- **빌드 캐싱 없음.** Docker Compose 빌드는 레이어 단위로 캐시됩니다. 베어 서비스의 `install` 명령은 assign 때마다 처음부터 실행됩니다.\n- **크래시 복구가 기본적임.** 재시작 정책은 지수 백오프를 사용하는 셸 루프입니다. systemd나 supervisord 같은 프로세스 슈퍼바이저가 아닙니다.\n- **서비스에 대한 `[omit]` 또는 `[unset]` 미지원.** Coastfile 타입 합성은 compose 서비스에서 동작하지만, 베어 서비스는 typed Coastfile로 개별 서비스를 생략하는 것을 지원하지 않습니다.\n\n## Compose로 마이그레이션\n\n컨테이너화할 준비가 되면, 마이그레이션 경로는 간단합니다:\n\n1. 각 서비스에 대해 `Dockerfile`을 작성합니다\n2. 이를 참조하는 `docker-compose.yml`을 만듭니다\n3. Coastfile의 `[services.*]` 섹션을 compose 파일을 가리키는 `compose` 필드로 교체합니다\n4. 이제 Dockerfile에서 처리되는 `[coast.setup]` 패키지를 제거합니다\n5. [`coast build`](BUILDS.md)로 리빌드합니다\n\n포트 매핑, [volumes](VOLUMES.md), [shared services](SHARED_SERVICES.md), [secrets](SECRETS.md) 구성은 모두 변경 없이 그대로 유지됩니다. 바뀌는 것은 서비스 자체가 실행되는 방식뿐입니다.\n", "concepts_and_terminology/BUILDS.md": "# 빌드\n\ncoast 빌드는 추가 지원이 있는 Docker 이미지라고 생각하면 됩니다. 빌드는 Coast 인스턴스를 만드는 데 필요한 모든 것을 묶는 디렉터리 기반 아티팩트입니다: 해석된 [Coastfile](COASTFILE_TYPES.md), 다시 작성된 compose 파일, 미리 pull된 OCI 이미지 tarball, 그리고 주입된 호스트 파일. 이것은 Docker 이미지 자체는 아니지만, Docker 이미지들(tarball 형태)과 Coast가 그것들을 함께 연결하는 데 필요한 메타데이터를 포함합니다.\n\n## `coast build`가 수행하는 일\n\n`coast build`를 실행하면 데몬은 다음 단계를 순서대로 실행합니다:\n\n1. Coastfile을 파싱하고 검증합니다.\n2. compose 파일을 읽고 제외된 서비스를 필터링합니다.\n3. 구성된 추출기에서 [시크릿](SECRETS.md)을 추출하고 keystore에 암호화하여 저장합니다.\n4. `build:` 지시어가 있는 compose 서비스에 대해 Docker 이미지를 빌드합니다(호스트에서).\n5. `image:` 지시어가 있는 compose 서비스에 대해 Docker 이미지를 pull합니다.\n6. 모든 이미지를 `~/.coast/image-cache/`에 OCI tarball로 캐시합니다.\n7. `[coast.setup]`이 구성되어 있으면, 지정된 패키지, 명령, 파일로 사용자 지정 DinD 베이스 이미지를 빌드합니다.\n8. 매니페스트, 해석된 coastfile, 다시 작성된 compose, 주입된 파일이 포함된 빌드 아티팩트 디렉터리를 작성합니다.\n9. `latest` 심볼릭 링크를 새 빌드를 가리키도록 업데이트합니다.\n10. 보관 한도를 초과한 오래된 빌드를 자동으로 정리합니다.\n\n## 빌드가 저장되는 위치\n\n```text\n~/.coast/\n images/\n my-project/\n latest -> a3c7d783_20260227143000 (symlink)\n a3c7d783_20260227143000/ (versioned build)\n manifest.json\n coastfile.toml\n compose.yml\n inject/\n b4d8e894_20260226120000/ (older build)\n ...\n image-cache/ (shared tarball cache)\n postgres_16_a1b2c3d4e5f6.tar\n redis_7_f6e5d4c3b2a1.tar\n coast-built_my-project_web_latest_...tar\n```\n\n각 빌드는 `{coastfile_hash}_{YYYYMMDDHHMMSS}` 형식의 고유한 **build ID**를 가집니다. 이 해시는 Coastfile 내용과 해석된 구성을 포함하므로, Coastfile이 변경되면 새로운 build ID가 생성됩니다.\n\n`latest` 심볼릭 링크는 빠른 해석을 위해 항상 가장 최근 빌드를 가리킵니다. 프로젝트가 타입이 있는 Coastfile(예: `Coastfile.light`)을 사용하는 경우, 각 타입은 자체 심볼릭 링크를 가집니다: `latest-light`.\n\n`~/.coast/image-cache/`의 이미지 캐시는 모든 프로젝트에서 공유됩니다. 두 프로젝트가 동일한 Postgres 이미지를 사용하면, 해당 tarball은 한 번만 캐시됩니다.\n\n## 빌드에 포함되는 것\n\n각 빌드 디렉터리에는 다음이 포함됩니다:\n\n- **`manifest.json`** -- 전체 빌드 메타데이터: 프로젝트 이름, 빌드 타임스탬프, coastfile 해시, 캐시되거나 빌드된 이미지 목록, 시크릿 이름, 제외된 서비스, [볼륨 전략](VOLUMES.md) 등.\n- **`coastfile.toml`** -- 해석된 Coastfile (`extends`를 사용하는 경우 부모와 병합됨).\n- **`compose.yml`** -- compose 파일의 다시 작성된 버전으로, `build:` 지시어는 미리 빌드된 이미지 태그로 대체되고 제외된 서비스는 제거됩니다.\n- **`inject/`** -- `[inject].files`의 호스트 파일 복사본(예: `~/.gitconfig`, `~/.npmrc`).\n\n## 빌드에는 시크릿이 포함되지 않음\n\n시크릿은 빌드 단계에서 추출되지만, 빌드 아티팩트 디렉터리 내부가 아닌 `~/.coast/keystore.db`의 별도 암호화된 keystore에 저장됩니다. 매니페스트에는 추출된 시크릿의 **이름**만 기록되며, 값은 절대 기록되지 않습니다.\n\n즉, 민감한 데이터를 노출하지 않고도 빌드 아티팩트를 안전하게 검사할 수 있습니다. 시크릿은 나중에 `coast run`으로 Coast 인스턴스를 생성할 때 복호화되고 주입됩니다.\n\n## 빌드와 Docker\n\n빌드에는 세 가지 종류의 Docker 이미지가 포함됩니다:\n\n- **빌드된 이미지** -- `build:` 지시어가 있는 compose 서비스는 호스트에서 `docker build`를 통해 빌드되고, `coast-built/{project}/{service}:latest`로 태그되며, 이미지 캐시에 tarball로 저장됩니다.\n- **pull된 이미지** -- `image:` 지시어가 있는 compose 서비스는 pull되어 tarball로 저장됩니다.\n- **Coast 이미지** -- `[coast.setup]`이 구성되어 있으면, 지정된 패키지, 명령, 파일을 사용해 `docker:dind` 위에 사용자 지정 Docker 이미지가 빌드됩니다. `coast-image/{project}:{build_id}`로 태그됩니다.\n\n런타임([`coast run`](RUN.md))에는 이 tarball들이 `docker load`를 통해 내부 [DinD 데몬](RUNTIMES_AND_SERVICES.md)으로 로드됩니다. 이것이 Coast 인스턴스가 레지스트리에서 이미지를 pull할 필요 없이 빠르게 시작되는 이유입니다.\n\n## 빌드와 인스턴스\n\n[`coast run`](RUN.md)을 실행하면 Coast는 최신 빌드(또는 특정 `--build-id`)를 해석하고, 해당 아티팩트를 사용해 인스턴스를 생성합니다. build ID는 인스턴스에 기록됩니다.\n\n더 많은 인스턴스를 만들기 위해 다시 빌드할 필요는 없습니다. 하나의 빌드로 병렬 실행되는 여러 Coast 인스턴스를 제공할 수 있습니다.\n\n## 다시 빌드해야 하는 경우\n\nCoastfile, `docker-compose.yml`, 또는 인프라 구성이 변경될 때만 다시 빌드하세요. 다시 빌드는 리소스를 많이 사용합니다 -- 이미지를 다시 pull하고, Docker 이미지를 다시 빌드하고, 시크릿을 다시 추출합니다.\n\n코드 변경은 다시 빌드할 필요가 없습니다. Coast는 프로젝트 디렉터리를 각 인스턴스에 직접 마운트하므로, 코드 업데이트가 즉시 반영됩니다.\n\n## 자동 정리\n\nCoast는 Coastfile 타입당 최대 5개의 빌드를 유지합니다. `coast build`가 성공적으로 실행될 때마다 한도를 초과한 오래된 빌드는 자동으로 제거됩니다.\n\n실행 중인 인스턴스에서 사용 중인 빌드는 한도와 관계없이 절대 정리되지 않습니다. 빌드가 7개 있지만 그중 3개가 활성 인스턴스를 지원하고 있다면, 그 3개는 모두 보호됩니다.\n\n## 수동 제거\n\n빌드는 `coast rm-build` 또는 Coastguard Builds 탭을 통해 수동으로 제거할 수 있습니다.\n\n- **전체 프로젝트 제거** (`coast rm-build `)는 먼저 모든 인스턴스를 중지하고 제거해야 합니다. 전체 빌드 디렉터리, 관련 Docker 이미지, 볼륨, 컨테이너를 제거합니다.\n- **선택적 제거** (Coastguard UI에서 사용 가능하며 build ID 기준)는 실행 중인 인스턴스에서 사용 중인 빌드를 건너뜁니다.\n\n## 타입별 빌드\n\n프로젝트가 여러 Coastfile을 사용하는 경우(예: 기본 구성용 `Coastfile`과 스냅샷 시드 볼륨용 `Coastfile.snap`), 각 타입은 자체 `latest-{type}` 심볼릭 링크와 자체 5개 빌드 정리 풀을 유지합니다.\n\n```bash\ncoast build # uses Coastfile, updates \"latest\"\ncoast build --type snap # uses Coastfile.snap, updates \"latest-snap\"\n```\n\n`snap` 빌드를 정리해도 `default` 빌드는 절대 건드리지 않으며, 그 반대도 마찬가지입니다.\n", - "concepts_and_terminology/CHECKOUT.md": "# 체크아웃\n\n체크아웃은 프로젝트의 [canonical ports](PORTS.md)를 어떤 Coast 인스턴스가 소유할지 제어합니다. Coast를 체크아웃하면 `localhost:3000`, `localhost:5432`, 그리고 그 외 모든 canonical port가 해당 인스턴스로 바로 매핑됩니다.\n\n```bash\ncoast checkout dev-1\n```\n\n```text\nBefore checkout:\n localhost:3000 ──→ (nothing)\n localhost:5432 ──→ (nothing)\n\nAfter checkout:\n localhost:3000 ──→ dev-1 web\n localhost:5432 ──→ dev-1 db\n```\n\n체크아웃 전환은 즉시 이루어집니다 — Coast는 가벼운 `socat` 포워더를 종료하고 다시 생성합니다. 어떤 컨테이너도 재시작되지 않습니다.\n\n```bash\ncoast checkout dev-2 # instant swap\n\n# localhost:3000 ──→ dev-2 web\n# localhost:5432 ──→ dev-2 db\n```\n\n## Linux 참고\n\n동적 포트는 Linux에서 특별한 권한 없이도 항상 작동합니다.\n\n`1024` 미만의 canonical port는 다릅니다. Coastfile이 `80` 또는 `443` 같은 포트를 선언한 경우, 호스트를 구성하기 전까지 Linux가 `coast checkout`이 해당 포트에 바인딩하는 것을 차단할 수 있습니다. 일반적인 해결 방법은 다음과 같습니다:\n\n- `net.ipv4.ip_unprivileged_port_start` 값을 올리기\n- 포워딩 바이너리 또는 프로세스에 bind capability 부여하기\n\n호스트가 바인딩을 거부할 경우 Coast는 이를 명시적으로 보고합니다.\n\nWSL에서는 Coast가 Docker에 의해 게시된 체크아웃 브리지를 사용하므로, Windows 브라우저와 도구가 Sail 같은 Docker Desktop 워크플로와 유사하게 `127.0.0.1`을 통해 체크아웃된 canonical port에 접근할 수 있습니다.\n\n## 체크아웃이 꼭 필요한가요?\n\n반드시 그렇지는 않습니다. 실행 중인 모든 Coast는 항상 자체 동적 포트를 가지며, 무엇이든 체크아웃하지 않아도 언제든지 그 포트를 통해 어떤 Coast에도 접근할 수 있습니다.\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\n체크아웃하지 않아도 브라우저에서 `localhost:62217`을 열어 dev-1의 웹 서버에 접근할 수 있습니다. 많은 워크플로에서는 이것만으로도 충분하며, `coast checkout`을 전혀 사용하지 않고도 원하는 만큼 많은 Coast를 실행할 수 있습니다.\n\n## 체크아웃이 유용한 경우\n\n동적 포트만으로는 충분하지 않고 canonical port가 필요한 상황이 있습니다:\n\n- **canonical port에 하드코딩된 클라이언트 애플리케이션.** Coast 외부에서 실행되는 클라이언트 — 예를 들어 호스트의 프런트엔드 개발 서버, 휴대폰의 모바일 앱, 또는 데스크톱 앱 — 가 `localhost:3000` 또는 `localhost:8080`을 기대한다면, 곳곳에서 포트 번호를 바꾸는 것은 비현실적입니다. Coast를 체크아웃하면 어떤 설정도 변경하지 않고 실제 포트를 사용할 수 있습니다.\n\n- **웹훅과 콜백 URL.** Stripe, GitHub, OAuth 제공자 같은 서비스는 등록해 둔 URL로 콜백을 보냅니다 — 보통 `localhost:3000`으로 전달되는 `https://your-ngrok-tunnel.io` 같은 형태입니다. 동적 포트로 전환하면 콜백이 더 이상 도착하지 않습니다. 체크아웃은 테스트 중인 Coast에 대해 canonical port가 활성화되도록 보장합니다.\n\n- **데이터베이스 도구, 디버거, IDE 통합.** 많은 GUI 클라이언트(pgAdmin, DataGrip, TablePlus), 디버거, IDE 실행 구성은 특정 포트로 연결 프로필을 저장합니다. 체크아웃을 사용하면 저장된 프로필은 그대로 두고, 그 뒤에 연결된 Coast만 바꿀 수 있습니다 — 컨텍스트를 전환할 때마다 디버거 attach 대상이나 데이터베이스 연결을 다시 설정할 필요가 없습니다.\n\n## 체크아웃 해제\n\n다른 Coast를 체크아웃하지 않고 canonical port를 해제하려면:\n\n```bash\ncoast checkout --none\n```\n\n이후에는 어떤 Coast도 canonical port를 소유하지 않습니다. 모든 Coast는 계속해서 각자의 동적 포트를 통해 접근할 수 있습니다.\n\n## 한 번에 하나만\n\n한 번에 정확히 하나의 Coast만 체크아웃할 수 있습니다. `dev-1`이 체크아웃된 상태에서 `coast checkout dev-2`를 실행하면, canonical port는 즉시 `dev-2`로 전환됩니다. 중간 공백은 없습니다 — 기존 포워더가 종료되고 같은 작업 안에서 새 포워더가 생성됩니다.\n\n```text\n┌──────────────────────────────────────────────────┐\n│ Your machine │\n│ │\n│ Canonical (checked-out Coast only): │\n│ localhost:3000 ──→ dev-2 web │\n│ localhost:5432 ──→ dev-2 db │\n│ │\n│ Dynamic (always available): │\n│ localhost:62217 ──→ dev-1 web │\n│ localhost:55681 ──→ dev-1 db │\n│ localhost:63104 ──→ dev-2 web │\n│ localhost:57220 ──→ dev-2 db │\n└──────────────────────────────────────────────────┘\n```\n\n동적 포트는 체크아웃의 영향을 받지 않습니다. 바뀌는 것은 canonical port가 가리키는 대상뿐입니다.\n", + "concepts_and_terminology/CHECKOUT.md": "# 체크아웃\n\n체크아웃은 프로젝트의 [canonical ports](PORTS.md)를 어떤 Coast 인스턴스가 소유할지 제어합니다. Coast를 체크아웃하면 `localhost:3000`, `localhost:5432`, 그리고 그 외 모든 canonical port가 해당 인스턴스로 바로 매핑됩니다.\n\n```bash\ncoast checkout dev-1\n```\n\n```text\nBefore checkout:\n localhost:3000 ──→ (nothing)\n localhost:5432 ──→ (nothing)\n\nAfter checkout:\n localhost:3000 ──→ dev-1 web\n localhost:5432 ──→ dev-1 db\n```\n\n체크아웃 전환은 즉시 이루어집니다 — Coast는 가벼운 `socat` 포워더를 종료하고 다시 생성합니다. 어떤 컨테이너도 재시작되지 않습니다.\n\n```bash\ncoast checkout dev-2 # instant swap\n\n# localhost:3000 ──→ dev-2 web\n# localhost:5432 ──→ dev-2 db\n```\n\n## Linux 참고\n\n동적 포트는 Linux에서 특별한 권한 없이도 항상 작동합니다.\n\n`1024` 미만의 canonical port는 다릅니다. Coastfile이 `80` 또는 `443` 같은 포트를 선언한 경우, 호스트를 구성하기 전까지 Linux가 `coast checkout`이 해당 포트에 바인딩하는 것을 차단할 수 있습니다. 일반적인 해결 방법은 다음과 같습니다:\n\n- `net.ipv4.ip_unprivileged_port_start` 값을 올리기\n- 포워딩 바이너리 또는 프로세스에 bind capability 부여하기\n\n호스트가 바인딩을 거부할 경우 Coast는 이를 명시적으로 보고합니다.\n\nWSL에서는 Coast가 Docker에 의해 게시된 체크아웃 브리지를 사용하므로, Windows 브라우저와 도구가 Sail 같은 Docker Desktop 워크플로와 유사하게 `127.0.0.1`을 통해 체크아웃된 canonical port에 접근할 수 있습니다.\n\nCaddy를 사용하는 로컬 HTTPS 프로젝트의 경우, Coast는 Coast 설치마다 하나의 Caddy 로컬 CA를 재사용합니다. 해당 루트를 한 번 신뢰하면, 같은 설치 아래에서 다시 생성된 워크스페이스도 계속 그것을 사용합니다.\n\n루트 인증서는 다음 위치에 있습니다:\n\n- 일반 설치의 경우 `~/.coast/caddy/pki/authorities/local/root.crt`\n- `coast-dev`의 경우 `~/.coast-dev/caddy/pki/authorities/local/root.crt`\n\n이 둘은 의도적으로 분리되어 있으므로, `coast-dev`를 신뢰한다고 해서 일반 `coast` 설치까지 함께 신뢰되는 것은 아니며, 그 반대도 마찬가지입니다.\n\n활성 설치의 루트 인증서를 확인하거나 내보내려면:\n\n```bash\ncoast cert info\ncoast cert path\ncoast cert fingerprint\ncoast cert export --to ~/Downloads/coast-root.crt\n```\n\nCoast는 신뢰 설치를 사용자가 직접 하도록 둡니다. 인증서를 내보낸 다음, 필요에 따라 OS 또는 브라우저의 신뢰 저장소로 가져오세요.\n\n## 체크아웃이 꼭 필요한가요?\n\n반드시 그렇지는 않습니다. 실행 중인 모든 Coast는 항상 자체 동적 포트를 가지며, 무엇이든 체크아웃하지 않아도 언제든지 그 포트를 통해 어떤 Coast에도 접근할 수 있습니다.\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\n체크아웃하지 않아도 브라우저에서 `localhost:62217`을 열어 dev-1의 웹 서버에 접근할 수 있습니다. 많은 워크플로에서는 이것만으로도 충분하며, `coast checkout`을 전혀 사용하지 않고도 원하는 만큼 많은 Coast를 실행할 수 있습니다.\n\n## 체크아웃이 유용한 경우\n\n동적 포트만으로는 충분하지 않고 canonical port가 필요한 상황이 있습니다:\n\n- **canonical port에 하드코딩된 클라이언트 애플리케이션.** Coast 외부에서 실행되는 클라이언트 — 예를 들어 호스트의 프런트엔드 개발 서버, 휴대폰의 모바일 앱, 또는 데스크톱 앱 — 가 `localhost:3000` 또는 `localhost:8080`을 기대한다면, 곳곳에서 포트 번호를 바꾸는 것은 비현실적입니다. Coast를 체크아웃하면 어떤 설정도 변경하지 않고 실제 포트를 사용할 수 있습니다.\n\n- **웹훅과 콜백 URL.** Stripe, GitHub, OAuth 제공자 같은 서비스는 등록해 둔 URL로 콜백을 보냅니다 — 보통 `localhost:3000`으로 전달되는 `https://your-ngrok-tunnel.io` 같은 형태입니다. 동적 포트로 전환하면 콜백이 더 이상 도착하지 않습니다. 체크아웃은 테스트 중인 Coast에 대해 canonical port가 활성화되도록 보장합니다.\n\n- **데이터베이스 도구, 디버거, IDE 통합.** 많은 GUI 클라이언트(pgAdmin, DataGrip, TablePlus), 디버거, IDE 실행 구성은 특정 포트로 연결 프로필을 저장합니다. 체크아웃을 사용하면 저장된 프로필은 그대로 두고, 그 뒤에 연결된 Coast만 바꿀 수 있습니다 — 컨텍스트를 전환할 때마다 디버거 attach 대상이나 데이터베이스 연결을 다시 설정할 필요가 없습니다.\n\n## 체크아웃 해제\n\n다른 Coast를 체크아웃하지 않고 canonical port를 해제하려면:\n\n```bash\ncoast checkout --none\n```\n\n이후에는 어떤 Coast도 canonical port를 소유하지 않습니다. 모든 Coast는 계속해서 각자의 동적 포트를 통해 접근할 수 있습니다.\n\n## 한 번에 하나만\n\n한 번에 정확히 하나의 Coast만 체크아웃할 수 있습니다. `dev-1`이 체크아웃된 상태에서 `coast checkout dev-2`를 실행하면, canonical port는 즉시 `dev-2`로 전환됩니다. 중간 공백은 없습니다 — 기존 포워더가 종료되고 같은 작업 안에서 새 포워더가 생성됩니다.\n\n```text\n┌──────────────────────────────────────────────────┐\n│ Your machine │\n│ │\n│ Canonical (checked-out Coast only): │\n│ localhost:3000 ──→ dev-2 web │\n│ localhost:5432 ──→ dev-2 db │\n│ │\n│ Dynamic (always available): │\n│ localhost:62217 ──→ dev-1 web │\n│ localhost:55681 ──→ dev-1 db │\n│ localhost:63104 ──→ dev-2 web │\n│ localhost:57220 ──→ dev-2 db │\n└──────────────────────────────────────────────────┘\n```\n\n동적 포트는 체크아웃의 영향을 받지 않습니다. 바뀌는 것은 canonical port가 가리키는 대상뿐입니다.\n", "concepts_and_terminology/CLI.md": "# Coast CLI\n\nCoast CLI(`coast`)는 Coast를 운영하기 위한 기본 명령줄 인터페이스입니다. 의도적으로 얇게 설계되어 있습니다: 명령을 파싱하고, [`coastd`](DAEMON.md)에 요청을 보내며, 구조화된 출력을 터미널에 다시 출력합니다.\n\n## 무엇에 사용하나요\n\n일반적인 워크플로는 모두 CLI에서 구동됩니다:\n\n```bash\ncoast build # see Builds\ncoast run dev-1 # see Run\ncoast assign dev-1 --worktree feature/oauth # see Assign\ncoast ports dev-1 # see Ports\ncoast checkout dev-1 # see Checkout\ncoast ui # see Coastguard\n```\n\nCLI에는 사람과 에이전트 모두에게 유용한 문서 명령도 포함되어 있습니다:\n\n```bash\ncoast docs\ncoast docs --path concepts_and_terminology/CHECKOUT.md\ncoast search-docs \"canonical vs dynamic ports\"\n```\n\n## 데몬과 별도로 존재하는 이유\n\nCLI를 데몬과 분리하면 몇 가지 중요한 이점이 있습니다:\n\n- 데몬은 상태와 장시간 실행되는 프로세스를 유지합니다.\n- CLI는 빠르고, 조합 가능하며, 스크립트 작성이 쉽습니다.\n- 터미널 상태를 계속 유지하지 않고도 일회성 명령을 실행할 수 있습니다.\n- 에이전트 도구는 예측 가능하고 자동화에 친화적인 방식으로 CLI 명령을 호출할 수 있습니다.\n\n## CLI vs Coastguard\n\n그 순간에 맞는 인터페이스를 사용하세요:\n\n- CLI는 전체 운영 범위를 포괄하도록 설계되었습니다: Coastguard에서 할 수 있는 모든 일은 CLI에서도 가능해야 합니다.\n- CLI는 자동화 인터페이스로 취급하세요 — 스크립트, 에이전트 워크플로, CI 작업, 그리고 맞춤형 개발자 도구를 위한 것입니다.\n- [Coastguard](COASTGUARD.md)는 사람을 위한 인터페이스로 취급하세요 — 시각적 점검, 대화형 디버깅, 운영 가시성을 위한 것입니다.\n\n둘 다 동일한 데몬과 통신하므로, 동일한 기반 프로젝트 상태에서 동작합니다.\n", "concepts_and_terminology/COASTFILE_TYPES.md": "# Coastfile 유형\n\n하나의 프로젝트는 서로 다른 사용 사례를 위해 여러 Coastfile을 가질 수 있습니다. 각 변형을 \"유형(type)\"이라고 부릅니다. 유형을 사용하면 공통 기반을 공유하면서도 어떤 서비스가 실행되는지, 볼륨을 어떻게 처리하는지, 또는 서비스가 자동 시작되는지 여부가 다른 구성을 조합할 수 있습니다.\n\n## 유형이 동작하는 방식\n\n이름 규칙은 기본은 `Coastfile`, 변형은 `Coastfile.{type}`입니다. 점 뒤의 접미사가 유형 이름이 됩니다:\n\n- `Coastfile` -- 기본 유형\n- `Coastfile.test` -- 테스트 유형\n- `Coastfile.snap` -- 스냅샷 유형\n- `Coastfile.light` -- 경량 유형\n\n`--type`으로 유형이 지정된 Coast를 빌드하고 실행합니다:\n\n```bash\ncoast build --type test\ncoast run test-1 --type test\ncoast exec test-1 -- go test ./...\n```\n\n## extends\n\n유형이 지정된 Coastfile은 `extends`를 통해 부모로부터 상속합니다. 부모의 모든 항목이 병합됩니다. 자식은 오버라이드하거나 추가하는 것만 지정하면 됩니다.\n\n```toml\n[coast]\nextends = \"Coastfile\"\n```\n\n이를 통해 각 변형마다 전체 구성을 중복하지 않아도 됩니다. 자식은 부모로부터 모든 [ports](PORTS.md), [secrets](SECRETS.md), [volumes](VOLUMES.md), [shared services](SHARED_SERVICES.md), [assign strategies](ASSIGN.md), 설정 명령, 그리고 [MCP](MCP_SERVERS.md) 구성을 상속합니다. 자식이 정의한 모든 것은 부모보다 우선합니다.\n\n## [unset]\n\n부모로부터 상속된 특정 항목을 이름으로 제거합니다. `ports`, `shared_services`, `secrets`, `volumes`를 unset할 수 있습니다.\n\n```toml\n[unset]\nports = [\"web\", \"redis\", \"backend\"]\nshared_services = [\"postgres\", \"redis\"]\n```\n\n이것이 테스트 변형에서 공유 서비스를 제거하는 방식입니다(그래서 데이터베이스가 격리된 볼륨을 가진 Coast 내부에서 실행됨). 또한 필요하지 않은 포트도 제거합니다.\n\n## [omit]\n\n빌드에서 compose 서비스를 완전히 제거합니다. omit된 서비스는 compose 파일에서 제거되며 Coast 내부에서 전혀 실행되지 않습니다.\n\n```toml\n[omit]\nservices = [\"redis\", \"backend\", \"mailhog\", \"web\"]\n```\n\n변형의 목적과 무관한 서비스를 제외할 때 사용합니다. 테스트 변형은 데이터베이스, 마이그레이션, 테스트 러너만 남길 수 있습니다.\n\n## autostart\n\nCoast가 시작될 때 `docker compose up`을 자동으로 실행할지 제어합니다. 기본값은 `true`입니다.\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n```\n\n전체 스택을 올리는 대신 특정 명령을 수동으로 실행하고 싶은 변형에는 `autostart = false`를 설정하세요. 이는 테스트 러너에서 흔합니다 -- Coast를 만든 다음 [`coast exec`](EXEC_AND_DOCKER.md)로 개별 테스트 스위트를 실행합니다.\n\n## 일반적인 패턴\n\n### 테스트 변형\n\n테스트 실행에 필요한 것만 유지하는 `Coastfile.test`:\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n\n[unset]\nports = [\"web\", \"redis\", \"backend\"]\nshared_services = [\"postgres\", \"redis\"]\n\n[omit]\nservices = [\"redis\", \"backend\", \"mailhog\", \"web\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[assign]\ndefault = \"none\"\n[assign.services]\ntest-runner = \"rebuild\"\nmigrations = \"rebuild\"\n```\n\n각 테스트 Coast는 자체의 깨끗한 데이터베이스를 갖습니다. 테스트는 내부 compose 네트워크를 통해 서비스와 통신하므로 어떤 포트도 노출되지 않습니다. `autostart = false`는 `coast exec`로 테스트 실행을 수동으로 트리거한다는 의미입니다.\n\n### 스냅샷 변형\n\n호스트의 기존 데이터베이스 볼륨 복사본으로 각 Coast를 시드하는 `Coastfile.snap`:\n\n```toml\n[coast]\nextends = \"Coastfile\"\n\n[unset]\nshared_services = [\"postgres\", \"redis\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"my_project_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"my_project_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n```\n\n공유 서비스를 unset하여 데이터베이스가 각 Coast 내부에서 실행되도록 합니다. `snapshot_source`는 빌드 시점에 기존 호스트 볼륨에서 격리된 볼륨을 시드합니다. 생성 이후에는 각 인스턴스의 데이터가 서로 독립적으로 분기됩니다.\n\n### 경량 변형\n\n특정 워크플로를 위해 프로젝트를 최소 구성으로 줄이는 `Coastfile.light` -- 예를 들어 빠른 반복을 위해 백엔드 서비스와 해당 데이터베이스만 남길 수 있습니다.\n\n## 독립적인 빌드 풀\n\n각 유형은 자체 `latest-{type}` 심볼릭 링크와 자체 5개 빌드 자동 프루닝 풀을 갖습니다:\n\n```bash\ncoast build # latest 업데이트, 기본 빌드 프루닝\ncoast build --type test # latest-test 업데이트, test 빌드 프루닝\ncoast build --type snap # latest-snap 업데이트, snap 빌드 프루닝\n```\n\n`test` 유형을 빌드해도 `default` 또는 `snap` 빌드에는 영향을 주지 않습니다. 프루닝은 유형별로 완전히 독립적입니다.\n\n## 유형이 지정된 Coast 실행\n\n`--type`으로 생성된 인스턴스는 해당 유형으로 태그됩니다. 같은 프로젝트에 대해 서로 다른 유형의 인스턴스를 동시에 실행할 수 있습니다:\n\n```bash\ncoast run dev-1 # 기본 유형\ncoast run test-1 --type test # 테스트 유형\ncoast run snapshot-1 --type snap # 스냅샷 유형\n\ncoast ls\n# 세 개 모두 표시되며, 각각 고유한 유형, 포트, 볼륨 전략을 가짐\n```\n\n이렇게 하면 동일한 프로젝트에 대해 전체 개발 환경을 실행하면서도 격리된 테스트 러너와 스냅샷으로 시드된 인스턴스를 함께, 동시에 실행할 수 있습니다.\n", "concepts_and_terminology/COASTGUARD.md": "# Coastguard\n\nCoastguard는 Coast의 로컬 웹 UI(예: Coast의 Docker Desktop 스타일 인터페이스)로, `31415` 포트에서 실행됩니다. CLI에서 실행합니다:\n\n```bash\ncoast ui\n```\n\n![Coastguard project overview](../../assets/coastguard-overview.png)\n*실행 중인 Coast 인스턴스, 해당 브랜치/워크트리, 그리고 체크아웃 상태를 보여주는 프로젝트 대시보드.*\n\n![Coastguard port mappings](../../assets/coastguard-ports.png)\n*특정 Coast 인스턴스의 포트 페이지로, 각 서비스에 대한 표준(canonical) 및 동적 포트 매핑을 보여줍니다.*\n\n## Coastguard가 유용한 점\n\nCoastguard는 프로젝트를 위한 시각적 제어 및 관측(Observability) 표면을 제공합니다:\n\n- 프로젝트, 인스턴스, 상태, 브랜치, 체크아웃 상태를 확인합니다.\n- [포트 매핑](PORTS.md)을 검사하고 서비스로 바로 이동합니다.\n- [로그](LOGS.md), 런타임 통계, 그리고 데이터를 검사합니다.\n- [빌드](BUILDS.md), 이미지 아티팩트, [볼륨](VOLUMES.md), [시크릿](SECRETS.md) 메타데이터를 탐색합니다.\n- 작업 중 앱 내에서 문서를 탐색합니다.\n\n## CLI 및 데몬과의 관계\n\nCoastguard는 CLI를 대체하지 않습니다. 사람 중심의 인터페이스로서 이를 보완합니다.\n\n- [`coast` CLI](CLI.md)는 스크립트, 에이전트 워크플로, 툴링 통합을 위한 자동화 인터페이스입니다.\n- Coastguard는 시각적 점검, 대화형 디버깅, 일상적인 운영 가시성을 위한 사람 중심의 인터페이스입니다.\n- 둘 다 [`coastd`](DAEMON.md)의 클라이언트이므로 동기화를 유지합니다.\n", "concepts_and_terminology/COASTS.md": "# 코스트\n\n코스트는 프로젝트의 독립 실행형 런타임입니다. 이는 [Docker-in-Docker 컨테이너](RUNTIMES_AND_SERVICES.md) 내부에서 실행되며, 여러 서비스(웹 서버, 데이터베이스, 캐시 등)가 모두 하나의 코스트 인스턴스 내부에서 실행될 수 있습니다.\n\n```text\n┌─── Coast: dev-1 (branch: feature/oauth) ──────────────┐\n│ │\n│ ┌─────────┐ ┌──────────┐ ┌─────────┐ │\n│ │ web │ │ postgres │ │ redis │ │\n│ │ :3000 │ │ :5432 │ │ :6379 │ │\n│ └─────────┘ └──────────┘ └─────────┘ │\n│ │\n│ dynamic ports: 62217, 55681, 56905 │\n└───────────────────────────────────────────────────────┘\n\n┌─── Coast: dev-2 (branch: feature/billing) ────────────┐\n│ │\n│ ┌─────────┐ ┌──────────┐ ┌─────────┐ │\n│ │ web │ │ postgres │ │ redis │ │\n│ │ :3000 │ │ :5432 │ │ :6379 │ │\n│ └─────────┘ └──────────┘ └─────────┘ │\n│ │\n│ dynamic ports: 63104, 57220, 58412 │\n└───────────────────────────────────────────────────────┘\n```\n\n각 코스트는 호스트 머신에 자체 [동적 포트](PORTS.md) 집합을 노출하므로, 다른 무엇이 실행 중이든 언제든지 실행 중인 어떤 코스트에도 접근할 수 있습니다.\n\n코스트를 [체크아웃](CHECKOUT.md)하면 프로젝트의 표준 포트가 해당 코스트에 매핑됩니다 — 따라서 `localhost:3000`은 동적 포트가 아니라 체크아웃된 코스트에 연결됩니다.\n\n```text\ncoast checkout dev-1\n\nlocalhost:3000 ──→ dev-1 web\nlocalhost:5432 ──→ dev-1 postgres\nlocalhost:6379 ──→ dev-1 redis\n\ncoast checkout dev-2 (instant swap)\n\nlocalhost:3000 ──→ dev-2 web\nlocalhost:5432 ──→ dev-2 postgres\nlocalhost:6379 ──→ dev-2 redis\n```\n\n일반적으로 코스트는 [특정 워크트리](ASSIGN.md)에 할당됩니다. 이것이 동일한 프로젝트의 여러 워크트리를 포트 충돌이나 볼륨 충돌 없이 병렬로 실행하는 방법입니다.\n\n코스트 인스턴스는 [`coast run`](RUN.md)으로 생성합니다. 코스트를 언제 올리고 내릴지는 필요에 따라 직접 결정하면 됩니다. 메모리를 많이 사용하는 프로젝트의 코스트 20개를 한꺼번에 실행하고 싶지는 않을 가능성이 크지만, 그건 각자 선택입니다.\n", "concepts_and_terminology/DAEMON.md": "# Coast 데몬\n\nCoast 데몬(`coastd`)은 실제 오케스트레이션 작업을 수행하는 장시간 실행되는 로컬 프로세스입니다. [CLI](CLI.md)와 [Coastguard](COASTGUARD.md)는 클라이언트이며, `coastd`는 그 뒤에 있는 제어 평면입니다.\n\n## 아키텍처 한눈에 보기\n\n```text\ncoast CLI (automation) -----+\n +--> coastd daemon\nCoastguard UI (human) ------+ |\n +--> Coasts\n +--> Ports\n +--> State\n```\n\nCLI는 로컬 Unix 소켓을 통해 `coastd`로 요청을 보내며, Coastguard는 WebSocket을 통해 연결합니다. 데몬은 런타임 상태에 변경 사항을 적용합니다.\n\n## 하는 일\n\n`coastd`는 영속적인 상태와 백그라운드 조정이 필요한 작업을 처리합니다:\n\n- Coast 인스턴스, 빌드, 공유 서비스를 추적합니다.\n- Coast 런타임을 생성, 시작, 중지, 제거합니다.\n- 할당/할당 해제/체크아웃 작업을 적용합니다.\n- 정적 및 동적 [포트 포워딩](PORTS.md)을 관리합니다.\n- [로그](LOGS.md), 상태, 런타임 이벤트를 CLI 및 UI 클라이언트로 스트리밍합니다.\n\n요약하면: `coast run`, `coast assign`, `coast checkout`, `coast ls`를 실행할 때 실제로 작업을 수행하는 구성 요소는 데몬입니다.\n\n## 실행 방법\n\n데몬을 실행하는 일반적인 방법은 두 가지입니다:\n\n```bash\n# Register daemon auto-start at login (recommended)\ncoast daemon install\n\n# Manual start mode\ncoast daemon start\n```\n\ndaemon install을 건너뛰면, Coast 명령을 사용하기 전에 매 세션마다 직접 시작해야 합니다.\n\n## 버그 제보\n\n문제가 발생하면 버그 리포트를 제출할 때 `coastd` 데몬 로그를 포함해 주세요. 로그에는 대부분의 문제를 진단하는 데 필요한 컨텍스트가 담겨 있습니다:\n\n```bash\ncoast daemon logs\n```\n", - "concepts_and_terminology/EXEC_AND_DOCKER.md": "# Exec & Docker\n\n`coast exec`는 Coast의 DinD 컨테이너 안의 셸로 들어가게 해줍니다. 작업 디렉터리는 `/workspace` — Coastfile이 있는 [바인드 마운트된 프로젝트 루트](FILESYSTEM.md)입니다. 이는 호스트 머신에서 Coast 내부의 명령을 실행하고, 파일을 살펴보거나, 서비스를 디버깅하는 기본 방법입니다.\n\n`coast docker`는 내부 Docker 데몬과 직접 통신하기 위한 동반 명령입니다.\n\n## `coast exec`\n\nCoast 인스턴스 내부에서 셸을 엽니다:\n\n```bash\ncoast exec dev-1\n```\n\n이 명령은 `/workspace`에서 `sh` 세션을 시작합니다. Coast 컨테이너는 Alpine 기반이므로 기본 셸은 `bash`가 아니라 `sh`입니다.\n\n대화형 셸에 들어가지 않고 특정 명령만 실행할 수도 있습니다:\n\n```bash\ncoast exec dev-1 ls -la\ncoast exec dev-1 -- npm install\ncoast exec dev-1 -- go test ./...\n```\n\n인스턴스 이름 뒤의 모든 내용은 명령으로 전달됩니다. `--`를 사용해, 실행하려는 명령에 속한 플래그와 `coast exec`에 속한 플래그를 구분하세요.\n\n### Working Directory\n\n셸은 `/workspace`에서 시작하며, 이는 호스트의 프로젝트 루트가 컨테이너에 바인드 마운트된 것입니다. 즉, 소스 코드, Coastfile, 그리고 모든 프로젝트 파일이 바로 그곳에 있습니다:\n\n```text\n/workspace $ ls\nCoastfile README.md apps/ packages/\nCoastfile.light go.work infra/ scripts/\nCoastfile.snap go.work.sum package-lock.json\n```\n\n`/workspace` 아래의 파일을 변경하면 호스트에 즉시 반영됩니다 — 복사본이 아니라 바인드 마운트입니다.\n\n### Interactive vs Non-Interactive\n\nstdin이 TTY(터미널에서 직접 타이핑)일 때, `coast exec`는 데몬을 완전히 우회하고 전체 TTY 패스스루를 위해 `docker exec -it`를 직접 실행합니다. 이는 색상, 커서 이동, 탭 자동완성, 대화형 프로그램이 모두 기대한 대로 동작한다는 뜻입니다.\n\nstdin이 파이프되거나 스크립트로 실행될 때(CI, 에이전트 워크플로, `coast exec dev-1 -- some-command | grep foo`), 요청은 데몬을 통해 처리되며 구조화된 stdout, stderr, 그리고 종료 코드를 반환합니다.\n\n### File Permissions\n\nexec는 호스트 사용자와 동일한 UID:GID로 실행되므로, Coast 내부에서 생성된 파일은 호스트에서 올바른 소유권을 갖습니다. 호스트와 컨테이너 사이에 권한 불일치가 없습니다.\n\n## `coast docker`\n\n`coast exec`가 DinD 컨테이너 자체 안에서 셸을 제공하는 반면, `coast docker`는 **내부** Docker 데몬 — compose 서비스를 관리하는 데몬 — 을 대상으로 Docker CLI 명령을 실행할 수 있게 해줍니다.\n\n```bash\ncoast docker dev-1 # defaults to: docker ps\ncoast docker dev-1 ps # same as above\ncoast docker dev-1 compose ps # docker compose ps (inner services)\ncoast docker dev-1 images # list images in the inner daemon\ncoast docker dev-1 compose logs web # docker compose logs for a service\n```\n\n전달하는 모든 명령은 자동으로 `docker`가 접두사로 붙습니다. 따라서 `coast docker dev-1 compose ps`는 Coast 컨테이너 내부에서 `docker compose ps`를 실행하며, 내부 데몬과 통신합니다.\n\n### `coast exec` vs `coast docker`\n\n차이는 무엇을 대상으로 하느냐입니다:\n\n| Command | Runs as | Target |\n|---|---|---|\n| `coast exec dev-1 ls /workspace` | `sh -c \"ls /workspace\"` in DinD container | Coast 컨테이너 자체 (프로젝트 파일, 설치된 도구) |\n| `coast docker dev-1 ps` | `docker ps` in DinD container | 내부 Docker 데몬 (compose 서비스 컨테이너) |\n| `coast docker dev-1 compose logs web` | `docker compose logs web` in DinD container | 내부 데몬을 통해 특정 compose 서비스의 로그 |\n\n프로젝트 수준 작업 — 테스트 실행, 의존성 설치, 파일 검사 — 에는 `coast exec`를 사용하세요. 내부 Docker 데몬이 무엇을 하고 있는지 — 컨테이너 상태, 이미지, 네트워크, compose 작업 — 확인해야 할 때는 `coast docker`를 사용하세요.\n\n## Coastguard Exec Tab\n\nCoastguard 웹 UI는 WebSocket으로 연결된 영구적인 대화형 터미널을 제공합니다.\n\n![Exec tab in Coastguard](../../assets/coastguard-exec.png)\n*Coast 인스턴스 내부의 /workspace에서 셸 세션을 보여주는 Coastguard Exec 탭.*\n\n터미널은 xterm.js로 구동되며 다음을 제공합니다:\n\n- **영구 세션** — 터미널 세션은 페이지 이동과 브라우저 새로고침 이후에도 유지됩니다. 재연결 시 스크롤백 버퍼를 재생하여 중단한 지점부터 이어갈 수 있습니다.\n- **여러 탭** — 여러 셸을 동시에 열 수 있습니다. 각 탭은 독립적인 세션입니다.\n- **[에이전트 셸](AGENT_SHELLS.md) 탭** — AI 코딩 에이전트를 위한 전용 에이전트 셸을 생성하며, 활성/비활성 상태 추적을 지원합니다.\n- **전체 화면 모드** — 터미널을 화면 전체로 확장합니다(나가려면 Escape).\n\n인스턴스 수준의 exec 탭을 넘어, Coastguard는 다른 수준에서도 터미널 접근을 제공합니다:\n\n- **서비스 exec** — Services 탭에서 개별 서비스를 클릭하여 해당 특정 내부 컨테이너에서 셸을 엽니다(이는 `docker exec`를 두 번 수행합니다 — 먼저 DinD 컨테이너로, 그다음 서비스 컨테이너로).\n- **[공유 서비스](SHARED_SERVICES.md) exec** — 호스트 수준의 공유 서비스 컨테이너 내부에서 셸을 엽니다.\n- **호스트 터미널** — Coast에 들어가지 않고도, 프로젝트 루트에서 호스트 머신의 셸을 제공합니다.\n\n## When to Use Which\n\n- **`coast exec`** — DinD 컨테이너 내부에서 프로젝트 수준 명령(npm install, go test, 파일 검사, 디버깅)을 실행합니다.\n- **`coast docker`** — 내부 Docker 데몬을 점검하거나 관리합니다(컨테이너 상태, 이미지, 네트워크, compose 작업).\n- **Coastguard Exec tab** — 영구 세션, 여러 탭, 에이전트 셸 지원을 통한 대화형 디버깅. UI의 나머지 부분을 탐색하면서 여러 터미널을 열어두고 싶을 때 가장 적합합니다.\n- **`coast logs`** — 서비스 출력을 읽을 때는 `coast docker compose logs` 대신 `coast logs`를 사용하세요. [Logs](LOGS.md)를 참고하세요.\n- **`coast ps`** — 서비스 상태를 확인할 때는 `coast docker compose ps` 대신 `coast ps`를 사용하세요. [Runtimes and Services](RUNTIMES_AND_SERVICES.md)를 참고하세요.\n", + "concepts_and_terminology/EXEC_AND_DOCKER.md": "# Exec & Docker\n\n`coast exec`는 Coast의 DinD 컨테이너 내부의 셸로 들어가게 해줍니다. 작업 디렉터리는 `/workspace`이며, 이는 Coastfile이 위치한 [바인드 마운트된 프로젝트 루트](FILESYSTEM.md)입니다. 이것은 호스트 머신에서 Coast 내부의 명령을 실행하고, 파일을 확인하거나, 서비스를 디버그하는 기본 방법입니다.\n\n`coast docker`는 내부 Docker 데몬과 직접 통신하기 위한 짝이 되는 명령입니다.\n\n## `coast exec`\n\nCoast 인스턴스 내부에서 셸 열기:\n\n```bash\ncoast exec dev-1\n```\n\n이 명령은 `/workspace`에서 `sh` 세션을 시작합니다. Coast 컨테이너는 Alpine 기반이므로 기본 셸은 `bash`가 아니라 `sh`입니다.\n\n대화형 셸에 들어가지 않고 특정 명령만 실행할 수도 있습니다:\n\n```bash\ncoast exec dev-1 ls -la\ncoast exec dev-1 -- npm install\ncoast exec dev-1 -- go test ./...\ncoast exec dev-1 --service web\ncoast exec dev-1 --service web -- php artisan test\n```\n\n인스턴스 이름 뒤의 모든 내용은 명령으로 전달됩니다. `coast exec`에 속한 플래그와 여러분의 명령에 속한 플래그를 구분하려면 `--`를 사용하세요.\n\n외부 Coast 컨테이너 대신 특정 compose 서비스 컨테이너를 대상으로 하려면 `--service `을 전달하세요. Coast의 기본 호스트 UID:GID 매핑 대신 순수한 컨테이너 루트 접근이 필요할 때는 `--root`를 전달하세요.\n\n### Working Directory\n\n셸은 `/workspace`에서 시작하며, 이는 호스트 프로젝트 루트가 컨테이너에 바인드 마운트된 위치입니다. 즉, 소스 코드, Coastfile, 그리고 모든 프로젝트 파일이 바로 그곳에 있습니다:\n\n```text\n/workspace $ ls\nCoastfile README.md apps/ packages/\nCoastfile.light go.work infra/ scripts/\nCoastfile.snap go.work.sum package-lock.json\n```\n\n`/workspace` 아래의 파일에 변경을 가하면 그 내용은 즉시 호스트에 반영됩니다 — 이것은 복사본이 아니라 바인드 마운트입니다.\n\n### Interactive vs Non-Interactive\n\nstdin이 TTY인 경우(터미널에 직접 입력 중일 때), `coast exec`는 데몬을 완전히 우회하고 전체 TTY 패스스루를 위해 직접 `docker exec -it`를 실행합니다. 즉, 색상, 커서 이동, 탭 완성, 대화형 프로그램이 모두 예상대로 동작합니다.\n\nstdin이 파이프로 전달되거나 스크립트에서 실행되는 경우(CI, 에이전트 워크플로, `coast exec dev-1 -- some-command | grep foo`), 요청은 데몬을 통해 전달되며 구조화된 stdout, stderr, 그리고 종료 코드를 반환합니다.\n\n### File Permissions\n\nexec는 호스트 사용자 UID:GID로 실행되므로 Coast 내부에서 생성된 파일은 호스트에서도 올바른 소유권을 가집니다. 호스트와 컨테이너 사이에 권한 불일치가 발생하지 않습니다.\n\n## `coast docker`\n\n`coast exec`가 DinD 컨테이너 자체 안의 셸을 제공하는 반면, `coast docker`는 **내부** Docker 데몬 — 즉 compose 서비스를 관리하는 데몬 — 을 대상으로 Docker CLI 명령을 실행할 수 있게 해줍니다.\n\n```bash\ncoast docker dev-1 # 기본값: docker ps\ncoast docker dev-1 ps # 위와 동일\ncoast docker dev-1 compose ps # 현재 Coast가 관리하는 활성 스택에 대한 docker compose ps\ncoast docker dev-1 images # 내부 데몬의 이미지 목록\ncoast docker dev-1 compose logs web # 서비스에 대한 docker compose logs\n```\n\n여러분이 전달하는 모든 명령 앞에는 자동으로 `docker`가 붙습니다. 따라서 `coast docker dev-1 compose ps`는 내부 데몬과 통신하면서 Coast 컨테이너 안에서 `docker compose ps`를 실행합니다.\n\n### `coast exec` vs `coast docker`\n\n차이는 무엇을 대상으로 하느냐입니다:\n\n| Command | Runs as | Target |\n|---|---|---|\n| `coast exec dev-1 ls /workspace` | DinD 컨테이너에서 `sh -c \"ls /workspace\"` | Coast 컨테이너 자체 (프로젝트 파일, 설치된 도구) |\n| `coast exec dev-1 --service web` | 확인된 내부 서비스 컨테이너에서 `docker exec ... sh` | 특정 compose 서비스 컨테이너 |\n| `coast docker dev-1 ps` | DinD 컨테이너에서 `docker ps` | 내부 Docker 데몬 (compose 서비스 컨테이너들) |\n| `coast docker dev-1 compose logs web` | DinD 컨테이너에서 `docker compose logs web` | 내부 데몬을 통한 특정 compose 서비스의 로그 |\n\n프로젝트 수준 작업 — 테스트 실행, 의존성 설치, 파일 확인 — 에는 `coast exec`를 사용하세요. 내부 Docker 데몬이 무엇을 하고 있는지 — 컨테이너 상태, 이미지, 네트워크, compose 작업 — 확인해야 할 때는 `coast docker`를 사용하세요.\n\n## Coastguard Exec Tab\n\nCoastguard 웹 UI는 WebSocket으로 연결되는 지속형 대화형 터미널을 제공합니다.\n\n![Exec tab in Coastguard](../../assets/coastguard-exec.png)\n*Coast 인스턴스 내부 /workspace에서 셸 세션을 보여주는 Coastguard Exec 탭.*\n\n이 터미널은 xterm.js로 구동되며 다음을 제공합니다:\n\n- **지속형 세션** — 터미널 세션은 페이지 이동과 브라우저 새로고침 후에도 유지됩니다. 다시 연결하면 스크롤백 버퍼가 재생되어 중단한 지점부터 이어갈 수 있습니다.\n- **여러 탭** — 여러 셸을 동시에 열 수 있습니다. 각 탭은 독립적인 세션입니다.\n- **[Agent shell](AGENT_SHELLS.md) tabs** — AI 코딩 에이전트를 위한 전용 에이전트 셸을 생성하며, 활성/비활성 상태 추적을 지원합니다.\n- **전체 화면 모드** — 터미널을 화면 전체로 확장합니다(종료하려면 Escape).\n\n인스턴스 수준의 exec 탭 외에도 Coastguard는 다른 수준의 터미널 접근도 제공합니다:\n\n- **Service exec** — Services 탭에서 개별 서비스를 클릭하면 해당 특정 내부 컨테이너 안의 셸로 들어갈 수 있습니다(이 경우 `docker exec`를 두 번 수행합니다 — 먼저 DinD 컨테이너로, 그다음 서비스 컨테이너로).\n- **[Shared service](SHARED_SERVICES.md) exec** — 호스트 수준 공유 서비스 컨테이너 내부의 셸로 들어갑니다.\n- **Host terminal** — Coast에 전혀 들어가지 않고 프로젝트 루트에서 호스트 머신의 셸을 엽니다.\n\n## When to Use Which\n\n- **`coast exec`** — DinD 컨테이너 내부에서 프로젝트 수준 명령을 실행하거나, `--service`를 전달해 특정 compose 서비스 컨테이너 안에서 셸을 열거나 명령을 실행합니다.\n- **`coast docker`** — 내부 Docker 데몬을 점검하거나 관리합니다(컨테이너 상태, 이미지, 네트워크, compose 작업).\n- **Coastguard Exec tab** — 지속형 세션, 여러 탭, 에이전트 셸 지원이 있는 대화형 디버깅용입니다. UI의 나머지 부분을 탐색하면서 여러 터미널을 열어두고 싶을 때 가장 적합합니다.\n- **`coast logs`** — 서비스 출력을 읽을 때는 `coast docker compose logs` 대신 `coast logs`를 사용하세요. [Logs](LOGS.md)를 참조하세요.\n- **`coast ps`** — 서비스 상태를 확인할 때는 `coast docker compose ps` 대신 `coast ps`를 사용하세요. [Runtimes and Services](RUNTIMES_AND_SERVICES.md)를 참조하세요.\n", "concepts_and_terminology/FILESYSTEM.md": "# 파일시스템\n\n호스트 머신과 모든 Coast 인스턴스는 동일한 프로젝트 파일을 공유합니다. 호스트 프로젝트 루트는 DinD 컨테이너의 `/host-project`에 읽기-쓰기(RW)로 마운트되고, Coast는 활성 작업 트리를 `/workspace`에 바인드 마운트합니다. 이것이 호스트 머신에서 실행 중인 에이전트가 코드를 편집하면 Coast 내부의 서비스가 변경 사항을 실시간으로 반영할 수 있는 이유입니다.\n\n## 공유 마운트\n\n```text\nHost machine\n│\n├── ~/dev/my-app/ (project root)\n│ ├── src/\n│ ├── Coastfile\n│ ├── docker-compose.yml\n│ └── .worktrees/ (worktrees, gitignored)\n│ ├── feature-auth/\n│ └── feature-billing/\n│\n└── Docker daemon (host)\n │\n └── Coast: dev-1 (docker:dind)\n │\n ├── /host-project ← Docker bind mount of project root (RW, fixed)\n │\n ├── /workspace ← mount --bind /host-project (switchable)\n │ ├── src/ same files, same bytes, instant sync\n │ ├── Coastfile\n │ └── docker-compose.yml\n │\n └── Inner Docker daemon\n └── web service\n └── /app ← compose bind mount from /workspace/src\n```\n\n호스트 프로젝트 루트는 컨테이너가 생성될 때 [DinD 컨테이너](RUNTIMES_AND_SERVICES.md) 내부의 `/host-project`에 읽기-쓰기(RW)로 마운트됩니다. 컨테이너가 시작된 뒤, 컨테이너 내부에서 `mount --bind /host-project /workspace`를 실행하여 공유 마운트 전파(`mount --make-rshared`)가 적용된 작업 경로 `/workspace`를 생성하므로, `/workspace`의 하위 디렉터리를 바인드 마운트하는 내부 compose 서비스들이 올바른 내용을 보게 됩니다.\n\n이 두 단계 접근 방식에는 이유가 있습니다. `/host-project`의 Docker 바인드 마운트는 컨테이너 생성 시점에 고정되며, 컨테이너를 재생성하지 않고는 변경할 수 없습니다. 하지만 컨테이너 내부의 Linux 바인드 마운트인 `/workspace`는 컨테이너 라이프사이클을 건드리지 않고도 언마운트한 뒤 다른 하위 디렉터리(워크트리)로 다시 바인드할 수 있습니다. 이것이 `coast assign`이 빠른 이유입니다.\n\n`/workspace`는 읽기-쓰기(RW)입니다. 파일 변경은 양방향으로 즉시 전파됩니다. 호스트에서 파일을 저장하면 Coast 내부의 개발 서버가 이를 반영합니다. Coast 내부에서 파일을 생성하면 호스트에 나타납니다.\n\n## 호스트 에이전트와 Coast\n\n```text\n┌─── Host machine ──────────────────────────────────────────┐\n│ │\n│ AI Agent (Cursor, Claude Code, etc.) │\n│ │ │\n│ ├── reads/writes files at /src/ │\n│ │ ↕ (instant, same filesystem) │\n│ ├── coast logs dev-1 --service web --tail 50 │\n│ ├── coast ps dev-1 │\n│ └── coast exec dev-1 -- npm test │\n│ │\n├───────────────────────────────────────────────────────────┤\n│ │\n│ Coast: dev-1 │\n│ └── /workspace/src/ ← same bytes as host project/src │\n│ └── web service picks up changes on save │\n│ │\n└───────────────────────────────────────────────────────────┘\n```\n\n파일시스템이 공유되므로, 호스트에서 실행되는 AI 코딩 에이전트는 파일을 자유롭게 편집할 수 있고 Coast 내부에서 실행 중인 서비스는 변경 사항을 즉시 확인합니다. 에이전트는 Coast 컨테이너 내부에서 실행될 필요가 없으며, 평소처럼 호스트에서 동작합니다.\n\n에이전트가 런타임 정보(로그, 서비스 상태, 테스트 출력)가 필요할 때는 호스트에서 Coast CLI 명령을 호출합니다:\n\n- `coast logs dev-1 --service web --tail 50` 서비스 출력(참고: [Logs](LOGS.md))\n- `coast ps dev-1` 서비스 상태(참고: [Runtimes and Services](RUNTIMES_AND_SERVICES.md))\n- `coast exec dev-1 -- npm test` Coast 내부에서 명령 실행(참고: [Exec & Docker](EXEC_AND_DOCKER.md))\n\n이것이 근본적인 아키텍처상의 장점입니다: **코드 편집은 호스트에서, 런타임은 Coast에서 이루어지며, 공유 파일시스템이 둘을 연결합니다.** 호스트 에이전트는 작업을 수행하기 위해 Coast “안”에 있을 필요가 전혀 없습니다.\n\n## 워크트리 전환\n\n`coast assign`이 Coast를 다른 워크트리로 전환할 때, 프로젝트 루트 대신 해당 git 워크트리를 가리키도록 `/workspace`를 다시 마운트합니다:\n\n```text\ncoast assign dev-1 --worktree feature-auth\n\nBefore: /workspace ←──mount── /host-project (project root)\nAfter: /workspace ←──mount── /host-project/.worktrees/feature-auth (worktree)\n```\n\n워크트리는 호스트의 `{project_root}/.worktrees/{worktree_name}`에 생성됩니다. `.worktrees` 디렉터리 이름은 Coastfile의 `worktree_dir`로 설정 가능하며, `.gitignore`에 포함되어야 합니다.\n\n워크트리가 새로 만들어진 경우, Coast는 리마운트 전에 프로젝트 루트에서 선택된 gitignored 파일을 부트스트랩합니다. `git ls-files --others --ignored --exclude-standard`로 무시된 파일을 나열하고, 일반적으로 용량이 큰 디렉터리와 설정된 `exclude_paths`를 제외하도록 필터링한 다음, `--link-dest`와 함께 `rsync --files-from`를 사용해 선택된 파일을 워크트리에 하드링크합니다. Coast는 그 부트스트랩을 내부 워크트리 메타데이터에 기록하며, `coast assign --force-sync`로 명시적으로 새로 고치지 않는 한 동일한 워크트리에 대한 이후 assign에서는 이를 건너뜁니다.\n\n컨테이너 내부에서는 `/workspace`를 lazy-unmount한 뒤 `/host-project/.worktrees/{branch_name}`의 워크트리 하위 디렉터리에 다시 바인드합니다. 이 리마운트는 빠르며 DinD 컨테이너를 재생성하거나 내부 Docker 데몬을 재시작하지 않습니다. 다만 compose 및 bare 서비스는 새 `/workspace`를 통해 바인드 마운트가 해석되도록 리마운트 이후 재생성되거나 재시작될 수 있습니다.\n\n`node_modules`와 같은 대규모 의존성 디렉터리는 이 일반적인 부트스트랩 경로의 일부가 아닙니다. 이런 것들은 보통 서비스별 캐시나 볼륨으로 처리됩니다.\n\n`[assign.rebuild_triggers]`를 사용하는 경우, Coast는 호스트에서 `git diff --name-only ..`도 실행하여 `rebuild`로 표시된 서비스를 `restart`로 다운그레이드할 수 있는지 결정합니다. assign 지연 시간에 영향을 주는 세부 사항은 [Assign and Unassign](ASSIGN.md) 및 [Performance Optimizations](PERFORMANCE_OPTIMIZATIONS.md)를 참고하세요.\n\n`coast unassign`는 `/workspace`를 `/host-project`(프로젝트 루트)로 되돌립니다. 중지 후 `coast start`는 인스턴스에 워크트리가 할당되어 있는지에 따라 올바른 마운트를 다시 적용합니다.\n\n## 모든 마운트\n\n모든 Coast 컨테이너에는 다음 마운트가 있습니다:\n\n| Path | Type | Access | Purpose |\n|---|---|---|---|\n| `/workspace` | bind mount (in-container) | RW | 프로젝트 루트 또는 워크트리. assign 시 전환 가능. |\n| `/host-project` | Docker bind mount | RW | 원본 프로젝트 루트. 컨테이너 생성 시 고정. |\n| `/image-cache` | Docker bind mount | RO | `~/.coast/image-cache/`의 사전 풀된 OCI tarball. |\n| `/coast-artifact` | Docker bind mount | RO | 재작성된 compose 파일이 포함된 빌드 아티팩트. |\n| `/coast-override` | Docker bind mount | RO | [shared services](SHARED_SERVICES.md)를 위한 생성된 compose 오버라이드. |\n| `/var/lib/docker` | Named volume | RW | 내부 Docker 데몬 상태. 컨테이너 제거 후에도 유지됨. |\n\n읽기 전용(RO) 마운트는 인프라용입니다 — Coast가 생성하는 빌드 아티팩트, 캐시된 이미지, compose 오버라이드를 담고 있습니다. 사용자는 `coast build`와 Coastfile을 통해 간접적으로 이를 다룹니다. 읽기-쓰기(RW) 마운트는 코드가 위치하는 곳이며 내부 데몬이 상태를 저장하는 곳입니다.\n", "concepts_and_terminology/LOGS.md": "# 로그\n\nCoast 내부의 서비스는 중첩 컨테이너에서 실행됩니다 — compose 서비스는 DinD 컨테이너 내부의 내부 Docker 데몬에 의해 관리됩니다. 이는 호스트 수준 로깅 도구가 이를 볼 수 없다는 뜻입니다. 워크플로에 호스트에서 Docker 로그를 읽는 로깅 MCP가 포함되어 있다면, 이는 외부 DinD 컨테이너만 보게 되며 그 안에서 실행되는 웹 서버, 데이터베이스, 워커는 보지 못합니다.\n\n해결책은 `coast logs`입니다. Coast 인스턴스에서 서비스 출력을 읽어야 하는 모든 에이전트나 도구는 호스트 수준 Docker 로그 접근 대신 Coast CLI를 사용해야 합니다.\n\n## MCP의 트레이드오프\n\n로깅 MCP(호스트에서 Docker 컨테이너 로그를 캡처하는 도구 — [MCP Servers](MCP_SERVERS.md) 참조)를 사용하는 AI 에이전트를 사용 중이라면, 해당 MCP는 Coast 내부에서 실행되는 서비스에 대해 작동하지 않습니다. 호스트 Docker 데몬은 Coast 인스턴스당 하나의 컨테이너 — DinD 컨테이너 — 만 보며, 그 로그는 내부 Docker 데몬의 시작 출력일 뿐입니다.\n\n실제 서비스 로그를 캡처하려면, 에이전트가 다음을 사용하도록 지시하세요:\n\n```bash\ncoast logs --service --tail \n```\n\n예를 들어, 에이전트가 백엔드 서비스가 실패하는 이유를 점검해야 한다면:\n\n```bash\ncoast logs dev-1 --service backend --tail 100\n```\n\n이는 `docker compose logs`와 동등하지만, Coast 데몬을 통해 내부 DinD 컨테이너로 라우팅됩니다. 로깅 MCP를 참조하는 에이전트 규칙이나 시스템 프롬프트가 있다면, Coast 내부에서 작업할 때 이 동작을 재정의하는 지시를 추가해야 합니다.\n\n## `coast logs`\n\nCLI는 Coast 인스턴스의 로그를 읽는 여러 가지 방법을 제공합니다:\n\n```bash\ncoast logs dev-1 # last 200 lines, all services\ncoast logs dev-1 --service web # last 200 lines, web only\ncoast logs dev-1 --tail 50 # last 50 lines, then follow\ncoast logs dev-1 --tail # all lines, then follow\ncoast logs dev-1 --service backend -f # follow mode (stream new entries)\ncoast logs dev-1 --service web --tail 100 # last 100 lines + follow\n```\n\n`--tail` 또는 `-f` 없이 실행하면, 명령은 마지막 200줄을 반환하고 종료합니다. `--tail`을 사용하면 요청한 줄 수를 스트리밍한 다음, 새 출력이 생성되는 대로 실시간으로 계속 따라갑니다. `-f` / `--follow`는 단독으로 follow 모드를 활성화합니다.\n\n출력은 각 줄에 서비스 접두사가 붙는 compose 로그 형식을 사용합니다:\n\n```text\nweb | 2026/02/28 01:49:34 Listening on :3000\nbackend | 2026/02/28 01:49:34 [INFO] Server started on :8080\nbackend | 2026/02/28 01:49:34 [ProcessCreditsJob] starting at 2026-02-28T01:49:34Z\nredis | 1:M 28 Feb 2026 01:49:30.123 * Ready to accept connections\n```\n\n레거시 위치 기반 문법(`coast logs dev-1 web`)으로도 서비스를 기준으로 필터링할 수 있지만, `--service` 플래그 사용을 권장합니다.\n\n## Coastguard 로그 탭\n\nCoastguard 웹 UI는 WebSocket을 통한 실시간 스트리밍으로 더 풍부한 로그 뷰잉 경험을 제공합니다.\n\n![Logs tab in Coastguard](../../assets/coastguard-logs.png)\n*서비스 필터링과 검색을 사용해 백엔드 서비스 출력을 스트리밍하는 Coastguard 로그 탭.*\n\n로그 탭은 다음을 제공합니다:\n\n- **실시간 스트리밍** — 로그는 생성되는 대로 WebSocket 연결을 통해 도착하며, 연결 상태를 보여주는 상태 표시기가 있습니다.\n- **서비스 필터** — 로그 스트림의 서비스 접두사로 채워지는 드롭다운입니다. 단일 서비스를 선택해 해당 출력에 집중할 수 있습니다.\n- **검색** — 텍스트 또는 정규식으로 표시된 줄을 필터링합니다(정규식 모드는 별표 버튼을 토글). 일치하는 용어는 하이라이트됩니다.\n- **줄 수** — 필터된 줄 수 대비 전체 줄 수를 표시합니다(예: \"200 / 971 lines\").\n- **지우기** — 내부 컨테이너 로그 파일을 잘라내고 뷰어를 초기화합니다.\n- **전체 화면** — 로그 뷰어를 화면 전체로 확장합니다.\n\n로그 라인은 ANSI 색상 지원, 로그 레벨 하이라이팅(ERROR는 빨강, WARN은 호박색, INFO는 파랑, DEBUG는 회색), 타임스탬프 디밍, 그리고 서비스 간 시각적 구분을 위한 컬러 서비스 배지로 렌더링됩니다.\n\n호스트 데몬에서 실행되는 공유 서비스는 Shared Services 탭에서 접근 가능한 자체 로그 뷰어를 가집니다. 자세한 내용은 [Shared Services](SHARED_SERVICES.md)를 참고하세요.\n\n## 동작 방식\n\n`coast logs`를 실행하면, 데몬은 `docker exec`를 통해 DinD 컨테이너 내부에서 `docker compose logs`를 실행하고 출력을 터미널(또는 WebSocket을 통해 Coastguard UI)로 스트리밍합니다.\n\n```text\ncoast logs dev-1 --service web --tail 50\n │\n ├── CLI sends LogsRequest to daemon (Unix socket)\n │\n ├── Daemon resolves instance → container ID\n │\n ├── Daemon exec's into DinD container:\n │ docker compose logs --tail 50 --follow web\n │\n └── Output streams back chunk by chunk\n └── CLI prints to stdout / Coastguard renders in UI\n```\n\n[bare services](BARE_SERVICES.md)의 경우, 데몬은 `docker compose logs`를 호출하는 대신 `/var/log/coast-services/`의 로그 파일을 tail 합니다. 출력 형식은 동일하며(`service | line`), 따라서 두 경우 모두 서비스 필터링이 동일하게 작동합니다.\n\n## 관련 명령\n\n- `coast ps ` — 어떤 서비스가 실행 중인지와 상태를 확인합니다. [Runtimes and Services](RUNTIMES_AND_SERVICES.md)를 참고하세요.\n- [`coast exec `](EXEC_AND_DOCKER.md) — 수동 디버깅을 위해 Coast 컨테이너 내부에서 셸을 엽니다.\n", "concepts_and_terminology/LOOKUP.md": "# Lookup\n\n`coast lookup`은 호출자의 현재 작업 디렉터리에 대해 어떤 Coast 인스턴스가 실행 중인지 발견합니다. 이는 호스트 측 에이전트가 자신을 정렬하기 위해 가장 먼저 실행해야 하는 명령입니다 — “나는 여기서 코드를 편집하고 있는데, 어떤 Coast(들)과 상호작용해야 하지?”\n\n```bash\ncoast lookup\n```\n\nLookup은 사용자가 [worktree](ASSIGN.md) 안에 있는지 또는 프로젝트 루트에 있는지 감지하고, 일치하는 인스턴스를 데몬에 질의한 뒤, 포트, URL, 예시 명령과 함께 결과를 출력합니다.\n\n## Why This Exists\n\n호스트에서 실행되는 AI 코딩 에이전트(Cursor, Claude Code, Codex 등)는 [shared filesystem](FILESYSTEM.md)을 통해 파일을 편집하고 런타임 작업을 위해 Coast CLI 명령을 호출합니다. 하지만 에이전트는 먼저 기본적인 질문에 답해야 합니다: **내가 작업 중인 디렉터리에 해당하는 Coast 인스턴스는 무엇인가?**\n\n`coast lookup`이 없다면, 에이전트는 `coast ls`를 실행하고, 전체 인스턴스 테이블을 파싱하고, 어떤 worktree에 있는지 파악한 다음, 교차 참조해야 합니다. `coast lookup`은 이 모든 것을 한 단계에서 수행하고 에이전트가 직접 소비할 수 있는 구조화된 출력을 반환합니다.\n\n이 명령은 Coast를 사용하는 에이전트 워크플로를 위한 모든 최상위 SKILL.md, AGENTS.md, 또는 규칙 파일에 포함되어야 합니다. 이는 에이전트가 자신의 런타임 컨텍스트를 발견하기 위한 진입점입니다.\n\n## Output Modes\n\n### Default (human-readable)\n\n```bash\ncoast lookup\n```\n\n```text\nCoast instances for worktree feature/oauth (my-app):\n\n dev-1 running ★ checked out\n\n Primary URL: http://dev-1.localhost:62217\n\n SERVICE CANONICAL DYNAMIC\n ★ web 3000 62217\n api 8080 63889\n postgres 5432 55681\n\n Examples (exec starts at the workspace root where your Coastfile is, cd to your target directory first):\n coast exec dev-1 -- sh -c \"cd && \"\n coast logs dev-1 --service \n coast ps dev-1\n```\n\n예시 섹션은 `coast exec`가 워크스페이스 루트 — Coastfile이 있는 디렉터리 — 에서 시작한다는 점을 에이전트(및 사람)에게 상기시킵니다. 하위 디렉터리에서 명령을 실행하려면 exec 내부에서 해당 디렉터리로 `cd` 하세요.\n\n### Compact (`--compact`)\n\n인스턴스 이름의 JSON 배열을 반환합니다. 어떤 인스턴스를 대상으로 할지만 알면 되는 스크립트 및 에이전트 도구를 위해 설계되었습니다.\n\n```bash\ncoast lookup --compact\n```\n\n```text\n[\"dev-1\"]\n```\n\n동일한 worktree에 여러 인스턴스가 있는 경우:\n\n```text\n[\"dev-1\",\"dev-2\"]\n```\n\n일치 항목이 없는 경우:\n\n```text\n[]\n```\n\n### JSON (`--json`)\n\n전체 구조화된 응답을 보기 좋게 출력된 JSON으로 반환합니다. 포트, URL, 상태를 기계가 읽을 수 있는 형식으로 필요로 하는 에이전트를 위해 설계되었습니다.\n\n```bash\ncoast lookup --json\n```\n\n```json\n{\n \"project\": \"my-app\",\n \"worktree\": \"feature/oauth\",\n \"project_root\": \"/Users/dev/my-app\",\n \"instances\": [\n {\n \"name\": \"dev-1\",\n \"status\": \"Running\",\n \"checked_out\": true,\n \"branch\": \"feature/oauth\",\n \"primary_url\": \"http://dev-1.localhost:62217\",\n \"ports\": [\n { \"logical_name\": \"web\", \"canonical_port\": 3000, \"dynamic_port\": 62217, \"is_primary\": true },\n { \"logical_name\": \"api\", \"canonical_port\": 8080, \"dynamic_port\": 63889, \"is_primary\": false }\n ]\n }\n ]\n}\n```\n\n## How It Resolves\n\nLookup은 현재 작업 디렉터리에서 위로 올라가며 가장 가까운 Coastfile을 찾고, 그다음 어떤 worktree에 있는지 결정합니다:\n\n1. cwd가 `{project_root}/{worktree_dir}/{name}/...` 아래에 있다면, lookup은 해당 worktree에 할당된 인스턴스를 찾습니다.\n2. cwd가 프로젝트 루트(또는 worktree 내부가 아닌 어떤 디렉터리)라면, lookup은 **worktree가 할당되지 않은** 인스턴스 — 즉 프로젝트 루트를 가리키는 인스턴스 — 를 찾습니다.\n\n이는 lookup이 하위 디렉터리에서도 동작한다는 뜻입니다. `my-app/.worktrees/feature-oauth/src/api/`에 있더라도 lookup은 여전히 `feature-oauth`를 worktree로 해석합니다.\n\n## Exit Codes\n\n| Code | Meaning |\n|------|---------|\n| 0 | 하나 이상의 일치하는 인스턴스를 찾음 |\n| 1 | 일치하는 인스턴스가 없음(빈 결과) |\n\n이를 통해 lookup은 셸 조건문에서 사용할 수 있습니다:\n\n```bash\nif coast lookup > /dev/null 2>&1; then\n coast exec dev-1 -- sh -c \"cd src && npm test\"\nfi\n```\n\n## For Agent Workflows\n\n일반적인 에이전트 통합 패턴:\n\n1. 에이전트가 worktree 디렉터리에서 작업을 시작합니다.\n2. 에이전트가 `coast lookup`을 실행해 인스턴스 이름, 포트, URL, 예시 명령을 발견합니다.\n3. 에이전트가 이후의 모든 Coast 명령에서 인스턴스 이름을 사용합니다: `coast exec`, `coast logs`, `coast ps`.\n\n```text\n┌─── Agent (host machine) ────────────────────────────┐\n│ │\n│ 1. coast lookup │\n│ → instance names, ports, URLs, examples │\n│ 2. coast exec dev-1 -- sh -c \"cd src && npm test\" │\n│ 3. coast logs dev-1 --service web --tail 50 │\n│ 4. coast ps dev-1 │\n│ │\n└──────────────────────────────────────────────────────┘\n```\n\n에이전트가 여러 worktree에 걸쳐 작업한다면, 각 worktree 디렉터리에서 `coast lookup`을 실행하여 각 컨텍스트에 맞는 올바른 인스턴스를 해석합니다.\n\n호스트 에이전트가 Coast와 상호작용하는 방식은 [Filesystem](FILESYSTEM.md)을, worktree 개념은 [Assign and Unassign](ASSIGN.md)을, Coast 내부에서 명령을 실행하는 방법은 [Exec & Docker](EXEC_AND_DOCKER.md)을 참고하세요.\n", @@ -1626,13 +1655,20 @@ "concepts_and_terminology/SHARED_SERVICES.md": "# 공유 서비스\n\n공유 서비스는 Coast 내부가 아니라 호스트 Docker 데몬에서 실행되는 데이터베이스 및 인프라 컨테이너(Postgres, Redis, MongoDB 등)입니다. Coast 인스턴스는 브리지 네트워크를 통해 이들에 연결되므로, 모든 Coast는 동일한 호스트 볼륨에 있는 동일한 서비스와 통신합니다.\n\n![Shared services in Coastguard](../../assets/coastguard-shared-services.png)\n*호스트에서 관리되는 Postgres, Redis, MongoDB를 보여주는 Coastguard 공유 서비스 탭.*\n\n## 작동 방식\n\nCoastfile에서 공유 서비스를 선언하면, Coast는 이를 호스트 데몬에서 시작하고 각 Coast 컨테이너 내부에서 실행되는 compose 스택에서는 제거합니다. 그런 다음 Coast는 서비스 이름 기반 트래픽을 공유 컨테이너로 다시 라우팅하도록 구성되며, 이때 Coast 내부에서는 해당 서비스의 컨테이너 측 포트가 그대로 유지됩니다.\n\n```text\nHost Docker daemon\n |\n +--> postgres (host volume: infra_postgres_data)\n +--> redis (host volume: infra_redis_data)\n +--> mongodb (host volume: infra_mongodb_data)\n |\n +--> Coast: dev-1 --bridge network--> host postgres, redis, mongodb\n +--> Coast: dev-2 --bridge network--> host postgres, redis, mongodb\n```\n\n공유 서비스는 기존 호스트 볼륨을 재사용하므로, 로컬에서 `docker-compose up`을 실행하며 이미 가지고 있던 데이터는 즉시 Coasts에서 사용할 수 있습니다.\n\n이 구분은 매핑된 포트를 사용할 때 중요합니다:\n\n```toml\n[shared_services.postgis]\nimage = \"ghcr.io/baosystems/postgis:12-3.3\"\nports = [\"5433:5432\"]\n```\n\n- 호스트에서는 공유 서비스가 `localhost:5433`으로 게시됩니다.\n- 각 Coast 내부에서는 앱 컨테이너가 계속 `postgis:5432`에 연결합니다.\n- `5432` 같은 단일 정수는 동일 매핑 `\"5432:5432\"`의 축약형입니다.\n\n## 공유 서비스를 사용해야 하는 경우\n\n- 프로젝트에 로컬 데이터베이스에 연결하는 MCP 통합이 있는 경우 — 공유 서비스를 사용하면 동적 포트 검색 없이도 계속 작동할 수 있습니다. 공유 서비스를 도구가 이미 사용 중인 동일한 호스트 포트로 게시하면(예: `ports = [5432]`), 해당 도구는 변경 없이 계속 작동합니다. 다른 호스트 포트로 게시하면(예: `\"5433:5432\"`), 호스트 측 도구는 그 호스트 포트를 사용해야 하며 Coasts는 계속 컨테이너 포트를 사용합니다.\n- 자체 데이터베이스 컨테이너를 실행할 필요가 없으므로 더 가벼운 Coast 인스턴스를 원할 때.\n- Coast 인스턴스 간 데이터 격리가 필요하지 않을 때(모든 인스턴스가 동일한 데이터를 봄).\n- 호스트에서 코딩 에이전트를 실행 중이고([Filesystem](FILESYSTEM.md) 참고), 데이터베이스 상태에 [`coast exec`](EXEC_AND_DOCKER.md)를 거치지 않고 접근하게 하려는 경우. 공유 서비스를 사용하면 에이전트의 기존 데이터베이스 도구와 MCP가 변경 없이 작동합니다.\n\n격리가 필요한 경우의 대안은 [Volume Topology](VOLUMES.md) 페이지를 참고하세요.\n\n## 볼륨 식별 경고\n\nDocker 볼륨 이름은 항상 전역적으로 고유하지 않습니다. 여러 다른 프로젝트에서 `docker-compose up`을 실행하면, Coast가 공유 서비스에 연결하는 호스트 볼륨이 예상한 것과 다를 수 있습니다.\n\n공유 서비스와 함께 Coast를 시작하기 전에, 마지막으로 실행한 `docker-compose up`이 Coasts와 함께 사용하려는 프로젝트에서 실행된 것이 맞는지 확인하세요. 이렇게 하면 호스트 볼륨이 Coastfile이 기대하는 것과 일치하게 됩니다.\n\n## 문제 해결\n\n공유 서비스가 잘못된 호스트 볼륨을 가리키는 것처럼 보이는 경우:\n\n1. [Coastguard](COASTGUARD.md) UI(`coast ui`)를 엽니다.\n2. **Shared Services** 탭으로 이동합니다.\n3. 영향을 받는 서비스를 선택하고 **Remove**를 클릭합니다.\n4. **Refresh Shared Services**를 클릭하여 현재 Coastfile 구성에서 다시 생성합니다.\n\n이렇게 하면 공유 서비스 컨테이너가 제거된 후 다시 생성되며, 올바른 호스트 볼륨에 다시 연결됩니다.\n", "concepts_and_terminology/TROUBLESHOOTING.md": "# 문제 해결\n\nCoasts에서 발생하는 대부분의 문제는 오래된 상태(stale state), 고아가 된 Docker 리소스, 또는 동기화가 어긋난 데몬 때문에 생깁니다. 이 페이지는 가벼운 조치부터 핵 옵션까지의 에스컬레이션 경로를 다룹니다.\n\n## Doctor\n\n뭔가 이상하다고 느껴진다면 — 인스턴스가 실행 중으로 표시되지만 아무것도 응답하지 않거나, 포트가 막힌 것처럼 보이거나, UI가 오래된 데이터를 보여주는 경우 — `coast doctor`부터 시작하세요:\n\n```bash\ncoast doctor\n```\n\nDoctor는 상태 데이터베이스와 Docker를 스캔하여 불일치를 찾습니다: 컨테이너가 누락된 고아 인스턴스 레코드, 상태 레코드가 없는 떠다니는(dangling) 컨테이너, 그리고 실행 중으로 표시되어 있지만 실제로는 죽어 있는 공유 서비스 등이 포함됩니다. 발견한 문제는 자동으로 수정합니다.\n\n아무것도 변경하지 않고 어떤 작업을 할지 미리 확인하려면:\n\n```bash\ncoast doctor --dry-run\n```\n\n## Daemon Restart\n\n데몬 자체가 응답하지 않는 것 같거나 상태가 꼬였다고 의심된다면, 데몬을 재시작하세요:\n\n```bash\ncoast daemon restart\n```\n\n이 명령은 정상 종료 신호를 보내고 데몬이 종료될 때까지 기다린 다음, 새 프로세스를 시작합니다. 인스턴스와 상태는 유지됩니다.\n\n## Removing a Single Project\n\n문제가 하나의 프로젝트에만 국한되어 있다면, 다른 것에는 영향을 주지 않고 해당 프로젝트의 빌드 아티팩트와 연관된 Docker 리소스를 제거할 수 있습니다:\n\n```bash\ncoast rm-build my-project\n```\n\n이는 프로젝트의 아티팩트 디렉터리, Docker 이미지, 볼륨, 컨테이너를 삭제합니다. 먼저 확인을 요청합니다. 프롬프트를 건너뛰려면 `--force`를 전달하세요.\n\n## Missing Shared Service Images\n\n`coast run`이 공유 서비스를 생성하는 중 `No such image: postgres:15` 같은 오류로 실패한다면, 해당 이미지는 호스트 Docker 데몬에 없습니다.\n\n이 문제는 보통 `Coastfile`에서 Postgres나 Redis 같은 `shared_services`를 정의했지만 Docker가 아직 해당 이미지를 pull하지 않았을 때 발생합니다.\n\n누락된 이미지를 pull한 다음, 인스턴스를 다시 실행하세요:\n\n```bash\ndocker pull postgres:15\ndocker pull redis:7\ncoast run my-instance\n```\n\n어떤 이미지가 누락되었는지 확실하지 않다면, 실패한 `coast run` 출력의 Docker 오류에 이미지 이름이 포함됩니다. 프로비저닝에 실패한 뒤 Coasts는 부분적으로 생성된 인스턴스를 자동으로 정리하므로, 인스턴스가 다시 `stopped`로 돌아오는 것은 정상입니다.\n\n## Factory Reset with Nuke\n\n다른 방법이 모두 실패했거나 — 또는 완전히 깨끗한 상태로 초기화하고 싶다면 — `coast nuke`가 전체 공장 초기화를 수행합니다:\n\n```bash\ncoast nuke\n```\n\n이 작업은 다음을 수행합니다:\n\n1. `coastd` 데몬을 중지합니다.\n2. coast가 관리하는 Docker 컨테이너 **전부**를 제거합니다.\n3. coast가 관리하는 Docker 볼륨 **전부**를 제거합니다.\n4. coast가 관리하는 Docker 네트워크 **전부**를 제거합니다.\n5. coast Docker 이미지 **전부**를 제거합니다.\n6. 전체 `~/.coast/` 디렉터리(상태 데이터베이스, 빌드, 로그, 시크릿, 이미지 캐시)를 삭제합니다.\n7. `~/.coast/`를 다시 생성하고 데몬을 재시작하여 coast를 즉시 다시 사용할 수 있게 합니다.\n\n이 작업은 모든 것을 파괴하므로, 확인 프롬프트에서 `nuke`를 입력해야 합니다:\n\n```text\n$ coast nuke\nWARNING: This will permanently destroy ALL coast data:\n\n - Stop the coastd daemon\n - Remove all coast-managed Docker containers\n - Remove all coast-managed Docker volumes\n - Remove all coast-managed Docker networks\n - Remove all coast Docker images\n - Delete ~/.coast/ (state DB, builds, logs, secrets, image cache)\n\nType \"nuke\" to confirm:\n```\n\n프롬프트를 건너뛰려면 `--force`를 전달하세요(스크립트에서 유용함):\n\n```bash\ncoast nuke --force\n```\n\nnuke 이후 coast는 사용할 준비가 되어 있습니다 — 데몬이 실행 중이고 홈 디렉터리가 존재합니다. 프로젝트를 다시 `coast build`하고 `coast run`하기만 하면 됩니다.\n\n## Reporting Bugs\n\n위의 어떤 방법으로도 해결되지 않는 문제를 겪는다면, 보고 시 데몬 로그를 포함하세요:\n\n```bash\ncoast daemon logs\n```\n", "concepts_and_terminology/VOLUMES.md": "# Volume Topology\n\nCoast는 데이터 집약적 서비스(데이터베이스, 캐시 등)가 Coast 인스턴스 전반에서 데이터를 저장하고 공유하는 방식을 제어하는 세 가지 볼륨 전략을 제공합니다. 올바른 전략을 선택하는 것은 필요한 격리 수준과 감내할 수 있는 오버헤드의 정도에 달려 있습니다.\n\n## Shared Services\n\n[공유 서비스](SHARED_SERVICES.md)는 어떤 Coast 컨테이너 밖에서, 호스트 Docker 데몬에서 실행됩니다. Postgres, MongoDB, Redis 같은 서비스는 호스트 머신에 그대로 유지되고, Coast 인스턴스는 브리지 네트워크를 통해 호스트로 다시 라우팅하여 호출합니다.\n\n```text\nHost machine\n |\n +--> Postgres (host daemon, existing volume)\n +--> Redis (host daemon, existing volume)\n |\n +--> Coast: dev-1 --connects to--> host Postgres, host Redis\n +--> Coast: dev-2 --connects to--> host Postgres, host Redis\n```\n\n인스턴스 간 데이터 격리는 없습니다 — 모든 Coast가 동일한 데이터베이스에 연결합니다. 그 대신 다음을 얻을 수 있습니다:\n\n- 자체 데이터베이스 컨테이너를 실행하지 않으므로 Coast 인스턴스가 더 가벼워집니다.\n- 기존 호스트 볼륨을 직접 재사용하므로, 이미 가지고 있는 데이터가 즉시 사용 가능합니다.\n- 로컬 데이터베이스에 연결하는 MCP 통합이 별도 설정 없이 그대로 동작합니다.\n\n이는 [Coastfile](COASTFILE_TYPES.md)의 `[shared_services]` 아래에서 설정합니다.\n\n## Shared Volumes\n\n공유 볼륨은 모든 Coast 인스턴스에서 공유되는 단일 Docker 볼륨을 마운트합니다. 서비스 자체(Postgres, Redis 등)는 각 Coast 컨테이너 내부에서 실행되지만, 모두 동일한 기본 볼륨에 읽기/쓰기를 수행합니다.\n\n```text\nCoast: dev-1 --mounts--> shared volume \"my-project-postgres\"\nCoast: dev-2 --mounts--> shared volume \"my-project-postgres\"\n```\n\n이는 호스트 머신에 있는 것과 Coast 데이터를 분리해 주지만, 인스턴스들끼리는 여전히 데이터를 공유합니다. 호스트 개발 환경과의 깔끔한 분리를 원하면서도 인스턴스별 볼륨의 오버헤드는 피하고 싶을 때 유용합니다.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## Isolated Volumes\n\n격리 볼륨은 각 Coast 인스턴스에 독립적인 볼륨을 제공합니다. 인스턴스 간에도, 호스트와도 어떤 데이터도 공유되지 않습니다. 각 인스턴스는 비어 있는 상태로 시작하며(또는 스냅샷에서 시작 — 아래 참조), 독립적으로 분기됩니다.\n\n```text\nCoast: dev-1 --mounts--> volume \"dev-1-postgres\"\nCoast: dev-2 --mounts--> volume \"dev-2-postgres\"\n```\n\n이는 병렬 환경 간 진정한 볼륨 격리가 필요하고 통합 테스트 비중이 큰 프로젝트에 가장 좋은 선택입니다. 단점은 각 인스턴스가 자체 데이터 사본을 유지하므로 시작이 더 느리고 Coast 빌드가 더 커진다는 점입니다.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## Snapshotting\n\n공유 및 격리 전략은 기본적으로 빈 볼륨으로 시작합니다. 인스턴스가 기존 호스트 볼륨의 복사본으로 시작하게 하려면, `snapshot_source`를 복사할 Docker 볼륨 이름으로 설정하세요:\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n스냅샷은 [빌드 시점](BUILDS.md)에 생성됩니다. 생성 이후에는 각 인스턴스의 볼륨이 독립적으로 분기되며 — 변경 사항은 소스나 다른 인스턴스로 전파되지 않습니다.\n\nCoast는 아직 런타임 스냅샷(예: 실행 중인 인스턴스의 볼륨을 스냅샷으로 생성)을 지원하지 않습니다. 이는 향후 릴리스에서 제공될 예정입니다.\n", - "harnesses/README.md": "# 하니스\n\n각 하니스는 서로 다른 위치에 git 워크트리를 생성합니다. Coasts에서는\n[`worktree_dir`](../coastfiles/WORKTREE_DIR.md) 배열이 어디를 찾아야 하는지 알려주며 --\n추가 bind mount가 필요한 `~/.codex/worktrees` 같은 외부 경로도 포함됩니다.\n\n각 하니스는 프로젝트 수준 지침, 스킬, 명령에 대해서도 자체적인 규칙을 가집니다. 아래 매트릭스는 각 하니스가 무엇을 지원하는지 보여주므로 Coasts에 대한 안내를 어디에 둘지 알 수 있습니다. 각 페이지는 Coastfile 구성, 권장 파일 레이아웃, 그리고 해당 하니스에 특화된 주의사항을 다룹니다.\n\n하나의 저장소를 여러 하니스에서 사용하는 경우 [Multiple Harnesses](MULTIPLE_HARNESSES.md)를 참고하세요.\n\n| Harness | Worktree location | Project instructions | Skills | Commands | Page |\n|---------|-------------------|----------------------|--------|----------|------|\n| OpenAI Codex | `~/.codex/worktrees` | `AGENTS.md` | `.agents/skills/` | Skills surface as `/` commands | [Codex](CODEX.md) |\n| Claude Code | `.claude/worktrees` | `CLAUDE.md` | `.claude/skills/` | `.claude/commands/` | [Claude Code](CLAUDE_CODE.md) |\n| Cursor | `~/.cursor/worktrees/` | `AGENTS.md` or `.cursor/rules/` | `.cursor/skills/` or `.agents/skills/` | `.cursor/commands/` | [Cursor](CURSOR.md) |\n| Conductor | `~/conductor/workspaces/` | `CLAUDE.md` | -- | -- | [Conductor](CONDUCTOR.md) |\n| T3 Code | `~/.t3/worktrees/` | `AGENTS.md` | `.agents/skills/` | -- | [T3 Code](T3_CODE.md) |\n\n## Skills vs Commands\n\n스킬과 명령은 둘 다 재사용 가능한 `/coasts` 워크플로를 정의할 수 있게 해줍니다. 하니스가 무엇을 지원하는지에 따라 둘 중 하나만 쓰거나 둘 다 쓸 수 있습니다.\n\n하니스가 명령을 지원하고 명시적인 `/coasts`\n진입점을 원한다면, 간단한 방법 하나는 스킬을 재사용하는 명령을 추가하는 것입니다.\n명령은 이름으로 명시적으로 호출되므로,\n`/coasts` 워크플로가 언제 실행되는지 정확히 알 수 있습니다. 스킬도 에이전트가\n문맥에 따라 자동으로 로드할 수 있는데, 이는 유용하지만 지침이\n언제 불러와지는지에 대해서는 제어가 더 적다는 뜻이기도 합니다.\n\n둘 다 사용할 수 있습니다. 그렇게 한다면,\n워크플로의 별도 복사본을 유지하지 말고 명령이 스킬을 재사용하게 하세요.\n\n하니스가 스킬만 지원한다면(T3 Code) 스킬을 사용하세요. 둘 다\n지원하지 않는다면(Conductor) `/coasts` 워크플로를 프로젝트\n지침 파일에 직접 넣으세요.\n", - "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview)는\n프로젝트 내부의 `.claude/worktrees/`에 worktree를 생성합니다. 그 디렉터리는\n리포지토리 내부에 있으므로, Coasts는 외부 bind mount 없이도 Claude Code worktree를\n발견하고 할당할 수 있습니다.\n\n여기서 Claude Code는 Coasts를 위한 세 가지 계층이 가장 명확하게 분리된\n하네스이기도 합니다:\n\n- Coasts와 함께 작업할 때의 짧고 항상 적용되는 규칙을 위한 `CLAUDE.md`\n- 재사용 가능한 `/coasts` 워크플로를 위한 `.claude/skills/coasts/SKILL.md`\n- 추가 진입점으로 명령 파일이 필요할 때만 사용하는 `.claude/commands/coasts.md`\n\n## Setup\n\n`.claude/worktrees`를 `worktree_dir`에 추가하세요:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n`.claude/worktrees`는 프로젝트 기준 상대 경로이므로, 외부 bind mount는\n필요하지 않습니다.\n\n## Where Coasts guidance goes\n\n### `CLAUDE.md`\n\n모든 작업에 적용되어야 하는 Coasts 규칙은 여기에 두세요. 짧고 실행 중심으로\n유지하세요:\n\n- 세션에서 첫 번째 런타임 명령 전에 `coast lookup` 실행\n- 테스트, 빌드, 서비스 명령에는 `coast exec` 사용\n- 런타임 피드백에는 `coast ps` 및 `coast logs` 사용\n- 일치하는 Coast가 없을 때 Coast를 생성하거나 재할당하기 전에 질문\n\n### `.claude/skills/coasts/SKILL.md`\n\n재사용 가능한 `/coasts` 워크플로는 여기에 두세요. 다음과 같은 흐름에 적합한\n위치입니다:\n\n1. `coast lookup`을 실행하고 일치하는 Coast를 재사용\n2. 일치하는 항목이 없으면 `coast ls`로 대체\n3. `coast run`, `coast assign`, `coast unassign`, `coast checkout`, `coast ui`를 제안\n4. 래핑하지 않고 Coast CLI 자체를 계약으로 사용\n\n이 리포지토리에서 Codex, T3 Code 또는 Cursor도 사용한다면,\n[Multiple Harnesses](MULTIPLE_HARNESSES.md)를 참고하고 정식 skill은\n`.agents/skills/coasts/`에 유지한 다음 Claude Code에 노출하세요.\n\n### `.claude/commands/coasts.md`\n\nClaude Code는 프로젝트 명령 파일도 지원합니다. Coasts에 대한 문서에서는\n이를 선택 사항으로 취급하세요:\n\n- 명령 파일이 특별히 필요할 때만 사용\n- 한 가지 단순한 옵션은 명령이 같은 skill을 재사용하게 하는 것\n- 명령에 별도의 자체 지침을 부여하면, 유지해야 할 워크플로의 두 번째 복사본을\n 떠안게 됩니다\n\n## Example layout\n\n### Claude Code only\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\n이 리포지토리에서 Codex, T3 Code 또는 Cursor도 사용한다면, 여기서 이를\n중복하지 말고 [Multiple Harnesses](MULTIPLE_HARNESSES.md)의 공유 패턴을\n사용하세요. 제공자별 지침이 중복되면 새 하네스를 추가할 때마다 동기화 상태를\n유지하기가 더 어려워지기 때문입니다.\n\n## What Coasts does\n\n- **실행** — `coast run `은 최신 빌드에서 새로운 Coast 인스턴스를 생성합니다. `coast run -w `를 사용하면 Claude Code worktree를 생성하고 한 번에 할당할 수 있습니다. [Run](../concepts_and_terminology/RUN.md)을 참고하세요.\n- **검색** — Coasts는 다른 로컬 worktree 디렉터리와 마찬가지로 `.claude/worktrees`를 읽습니다.\n- **이름 지정** — Claude Code worktree는 Coasts UI와 CLI에서 다른 리포지토리 내부 worktree와 동일한 로컬 worktree 이름 지정 동작을 따릅니다.\n- **할당** — `coast assign`은 외부 bind-mount 우회 없이 `/workspace`를 Claude Code worktree로 전환할 수 있습니다.\n- **Gitignored 동기화** — worktree가 리포지토리 트리 내부에 있으므로 정상적으로 작동합니다.\n- **고아 감지** — Claude Code가 worktree를 제거하면, Coasts는 누락된 gitdir를 감지하고 필요할 때 할당을 해제할 수 있습니다.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code worktree\n- `~/.codex/worktrees/` — 이 리포지토리에서 Codex도 사용하는 경우의 Codex worktree\n\n## Limitations\n\n- `CLAUDE.md`, `.claude/skills`, `.claude/commands` 전반에 동일한 `/coasts`\n 워크플로를 중복하면, 그 복사본들은 서로 어긋나게 됩니다. `CLAUDE.md`는 짧게\n 유지하고 재사용 가능한 워크플로는 하나의 skill에만 두세요.\n- 하나의 리포지토리가 여러 하네스에서 깔끔하게 작동하길 원한다면,\n [Multiple Harnesses](MULTIPLE_HARNESSES.md)의 공유 패턴을 우선하세요.\n", - "harnesses/CODEX.md": "# Codex\n\n[Codex](https://developers.openai.com/codex/app/worktrees/)는 `$CODEX_HOME/worktrees`(일반적으로 `~/.codex/worktrees`)에 worktree를 생성합니다. 각 worktree는 `~/.codex/worktrees/a0db/project-name`처럼 불투명한 해시 디렉터리 아래에 존재하고, 분리된 HEAD에서 시작하며, Codex의 보존 정책에 따라 자동으로 정리됩니다.\n\n[Codex docs](https://developers.openai.com/codex/app/worktrees/)에서 발췌:\n\n> worktree가 생성되는 위치를 제가 제어할 수 있나요?\n> 현재는 불가능합니다. Codex는 일관되게 관리할 수 있도록 `$CODEX_HOME/worktrees` 아래에 worktree를 생성합니다.\n\n이러한 worktree는 프로젝트 루트 밖에 존재하므로, Coasts가 이를 발견하고 마운트하려면 명시적인\n구성이 필요합니다.\n\n## Setup\n\n`worktree_dir`에 `~/.codex/worktrees`를 추가하세요:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nCoasts는 런타임에 `~`를 확장하며, `~/` 또는 `/`로 시작하는 모든 경로를\n외부 경로로 취급합니다. 자세한 내용은\n[Worktree Directories](../coastfiles/WORKTREE_DIR.md)를 참고하세요.\n\n`worktree_dir`를 변경한 후에는 bind mount가 적용되도록 기존 인스턴스를 **다시 생성**해야 합니다:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree 목록은 즉시 업데이트됩니다(Coasts가 새 Coastfile을 읽기 때문). 하지만\nCodex worktree에 할당하려면 컨테이너 내부의 bind mount가 필요합니다.\n\n## Where Coasts guidance goes\n\nCoasts 작업에는 Codex의 프로젝트 지침 파일과 공유 skill 레이아웃을\n사용하세요:\n\n- 짧은 Coast Runtime 규칙은 `AGENTS.md`에 둡니다\n- 재사용 가능한 `/coasts` 워크플로는 `.agents/skills/coasts/SKILL.md`에 둡니다\n- Codex는 해당 skill을 `/coasts` 명령으로 노출합니다\n- Codex 전용 메타데이터를 사용하는 경우, 이를 skill 옆의\n `.agents/skills/coasts/agents/openai.yaml`에 둡니다\n- Coasts 관련 문서만을 위한 별도의 프로젝트 명령 파일을 만들지 마세요. skill이\n 재사용 가능한 표면입니다\n- 이 저장소가 Cursor나 Claude Code도 함께 사용하는 경우, 정본 skill은\n `.agents/skills/`에 두고 그곳에서 노출하세요. 자세한 내용은\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) 및\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)를 참고하세요.\n\n예를 들어, 최소한의 `.agents/skills/coasts/agents/openai.yaml`은 다음과\n같을 수 있습니다:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\n이렇게 하면 Codex에서 더 보기 좋은 라벨로 skill이 표시되고 `/coasts`가\n명시적 명령이 됩니다. skill에 MCP 서버나 기타 OpenAI 관리 도구 연결도\n필요한 경우에만 `dependencies.tools`를 추가하세요.\n\n## What Coasts does\n\n- **Run** -- `coast run `은 최신 빌드로부터 새 Coast 인스턴스를 생성합니다. `coast run -w `를 사용하면 Codex worktree를 한 단계에서 생성하고 할당할 수 있습니다. 자세한 내용은 [Run](../concepts_and_terminology/RUN.md)을 참고하세요.\n- **Bind mount** -- 컨테이너 생성 시, Coasts는\n `~/.codex/worktrees`를 컨테이너 내부의 `/host-external-wt/{index}`에 마운트합니다.\n- **Discovery** -- `git worktree list --porcelain`는 리포지토리 범위로 동작하므로, 디렉터리에 많은 프로젝트의 worktree가 들어 있더라도 현재 프로젝트에 속한 Codex worktree만 표시됩니다.\n- **Naming** -- 분리된 HEAD worktree는 외부 디렉터리 내 상대 경로(`a0db/my-app`, `eca7/my-app`)로 표시됩니다. 브랜치 기반 worktree는 브랜치 이름으로 표시됩니다.\n- **Assign** -- `coast assign`은 외부 bind mount 경로에서 `/workspace`를 다시 마운트합니다.\n- **Gitignored sync** -- 절대 경로를 사용해 호스트 파일시스템에서 실행되므로, bind mount 없이도 동작합니다.\n- **Orphan detection** -- git watcher는 외부 디렉터리를\n 재귀적으로 스캔하면서 `.git` gitdir 포인터로 필터링합니다. Codex가\n worktree를 삭제하면 Coasts는 인스턴스 할당을 자동으로 해제합니다.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code(로컬, 특별한 처리 없음)\n- `~/.codex/worktrees/` -- Codex(외부, bind mount됨)\n\n## Limitations\n\n- Codex는 언제든지 worktree를 정리할 수 있습니다. Coasts의 orphan detection은\n 이를 문제없이 처리합니다.\n", - "harnesses/CONDUCTOR.md": "# Conductor\n\n[Conductor](https://conductor.build/)는 병렬 Claude Code 에이전트를 실행하며, 각 에이전트는 자체적으로 격리된 워크스페이스를 가집니다. 워크스페이스는 `~/conductor/workspaces//`에 저장된 git worktree입니다. 각 워크스페이스는 이름이 지정된 브랜치로 체크아웃됩니다.\n\n이러한 worktree는 프로젝트 루트 외부에 존재하므로, Coasts가 이를 발견하고 마운트하려면 명시적인 구성이 필요합니다.\n\n## 설정\n\n`~/conductor/workspaces/`를 `worktree_dir`에 추가하세요. Codex와 달리(모든 프로젝트를 하나의 평면 디렉터리 아래에 저장함), Conductor는 프로젝트별 하위 디렉터리 아래에 worktree를 중첩하므로 경로에 프로젝트 이름이 포함되어야 합니다. 아래 예시에서 `my-app`은 해당 저장소에 대해 `~/conductor/workspaces/` 아래의 실제 폴더 이름과 일치해야 합니다.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nConductor는 저장소별로 워크스페이스 경로를 구성할 수 있으므로, 기본값인 `~/conductor/workspaces`가 현재 설정과 일치하지 않을 수 있습니다. 실제 경로를 확인하려면 Conductor 저장소 설정을 확인하고 그에 맞게 조정하세요 — 디렉터리가 어디에 있든 원리는 동일합니다.\n\nCoasts는 런타임에 `~`를 확장하며, `~/` 또는 `/`로 시작하는 모든 경로를 외부 경로로 취급합니다. 자세한 내용은 [Worktree Directories](../coastfiles/WORKTREE_DIR.md)를 참조하세요.\n\n`worktree_dir`를 변경한 후에는 bind mount가 적용되도록 기존 인스턴스를 **다시 생성**해야 합니다:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree 목록은 즉시 업데이트됩니다(Coasts가 새 Coastfile을 읽기 때문입니다). 그러나 Conductor worktree에 할당하려면 컨테이너 내부의 bind mount가 필요합니다.\n\n## Coasts 지침은 어디에 두어야 하나요\n\nConductor를 Coasts와 함께 작업하기 위한 독립적인 harness로 취급하세요:\n\n- 짧은 Coast Runtime 규칙은 `CLAUDE.md`에 두세요\n- 설정이나 실행 동작 중 실제로 Conductor 전용인 것은 Conductor Repository Settings 스크립트를 사용하세요\n- 여기서는 전체 Claude Code 프로젝트 명령 또는 프로젝트 스킬 동작을 가정하지 마세요\n- 명령을 추가했는데 나타나지 않으면 다시 테스트하기 전에 Conductor를 완전히 종료했다가 다시 여세요\n- 이 저장소가 다른 harness도 함께 사용한다면, 공유 `/coasts` 워크플로를 한 곳에 유지하는 방법은 [Multiple Harnesses](MULTIPLE_HARNESSES.md) 및 [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)를 참조하세요\n\n## Coasts가 수행하는 작업\n\n- **Run** — `coast run `은 최신 빌드에서 새 Coast 인스턴스를 생성합니다. `coast run -w `를 사용하면 Conductor worktree를 생성하고 할당하는 작업을 한 번에 수행할 수 있습니다. [Run](../concepts_and_terminology/RUN.md)을 참조하세요.\n- **Bind mount** — 컨테이너 생성 시 Coasts는 `~/conductor/workspaces/`를 컨테이너의 `/host-external-wt/{index}`에 마운트합니다.\n- **Discovery** — `git worktree list --porcelain`는 저장소 범위로 동작하므로 현재 프로젝트에 속한 worktree만 표시됩니다.\n- **Naming** — Conductor worktree는 이름이 지정된 브랜치를 사용하므로 Coasts UI와 CLI에 브랜치 이름으로 표시됩니다(예: `scroll-to-bottom-btn`). 하나의 브랜치는 한 번에 하나의 Conductor 워크스페이스에서만 체크아웃할 수 있습니다.\n- **Assign** — `coast assign`은 외부 bind mount 경로에서 `/workspace`를 다시 마운트합니다.\n- **Gitignored sync** — 호스트 파일시스템에서 절대 경로로 실행되며, bind mount 없이도 동작합니다.\n- **Orphan detection** — git watcher는 외부 디렉터리를 재귀적으로 스캔하고 `.git` gitdir 포인터를 기준으로 필터링합니다. Conductor가 워크스페이스를 보관 처리하거나 삭제하면 Coasts는 인스턴스 할당을 자동으로 해제합니다.\n\n## 예시\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor(외부, bind-mounted; `my-app`은 저장소 폴더 이름으로 바꾸세요)\n\n## Conductor 환경 변수\n\n- Coasts 내부 런타임 구성에 Conductor 전용 환경 변수(예: `CONDUCTOR_PORT`, `CONDUCTOR_WORKSPACE_PATH`)에 의존하지 마세요. Coasts는 포트, 워크스페이스 경로, 서비스 검색을 독립적으로 관리합니다 — 대신 Coastfile의 `[ports]`와 `coast exec`를 사용하세요.\n", - "harnesses/CURSOR.md": "# Cursor\n\n[Cursor](https://cursor.com/docs/agent/overview)는 현재 체크아웃에서 직접 작업할 수 있으며,\nParallel Agents 기능은 `~/.cursor/worktrees//` 아래에 git\nworktree를 생성할 수도 있습니다.\n\nCoasts 문서 기준으로는, 이는 두 가지 설정 경우를 의미합니다:\n\n- 현재 체크아웃에서만 Cursor를 사용 중이라면, Cursor 전용\n `worktree_dir` 항목은 필요하지 않습니다\n- Cursor Parallel Agents를 사용한다면, Coasts가 해당 worktree를\n 발견하고 할당할 수 있도록 Cursor worktree 디렉터리를 `worktree_dir`에 추가하세요\n\n## 설정\n\n### 현재 체크아웃만 사용\n\nCursor가 이미 열어 둔 체크아웃만 편집하는 경우, Coasts에는 특별한\nCursor 전용 worktree 경로가 필요하지 않습니다. Coasts는 해당 체크아웃을\n다른 로컬 저장소 루트와 동일하게 처리합니다.\n\n### Cursor Parallel Agents\n\nParallel Agents를 사용한다면, `~/.cursor/worktrees/`를\n`worktree_dir`에 추가하세요:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nCursor는 각 에이전트 worktree를 이 프로젝트별 디렉터리 아래에 저장합니다. Coasts는\n런타임에 `~`를 확장하고 이 경로를 외부 경로로 처리하므로, 바인드 마운트가 적용되려면\n기존 인스턴스를 다시 생성해야 합니다:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nCoastfile 변경 후 worktree 목록은 즉시 업데이트되지만,\nCursor Parallel Agent worktree에 할당하려면 컨테이너 내부의 외부 바인드 마운트가 필요합니다.\n\n## Coasts 가이드 배치 위치\n\n### `AGENTS.md` 또는 `.cursor/rules/coast.md`\n\n짧고 항상 활성화되는 Coast Runtime 규칙은 여기에 두세요:\n\n- 가장 이식성 높은 프로젝트 지침을 원한다면 `AGENTS.md`를 사용하세요\n- Cursor 네이티브 프로젝트 규칙과 설정 UI 지원을 원한다면 `.cursor/rules/coast.md`를 사용하세요\n- 명확한 이유가 없다면 동일한 Coast Runtime 블록을 두 곳 모두에 중복하지 마세요\n\n### `.cursor/skills/coasts/SKILL.md` 또는 공유 `.agents/skills/coasts/SKILL.md`\n\n재사용 가능한 `/coasts` 워크플로는 여기에 두세요:\n\n- Cursor 전용 저장소라면 `.cursor/skills/coasts/SKILL.md`가 자연스러운 위치입니다\n- 여러 하네스를 사용하는 저장소라면, 정본 skill을\n `.agents/skills/coasts/SKILL.md`에 두세요; Cursor는 이를 직접 로드할 수 있습니다\n- skill은 실제 `/coasts` 워크플로를 담당해야 합니다: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout`, 그리고 `coast ui`\n\n### `.cursor/commands/coasts.md`\n\nCursor는 프로젝트 명령도 지원합니다. Coasts 문서 기준으로는, 명령은\n선택 사항으로 취급하세요:\n\n- 명시적인 `/coasts` 진입점을 원할 때만 명령을 추가하세요\n- 한 가지 단순한 방법은 해당 명령이 같은 skill을 재사용하도록 하는 것입니다\n- 명령에 별도의 자체 지침을 부여하면, 유지해야 할 워크플로 사본이\n 두 개가 됩니다\n\n### `.cursor/worktrees.json`\n\n`.cursor/worktrees.json`은 Coasts 정책이 아니라 Cursor 자체의\nworktree 부트스트랩에 사용하세요:\n\n- 의존성 설치\n- `.env` 파일 복사 또는 심볼릭 링크 생성\n- 데이터베이스 마이그레이션 또는 기타 일회성 부트스트랩 단계 실행\n\nCoast Runtime 규칙이나 Coast CLI 워크플로를\n`.cursor/worktrees.json`으로 옮기지 마세요.\n\n## 예시 레이아웃\n\n### Cursor만 사용\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # optional\n.cursor/rules/coast.md # optional alternative to AGENTS.md\n.cursor/worktrees.json # optional, for Parallel Agents bootstrap\n```\n\n### Cursor와 다른 하네스를 함께 사용\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional\n```\n\n## Coasts의 동작\n\n- **실행** — `coast run `은 최신 빌드에서 새 Coast 인스턴스를 생성합니다. `coast run -w `를 사용하면 Cursor worktree를 한 단계에서 생성하고 할당할 수 있습니다. [Run](../concepts_and_terminology/RUN.md)을 참조하세요.\n- **현재 체크아웃** — Cursor가 사용자가 연 저장소에서 직접 작업 중인 경우,\n 특별한 Cursor 처리가 필요하지 않습니다.\n- **바인드 마운트** — Parallel Agents의 경우, Coasts는\n `~/.cursor/worktrees/`를 컨테이너 내부의\n `/host-external-wt/{index}`에 마운트합니다.\n- **탐색** — `git worktree list --porcelain`는 여전히 저장소 범위로 동작하므로, Coasts는\n 현재 프로젝트에 속한 Cursor worktree만 표시합니다.\n- **이름 지정** — Cursor Parallel Agent worktree는 Coasts의 CLI와 UI에서\n 브랜치 이름으로 표시됩니다.\n- **할당** — `coast assign`은 Cursor worktree가 선택되면 외부 바인드\n 마운트 경로에서 `/workspace`를 다시 마운트합니다.\n- **Gitignored 동기화** — 절대 경로를 사용해 호스트 파일시스템에서 계속 동작합니다.\n- **고아 감지** — Cursor가 오래된 worktree를 정리하면, Coasts는 누락된 gitdir를 감지하고 필요 시 할당 해제를 할 수 있습니다.\n\n## 예시\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code worktree\n- `~/.codex/worktrees/` — Codex worktree\n- `~/.cursor/worktrees/my-app/` — Cursor Parallel Agent worktree\n\n## 제한 사항\n\n- Cursor Parallel Agents를 사용하지 않는다면, 단지 Cursor에서 편집 중이라는 이유만으로\n `~/.cursor/worktrees/`를 추가하지 마세요.\n- Coast Runtime 규칙은 항상 활성화되는 한 곳에만 두세요: `AGENTS.md` 또는\n `.cursor/rules/coast.md`. 둘 다 중복하면 내용이 어긋나기 쉽습니다.\n- 재사용 가능한 `/coasts` 워크플로는 skill에 두세요. `.cursor/worktrees.json`은\n Cursor 부트스트랩용이지 Coasts 정책용이 아닙니다.\n- 하나의 저장소를 Cursor, Codex, Claude Code, 또는 T3 Code에서 함께 사용한다면,\n [Multiple Harnesses](MULTIPLE_HARNESSES.md)의 공유 레이아웃을 우선하세요.\n", + "harnesses/README.md": "# 하니스\n\n각 하니스는 서로 다른 위치에 git 워크트리를 생성합니다. Coasts에서는\n[`worktree_dir`](../coastfiles/WORKTREE_DIR.md) 배열이 어디를 찾아야 하는지 알려주며 --\n추가 bind mount가 필요한 `~/.codex/worktrees` 같은 외부 경로도 포함됩니다.\n\n각 하니스는 프로젝트 수준 지침, 스킬, 명령에 대해서도 자체적인 규칙을 가집니다. 아래 매트릭스는 각 하니스가 무엇을 지원하는지 보여주므로 Coasts에 대한 안내를 어디에 둘지 알 수 있습니다. 각 페이지는 Coastfile 구성, 권장 파일 레이아웃, 그리고 해당 하니스에 특화된 주의사항을 다룹니다.\n\n하나의 저장소를 여러 하니스에서 사용하는 경우 [Multiple Harnesses](MULTIPLE_HARNESSES.md)를 참고하세요.\n\n| Harness | Worktree location | Project instructions | Skills | Commands | Page |\n|---------|-------------------|----------------------|--------|----------|------|\n| OpenAI Codex | `~/.codex/worktrees` | `AGENTS.md` | `.agents/skills/` | Skills surface as `/` commands | [Codex](CODEX.md) |\n| Claude Code | `.claude/worktrees` | `CLAUDE.md` | `.claude/skills/` | `.claude/commands/` | [Claude Code](CLAUDE_CODE.md) |\n| Cursor | `~/.cursor/worktrees/` | `AGENTS.md` or `.cursor/rules/` | `.cursor/skills/` or `.agents/skills/` | `.cursor/commands/` | [Cursor](CURSOR.md) |\n| Conductor | `~/conductor/workspaces/` | `CLAUDE.md` | -- | -- | [Conductor](CONDUCTOR.md) |\n| T3 Code | `~/.t3/worktrees/` | `AGENTS.md` | `.agents/skills/` | -- | [T3 Code](T3_CODE.md) |\n| Shep | `~/.shep/repos/*/wt` | `CLAUDE.md` | `.agents/skills/` or `.claude/skills/` | -- | [Shep](SHEP.md) |\n\n## Skills vs Commands\n\n스킬과 명령은 둘 다 재사용 가능한 `/coasts` 워크플로를 정의할 수 있게 해줍니다. 하니스가 무엇을 지원하는지에 따라 둘 중 하나만 쓰거나 둘 다 쓸 수 있습니다.\n\n하니스가 명령을 지원하고 명시적인 `/coasts`\n진입점을 원한다면, 간단한 방법 하나는 스킬을 재사용하는 명령을 추가하는 것입니다.\n명령은 이름으로 명시적으로 호출되므로,\n`/coasts` 워크플로가 언제 실행되는지 정확히 알 수 있습니다. 스킬도 에이전트가\n문맥에 따라 자동으로 로드할 수 있는데, 이는 유용하지만 지침이\n언제 불러와지는지에 대해서는 제어가 더 적다는 뜻이기도 합니다.\n\n둘 다 사용할 수 있습니다. 그렇게 한다면,\n워크플로의 별도 복사본을 유지하지 말고 명령이 스킬을 재사용하게 하세요.\n\n하니스가 스킬만 지원한다면(T3 Code) 스킬을 사용하세요. 둘 다\n지원하지 않는다면(Conductor) `/coasts` 워크플로를 프로젝트\n지침 파일에 직접 넣으세요.\n", + "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n## Quick setup\n\n[Coast CLI](../GETTING_STARTED.md)가 필요합니다. Coasts를 자동으로 설정하려면\n이 프롬프트를 에이전트의 채팅에 복사하세요:\n\n```prompt-copy\nclaude_code_setup_prompt.txt\n```\n\nCLI에서도 skill 내용을 가져올 수 있습니다: `coast skills-prompt`.\n\n설정 후에는 **새 Claude Code 세션을 시작하세요** — skill과 `CLAUDE.md`\n변경 사항은 세션 시작 시 로드됩니다.\n\n---\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview)는\n프로젝트 내부의 `.claude/worktrees/`에 worktree를 생성합니다. 그 디렉터리는\n리포지토리 내부에 있으므로, Coasts는 외부 bind mount 없이도 Claude Code worktree를\n발견하고 할당할 수 있습니다.\n\n여기서 Claude Code는 Coasts를 위한 세 가지 계층이 가장 명확하게 분리된\n하네스이기도 합니다:\n\n- Coasts와 함께 작업할 때의 짧고 항상 적용되는 규칙을 위한 `CLAUDE.md`\n- 재사용 가능한 `/coasts` 워크플로를 위한 `.claude/skills/coasts/SKILL.md`\n- 추가 진입점으로 명령 파일이 필요할 때만 사용하는 `.claude/commands/coasts.md`\n\n## Setup\n\n`.claude/worktrees`를 `worktree_dir`에 추가하세요:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n`.claude/worktrees`는 프로젝트 기준 상대 경로이므로, 외부 bind mount는\n필요하지 않습니다.\n\n## Where Coasts guidance goes\n\n### `CLAUDE.md`\n\n모든 작업에 적용되어야 하는 Coasts 규칙은 여기에 두세요. 짧고 실행 중심으로\n유지하세요:\n\n- 세션에서 첫 번째 런타임 명령 전에 `coast lookup` 실행\n- 테스트, 빌드, 서비스 명령에는 `coast exec` 사용\n- 런타임 피드백에는 `coast ps` 및 `coast logs` 사용\n- 일치하는 Coast가 없을 때 Coast를 생성하거나 재할당하기 전에 질문\n\n### `.claude/skills/coasts/SKILL.md`\n\n재사용 가능한 `/coasts` 워크플로는 여기에 두세요. 다음과 같은 흐름에 적합한\n위치입니다:\n\n1. `coast lookup`을 실행하고 일치하는 Coast를 재사용\n2. 일치하는 항목이 없으면 `coast ls`로 대체\n3. `coast run`, `coast assign`, `coast unassign`, `coast checkout`, `coast ui`를 제안\n4. 래핑하지 않고 Coast CLI 자체를 계약으로 사용\n\n이 리포지토리에서 Codex, T3 Code 또는 Cursor도 사용한다면,\n[Multiple Harnesses](MULTIPLE_HARNESSES.md)를 참고하고 정식 skill은\n`.agents/skills/coasts/`에 유지한 다음 Claude Code에 노출하세요.\n\n### `.claude/commands/coasts.md`\n\nClaude Code는 프로젝트 명령 파일도 지원합니다. Coasts에 대한 문서에서는\n이를 선택 사항으로 취급하세요:\n\n- 명령 파일이 특별히 필요할 때만 사용\n- 한 가지 단순한 옵션은 명령이 같은 skill을 재사용하게 하는 것\n- 명령에 별도의 자체 지침을 부여하면, 유지해야 할 워크플로의 두 번째 복사본을\n 떠안게 됩니다\n\n## Example layout\n\n### Claude Code only\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\n이 리포지토리에서 Codex, T3 Code 또는 Cursor도 사용한다면, 여기서 이를\n중복하지 말고 [Multiple Harnesses](MULTIPLE_HARNESSES.md)의 공유 패턴을\n사용하세요. 제공자별 지침이 중복되면 새 하네스를 추가할 때마다 동기화 상태를\n유지하기가 더 어려워지기 때문입니다.\n\n## What Coasts does\n\n- **실행** — `coast run `은 최신 빌드에서 새로운 Coast 인스턴스를 생성합니다. `coast run -w `를 사용하면 Claude Code worktree를 생성하고 한 번에 할당할 수 있습니다. [Run](../concepts_and_terminology/RUN.md)을 참고하세요.\n- **검색** — Coasts는 다른 로컬 worktree 디렉터리와 마찬가지로 `.claude/worktrees`를 읽습니다.\n- **이름 지정** — Claude Code worktree는 Coasts UI와 CLI에서 다른 리포지토리 내부 worktree와 동일한 로컬 worktree 이름 지정 동작을 따릅니다.\n- **할당** — `coast assign`은 외부 bind-mount 우회 없이 `/workspace`를 Claude Code worktree로 전환할 수 있습니다.\n- **Gitignored 동기화** — worktree가 리포지토리 트리 내부에 있으므로 정상적으로 작동합니다.\n- **고아 감지** — Claude Code가 worktree를 제거하면, Coasts는 누락된 gitdir를 감지하고 필요할 때 할당을 해제할 수 있습니다.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code worktree\n- `~/.codex/worktrees/` — 이 리포지토리에서 Codex도 사용하는 경우의 Codex worktree\n\n## Limitations\n\n- `CLAUDE.md`, `.claude/skills`, `.claude/commands` 전반에 동일한 `/coasts`\n 워크플로를 중복하면, 그 복사본들은 서로 어긋나게 됩니다. `CLAUDE.md`는 짧게\n 유지하고 재사용 가능한 워크플로는 하나의 skill에만 두세요.\n- 하나의 리포지토리가 여러 하네스에서 깔끔하게 작동하길 원한다면,\n [Multiple Harnesses](MULTIPLE_HARNESSES.md)의 공유 패턴을 우선하세요.\n", + "harnesses/CODEX.md": "# Codex\n\n## Quick setup\n\n[Coast CLI](../GETTING_STARTED.md)가 필요합니다. Coasts를 자동으로 설정하려면 이 프롬프트를\n에이전트의 채팅에 복사하세요:\n\n```prompt-copy\ncodex_setup_prompt.txt\n```\n\nCLI에서도 skill 내용을 가져올 수 있습니다: `coast skills-prompt`.\n\n설정 후에는 새 skill과 `AGENTS.md`가 적용되도록 **Codex를 종료했다가 다시 여세요**.\n\n---\n\n[Codex](https://developers.openai.com/codex/app/worktrees/)는 `$CODEX_HOME/worktrees`(일반적으로 `~/.codex/worktrees`)에 worktree를 생성합니다. 각 worktree는 `~/.codex/worktrees/a0db/project-name`처럼 불투명한 해시 디렉터리 아래에 존재하고, 분리된 HEAD에서 시작하며, Codex의 보존 정책에 따라 자동으로 정리됩니다.\n\n[Codex docs](https://developers.openai.com/codex/app/worktrees/)에서 발췌:\n\n> worktree가 생성되는 위치를 제가 제어할 수 있나요?\n> 현재는 불가능합니다. Codex는 일관되게 관리할 수 있도록 `$CODEX_HOME/worktrees` 아래에 worktree를 생성합니다.\n\n이러한 worktree는 프로젝트 루트 밖에 존재하므로, Coasts가 이를 발견하고 마운트하려면 명시적인\n구성이 필요합니다.\n\n## Setup\n\n`worktree_dir`에 `~/.codex/worktrees`를 추가하세요:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nCoasts는 런타임에 `~`를 확장하며, `~/` 또는 `/`로 시작하는 모든 경로를\n외부 경로로 취급합니다. 자세한 내용은\n[Worktree Directories](../coastfiles/WORKTREE_DIR.md)를 참고하세요.\n\n`worktree_dir`를 변경한 후에는 bind mount가 적용되도록 기존 인스턴스를 **다시 생성**해야 합니다:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree 목록은 즉시 업데이트됩니다(Coasts가 새 Coastfile을 읽기 때문). 하지만\nCodex worktree에 할당하려면 컨테이너 내부의 bind mount가 필요합니다.\n\n## Where Coasts guidance goes\n\nCoasts 작업에는 Codex의 프로젝트 지침 파일과 공유 skill 레이아웃을\n사용하세요:\n\n- 짧은 Coast Runtime 규칙은 `AGENTS.md`에 둡니다\n- 재사용 가능한 `/coasts` 워크플로는 `.agents/skills/coasts/SKILL.md`에 둡니다\n- Codex는 해당 skill을 `/coasts` 명령으로 노출합니다\n- Codex 전용 메타데이터를 사용하는 경우, 이를 skill 옆의\n `.agents/skills/coasts/agents/openai.yaml`에 둡니다\n- Coasts 관련 문서만을 위한 별도의 프로젝트 명령 파일을 만들지 마세요. skill이\n 재사용 가능한 표면입니다\n- 이 저장소가 Cursor나 Claude Code도 함께 사용하는 경우, 정본 skill은\n `.agents/skills/`에 두고 그곳에서 노출하세요. 자세한 내용은\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) 및\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)를 참고하세요.\n\n예를 들어, 최소한의 `.agents/skills/coasts/agents/openai.yaml`은 다음과\n같을 수 있습니다:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\n이렇게 하면 Codex에서 더 보기 좋은 라벨로 skill이 표시되고 `/coasts`가\n명시적 명령이 됩니다. skill에 MCP 서버나 기타 OpenAI 관리 도구 연결도\n필요한 경우에만 `dependencies.tools`를 추가하세요.\n\n## What Coasts does\n\n- **Run** -- `coast run `은 최신 빌드로부터 새 Coast 인스턴스를 생성합니다. `coast run -w `를 사용하면 Codex worktree를 한 단계에서 생성하고 할당할 수 있습니다. 자세한 내용은 [Run](../concepts_and_terminology/RUN.md)을 참고하세요.\n- **Bind mount** -- 컨테이너 생성 시, Coasts는\n `~/.codex/worktrees`를 컨테이너 내부의 `/host-external-wt/{index}`에 마운트합니다.\n- **Discovery** -- `git worktree list --porcelain`는 리포지토리 범위로 동작하므로, 디렉터리에 많은 프로젝트의 worktree가 들어 있더라도 현재 프로젝트에 속한 Codex worktree만 표시됩니다.\n- **Naming** -- 분리된 HEAD worktree는 외부 디렉터리 내 상대 경로(`a0db/my-app`, `eca7/my-app`)로 표시됩니다. 브랜치 기반 worktree는 브랜치 이름으로 표시됩니다.\n- **Assign** -- `coast assign`은 외부 bind mount 경로에서 `/workspace`를 다시 마운트합니다.\n- **Gitignored sync** -- 절대 경로를 사용해 호스트 파일시스템에서 실행되므로, bind mount 없이도 동작합니다.\n- **Orphan detection** -- git watcher는 외부 디렉터리를\n 재귀적으로 스캔하면서 `.git` gitdir 포인터로 필터링합니다. Codex가\n worktree를 삭제하면 Coasts는 인스턴스 할당을 자동으로 해제합니다.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code(로컬, 특별한 처리 없음)\n- `~/.codex/worktrees/` -- Codex(외부, bind mount됨)\n\n## Limitations\n\n- Codex는 언제든지 worktree를 정리할 수 있습니다. Coasts의 orphan detection은\n 이를 문제없이 처리합니다.\n", + "harnesses/CONDUCTOR.md": "# Conductor\n\n## 빠른 설정\n\n[Coast CLI](../GETTING_STARTED.md)가 필요합니다. Coasts를 자동으로 설정하려면 이 프롬프트를\n에이전트의 채팅에 복사하세요:\n\n```prompt-copy\nconductor_setup_prompt.txt\n```\n\nCLI에서 스킬 내용도 가져올 수 있습니다: `coast skills-prompt`.\n\n> **중요:** Conductor는 각 세션을 격리된 git worktree에서 실행합니다. 이\n> 설정 프롬프트는 현재 워크스페이스에만 존재하는 파일을 생성합니다 — 이를\n> 메인 브랜치에 커밋하고 병합하지 않으면 새 세션에서는 사용할 수\n> 없습니다.\n\n설정 후에는 변경 사항이 적용되도록 **Conductor를 완전히 종료한 뒤 다시 여세요**. `/coasts`\n명령이 나타나지 않으면 다시 한 번 종료 후 재실행하세요.\n\n## 설정\n\n`~/conductor/workspaces/`를 `worktree_dir`에 추가하세요. Codex와 달리(모든 프로젝트를 하나의 평면 디렉터리 아래에 저장함), Conductor는 프로젝트별 하위 디렉터리 아래에 worktree를 중첩하므로 경로에 프로젝트 이름이 포함되어야 합니다. 아래 예시에서 `my-app`은 해당 저장소에 대해 `~/conductor/workspaces/` 아래의 실제 폴더 이름과 일치해야 합니다.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nConductor는 저장소별로 워크스페이스 경로를 구성할 수 있으므로, 기본값인 `~/conductor/workspaces`가 현재 설정과 일치하지 않을 수 있습니다. 실제 경로를 확인하려면 Conductor 저장소 설정을 확인하고 그에 맞게 조정하세요 — 디렉터리가 어디에 있든 원리는 동일합니다.\n\nCoasts는 런타임에 `~`를 확장하며, `~/` 또는 `/`로 시작하는 모든 경로를 외부 경로로 취급합니다. 자세한 내용은 [Worktree Directories](../coastfiles/WORKTREE_DIR.md)를 참조하세요.\n\n`worktree_dir`를 변경한 후에는 bind mount가 적용되도록 기존 인스턴스를 **다시 생성**해야 합니다:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree 목록은 즉시 업데이트됩니다(Coasts가 새 Coastfile을 읽기 때문입니다). 그러나 Conductor worktree에 할당하려면 컨테이너 내부의 bind mount가 필요합니다.\n\n## Coasts 지침은 어디에 두어야 하나요\n\nConductor를 Coasts와 함께 작업하기 위한 독립적인 harness로 취급하세요:\n\n- 짧은 Coast Runtime 규칙은 `CLAUDE.md`에 두세요\n- 설정이나 실행 동작 중 실제로 Conductor 전용인 것은 Conductor Repository Settings 스크립트를 사용하세요\n- 여기서는 전체 Claude Code 프로젝트 명령 또는 프로젝트 스킬 동작을 가정하지 마세요\n- 명령을 추가했는데 나타나지 않으면 다시 테스트하기 전에 Conductor를 완전히 종료했다가 다시 여세요\n- 이 저장소가 다른 harness도 함께 사용한다면, 공유 `/coasts` 워크플로를 한 곳에 유지하는 방법은 [Multiple Harnesses](MULTIPLE_HARNESSES.md) 및 [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)를 참조하세요\n\n## Coasts가 수행하는 작업\n\n- **Run** — `coast run `은 최신 빌드에서 새 Coast 인스턴스를 생성합니다. `coast run -w `를 사용하면 Conductor worktree를 생성하고 할당하는 작업을 한 번에 수행할 수 있습니다. [Run](../concepts_and_terminology/RUN.md)을 참조하세요.\n- **Bind mount** — 컨테이너 생성 시 Coasts는 `~/conductor/workspaces/`를 컨테이너의 `/host-external-wt/{index}`에 마운트합니다.\n- **Discovery** — `git worktree list --porcelain`는 저장소 범위로 동작하므로 현재 프로젝트에 속한 worktree만 표시됩니다.\n- **Naming** — Conductor worktree는 이름이 지정된 브랜치를 사용하므로 Coasts UI와 CLI에 브랜치 이름으로 표시됩니다(예: `scroll-to-bottom-btn`). 하나의 브랜치는 한 번에 하나의 Conductor 워크스페이스에서만 체크아웃할 수 있습니다.\n- **Assign** — `coast assign`은 외부 bind mount 경로에서 `/workspace`를 다시 마운트합니다.\n- **Gitignored sync** — 호스트 파일시스템에서 절대 경로로 실행되며, bind mount 없이도 동작합니다.\n- **Orphan detection** — git watcher는 외부 디렉터리를 재귀적으로 스캔하고 `.git` gitdir 포인터를 기준으로 필터링합니다. Conductor가 워크스페이스를 보관 처리하거나 삭제하면 Coasts는 인스턴스 할당을 자동으로 해제합니다.\n\n## 예시\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor(외부, bind-mounted; `my-app`은 저장소 폴더 이름으로 바꾸세요)\n\n## Conductor 환경 변수\n\n- Coasts 내부 런타임 구성에 Conductor 전용 환경 변수(예: `CONDUCTOR_PORT`, `CONDUCTOR_WORKSPACE_PATH`)에 의존하지 마세요. Coasts는 포트, 워크스페이스 경로, 서비스 검색을 독립적으로 관리합니다 — 대신 Coastfile의 `[ports]`와 `coast exec`를 사용하세요.\n", + "harnesses/CURSOR.md": "# Cursor\n\n## Quick setup\n\n[Coast CLI](../GETTING_STARTED.md)가 필요합니다. Coasts를 자동으로 설정하려면\n이 프롬프트를 에이전트의 채팅에 복사하세요:\n\n```prompt-copy\ncursor_setup_prompt.txt\n```\n\nCLI에서도 skill 내용을 가져올 수 있습니다: `coast skills-prompt`.\n\n설정 후 skill 및 규칙 변경 사항이 적용되도록 **Cursor를 다시 시작하세요**.\n\n---\n\n[Cursor](https://cursor.com/docs/agent/overview)는 현재 체크아웃에서 직접 작업할 수 있으며,\nParallel Agents 기능은 `~/.cursor/worktrees//` 아래에 git\nworktree를 생성할 수도 있습니다.\n\nCoasts 문서 기준으로는, 이는 두 가지 설정 경우를 의미합니다:\n\n- 현재 체크아웃에서만 Cursor를 사용 중이라면, Cursor 전용\n `worktree_dir` 항목은 필요하지 않습니다\n- Cursor Parallel Agents를 사용한다면, Coasts가 해당 worktree를\n 발견하고 할당할 수 있도록 Cursor worktree 디렉터리를 `worktree_dir`에 추가하세요\n\n## Setup\n\n### Current checkout only\n\nCursor가 이미 열어 둔 체크아웃만 편집하는 경우, Coasts에는 특별한\nCursor 전용 worktree 경로가 필요하지 않습니다. Coasts는 해당 체크아웃을\n다른 로컬 저장소 루트와 동일하게 처리합니다.\n\n### Cursor Parallel Agents\n\nParallel Agents를 사용한다면, `~/.cursor/worktrees/`를\n`worktree_dir`에 추가하세요:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nCursor는 각 에이전트 worktree를 이 프로젝트별 디렉터리 아래에 저장합니다. Coasts는\n런타임에 `~`를 확장하고 이 경로를 외부 경로로 처리하므로, 바인드 마운트가 적용되려면\n기존 인스턴스를 다시 생성해야 합니다:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nCoastfile 변경 후 worktree 목록은 즉시 업데이트되지만,\nCursor Parallel Agent worktree에 할당하려면 컨테이너 내부의 외부 바인드 마운트가 필요합니다.\n\n## Where Coasts guidance goes\n\n### `AGENTS.md` or `.cursor/rules/coast.md`\n\n짧고 항상 활성화되는 Coast Runtime 규칙은 여기에 두세요:\n\n- 가장 이식성 높은 프로젝트 지침을 원한다면 `AGENTS.md`를 사용하세요\n- Cursor 네이티브 프로젝트 규칙과 설정 UI 지원을 원한다면 `.cursor/rules/coast.md`를 사용하세요\n- 명확한 이유가 없다면 동일한 Coast Runtime 블록을 두 곳 모두에 중복하지 마세요\n\n### `.cursor/skills/coasts/SKILL.md` or shared `.agents/skills/coasts/SKILL.md`\n\n재사용 가능한 `/coasts` 워크플로는 여기에 두세요:\n\n- Cursor 전용 저장소라면 `.cursor/skills/coasts/SKILL.md`가 자연스러운 위치입니다\n- 여러 하네스를 사용하는 저장소라면, 정본 skill을\n `.agents/skills/coasts/SKILL.md`에 두세요; Cursor는 이를 직접 로드할 수 있습니다\n- skill은 실제 `/coasts` 워크플로를 담당해야 합니다: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout`, 그리고 `coast ui`\n\n### `.cursor/commands/coasts.md`\n\nCursor는 프로젝트 명령도 지원합니다. Coasts 문서 기준으로는, 명령은\n선택 사항으로 취급하세요:\n\n- 명시적인 `/coasts` 진입점을 원할 때만 명령을 추가하세요\n- 한 가지 단순한 방법은 해당 명령이 같은 skill을 재사용하도록 하는 것입니다\n- 명령에 별도의 자체 지침을 부여하면, 유지해야 할 워크플로 사본이\n 두 개가 됩니다\n\n### `.cursor/worktrees.json`\n\n`.cursor/worktrees.json`은 Coasts 정책이 아니라 Cursor 자체의\nworktree 부트스트랩에 사용하세요:\n\n- 의존성 설치\n- `.env` 파일 복사 또는 심볼릭 링크 생성\n- 데이터베이스 마이그레이션 또는 기타 일회성 부트스트랩 단계 실행\n\nCoast Runtime 규칙이나 Coast CLI 워크플로를\n`.cursor/worktrees.json`으로 옮기지 마세요.\n\n## Example layout\n\n### Cursor only\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # optional\n.cursor/rules/coast.md # optional alternative to AGENTS.md\n.cursor/worktrees.json # optional, for Parallel Agents bootstrap\n```\n\n### Cursor plus other harnesses\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional\n```\n\n## What Coasts does\n\n- **실행** — `coast run `은 최신 빌드에서 새 Coast 인스턴스를 생성합니다. `coast run -w `를 사용하면 Cursor worktree를 한 단계에서 생성하고 할당할 수 있습니다. [Run](../concepts_and_terminology/RUN.md)을 참조하세요.\n- **현재 체크아웃** — Cursor가 사용자가 연 저장소에서 직접 작업 중인 경우,\n 특별한 Cursor 처리가 필요하지 않습니다.\n- **바인드 마운트** — Parallel Agents의 경우, Coasts는\n `~/.cursor/worktrees/`를 컨테이너 내부의\n `/host-external-wt/{index}`에 마운트합니다.\n- **탐색** — `git worktree list --porcelain`는 여전히 저장소 범위로 동작하므로, Coasts는\n 현재 프로젝트에 속한 Cursor worktree만 표시합니다.\n- **이름 지정** — Cursor Parallel Agent worktree는 Coasts의 CLI와 UI에서\n 브랜치 이름으로 표시됩니다.\n- **할당** — `coast assign`은 Cursor worktree가 선택되면 외부 바인드\n 마운트 경로에서 `/workspace`를 다시 마운트합니다.\n- **Gitignored 동기화** — 절대 경로를 사용해 호스트 파일시스템에서 계속 동작합니다.\n- **고아 감지** — Cursor가 오래된 worktree를 정리하면, Coasts는 누락된 gitdir를 감지하고 필요 시 할당 해제를 할 수 있습니다.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code worktree\n- `~/.codex/worktrees/` — Codex worktree\n- `~/.cursor/worktrees/my-app/` — Cursor Parallel Agent worktree\n\n## Limitations\n\n- Cursor Parallel Agents를 사용하지 않는다면, 단지 Cursor에서 편집 중이라는 이유만으로\n `~/.cursor/worktrees/`를 추가하지 마세요.\n- Coast Runtime 규칙은 항상 활성화되는 한 곳에만 두세요: `AGENTS.md` 또는\n `.cursor/rules/coast.md`. 둘 다 중복하면 내용이 어긋나기 쉽습니다.\n- 재사용 가능한 `/coasts` 워크플로는 skill에 두세요. `.cursor/worktrees.json`은\n Cursor 부트스트랩용이지 Coasts 정책용이 아닙니다.\n- 하나의 저장소를 Cursor, Codex, Claude Code, 또는 T3 Code에서 함께 사용한다면,\n [Multiple Harnesses](MULTIPLE_HARNESSES.md)의 공유 레이아웃을 우선하세요.\n", "harnesses/MULTIPLE_HARNESSES.md": "# 여러 하네스\n\n하나의 저장소가 둘 이상의 하네스에서 사용되는 경우, Coasts 설정을 통합하는 한 가지 방법은\n공유되는 `/coasts` 워크플로를 한 곳에 유지하고 하네스별 상시 적용 규칙은 각 하네스의 파일에\n유지하는 것입니다.\n\n## 권장 레이아웃\n\n```text\nAGENTS.md\nCLAUDE.md\n.cursor/rules/coast.md # optional Cursor-native always-on rules\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional, thin, harness-specific\n.claude/commands/coasts.md # optional, thin, harness-specific\n```\n\n이 레이아웃은 다음과 같이 사용하세요:\n\n- `AGENTS.md` — Codex 및 T3 Code에서 Coasts로 작업하기 위한 짧은 상시 적용 규칙\n- `.cursor/rules/coast.md` — 선택적인 Cursor 기본 상시 적용 규칙\n- `CLAUDE.md` — Claude Code 및 Conductor에서 Coasts로 작업하기 위한 짧은 상시 적용 규칙\n- `.agents/skills/coasts/SKILL.md` — 표준 재사용 가능 `/coasts` 워크플로\n- `.agents/skills/coasts/agents/openai.yaml` — 선택적인 Codex/OpenAI 메타데이터\n- `.claude/skills/coasts` — Claude Code에서도 같은 스킬이 필요할 때 사용하는 Claude용 미러 또는 심볼릭 링크\n- `.cursor/commands/coasts.md` — 선택적인 Cursor 명령 파일; 간단한 한 가지 방법은 같은 스킬을 재사용하게 하는 것입니다\n- `.claude/commands/coasts.md` — 선택적인 명시적 명령 파일; 간단한 한 가지 방법은 같은 스킬을 재사용하게 하는 것입니다\n\n## 단계별 안내\n\n1. Coast Runtime 규칙을 상시 적용 지시 파일에 넣습니다.\n - `AGENTS.md`, `CLAUDE.md`, 또는 `.cursor/rules/coast.md`는 \"모든 작업\" 규칙에 답해야 합니다: 먼저 `coast lookup` 실행, `coast exec` 사용, `coast logs`로 로그 읽기, 일치 항목이 없을 때 `coast assign` 또는 `coast run` 전에 확인 요청.\n2. Coasts용 표준 스킬 하나를 만듭니다.\n - 재사용 가능한 `/coasts` 워크플로를 `.agents/skills/coasts/SKILL.md`에 넣습니다.\n - 해당 스킬 안에서 Coast CLI를 직접 사용합니다: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout`, 그리고 `coast ui`.\n3. 하네스에 다른 경로가 필요한 곳에만 그 스킬을 노출합니다.\n - Codex, T3 Code, Cursor는 모두 `.agents/skills/`를 직접 사용할 수 있습니다.\n - Claude Code는 `.claude/skills/`가 필요하므로, 표준 스킬을 그 위치에 미러링하거나 심볼릭 링크로 연결합니다.\n4. 명시적인 `/coasts` 진입점을 원할 때만 명령 파일을 추가합니다.\n - `.claude/commands/coasts.md` 또는\n `.cursor/commands/coasts.md`를 만든다면, 간단한 한 가지 방법은 명령이 같은 스킬을 재사용하게 하는 것입니다.\n - 명령에 자체적인 별도 지침을 부여하면, 유지 관리해야 할 워크플로의 두 번째 복사본을 떠안게 됩니다.\n5. Conductor 전용 설정은 스킬이 아니라 Conductor에 유지합니다.\n - Conductor 자체에 속하는 bootstrap 또는 실행 동작에는 Conductor Repository Settings 스크립트를 사용합니다.\n - Coasts 정책과 `coast` CLI 사용은 `CLAUDE.md`와 공유 스킬에 유지합니다.\n\n## 구체적인 `/coasts` 예시\n\n좋은 공유 `coasts` 스킬은 세 가지 작업을 수행해야 합니다:\n\n1. `Use Existing Coast`\n - `coast lookup` 실행\n - 일치 항목이 있으면 `coast exec`, `coast ps`, `coast logs` 사용\n2. `Manage Assignment`\n - `coast ls` 실행\n - `coast run`, `coast assign`, `coast unassign`, 또는\n `coast checkout` 제안\n - 기존 슬롯을 재사용하거나 방해하기 전에 확인 요청\n3. `Open UI`\n - `coast ui` 실행\n\n이것이 `/coasts` 워크플로를 두기에 적절한 위치입니다. 상시 적용 파일에는\n스킬이 전혀 호출되지 않더라도 반드시 적용되어야 하는 짧은 규칙만 담아야 합니다.\n\n## 심볼릭 링크 패턴\n\nClaude Code가 Codex, T3 Code, 또는 Cursor와 같은 스킬을 재사용하게 하려면,\n한 가지 방법은 심볼릭 링크를 사용하는 것입니다:\n\n```bash\nmkdir -p .claude/skills\nln -s ../../.agents/skills/coasts .claude/skills/coasts\n```\n\n팀이 심볼릭 링크 사용을 선호하지 않는다면 저장소에 포함된 미러도 괜찮습니다. 주요 목표는\n복사본 간의 불필요한 차이를 피하는 것입니다.\n\n## 하네스별 주의사항\n\n- Claude Code: 프로젝트 스킬과 선택적인 프로젝트 명령은 모두 유효하지만,\n 로직은 스킬에 유지하세요.\n- Cursor: 짧은 Coast Runtime 규칙에는 `AGENTS.md` 또는 `.cursor/rules/coast.md`를 사용하고, 재사용 가능한 워크플로에는 스킬을 사용하며,\n `.cursor/commands`는 선택 사항으로 유지하세요.\n- Conductor: 우선 `CLAUDE.md`와 Conductor 스크립트 및 설정의 조합으로 취급하세요.\n 명령을 추가했는데 표시되지 않으면, 다시 확인하기 전에 앱을 완전히 종료했다가 다시 여세요.\n- T3 Code: 여기서는 가장 얇은 하네스 표면입니다. Codex 스타일의\n `AGENTS.md`와 `.agents/skills` 패턴을 사용하고, Coasts 문서를 위해 별도의\n T3 전용 명령 레이아웃을 새로 만들지 마세요.\n- Codex: `AGENTS.md`는 짧게 유지하고 재사용 가능한 워크플로는\n `.agents/skills`에 두세요.\n", - "harnesses/T3_CODE.md": "# T3 코드\n\n[T3 Code](https://github.com/pingdotgg/t3code)는 `~/.t3/worktrees//`에 git worktree를 생성하고, 이름이 지정된 브랜치로 체크아웃합니다.\n\nT3 Code에서는 항상 활성화되는 Coast Runtime 규칙을 `AGENTS.md`에 두고, 재사용 가능한 `/coasts` 워크플로를 `.agents/skills/coasts/SKILL.md`에 두세요.\n\n이러한 worktree는 프로젝트 루트 외부에 위치하므로, Coasts가 이를 발견하고 마운트하려면 명시적인 구성이 필요합니다.\n\n## 설정\n\n`~/.t3/worktrees/`를 `worktree_dir`에 추가하세요. T3 Code는 프로젝트별 하위 디렉터리 아래에 worktree를 중첩하므로, 경로에는 반드시 프로젝트 이름이 포함되어야 합니다. 아래 예시에서 `my-app`은 `~/.t3/worktrees/` 아래에 있는 저장소의 실제 폴더 이름과 일치해야 합니다.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nCoasts는 런타임에 `~`를 확장하며, `~/` 또는 `/`로 시작하는 모든 경로를 외부 경로로 처리합니다. 자세한 내용은 [Worktree Directories](../coastfiles/WORKTREE_DIR.md)를 참조하세요.\n\n`worktree_dir`를 변경한 후에는 바인드 마운트가 적용되도록 기존 인스턴스를 반드시 **재생성**해야 합니다:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree 목록은 즉시 업데이트되지만(Coasts가 새 Coastfile을 읽음), T3 Code worktree에 할당하려면 컨테이너 내부의 바인드 마운트가 필요합니다.\n\n## Coasts 가이드의 위치\n\nT3 Code에는 다음 레이아웃을 사용하세요:\n\n- 짧은 Coast Runtime 규칙은 `AGENTS.md`에 둡니다\n- 재사용 가능한 `/coasts` 워크플로는 `.agents/skills/coasts/SKILL.md`에 둡니다\n- Coasts를 위해 별도의 T3 전용 프로젝트 명령 또는 슬래시 명령 계층을 추가하지 마세요\n- 이 저장소가 여러 하니스를 사용한다면\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) 및\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)를 참조하세요.\n\n## Coasts가 수행하는 작업\n\n- **실행** — `coast run `은 최신 빌드에서 새 Coast 인스턴스를 생성합니다. `coast run -w `를 사용하면 T3 Code worktree를 생성하고 할당하는 작업을 한 번에 수행할 수 있습니다. 자세한 내용은 [Run](../concepts_and_terminology/RUN.md)을 참조하세요.\n- **바인드 마운트** — 컨테이너 생성 시, Coasts는 `~/.t3/worktrees/`를 컨테이너 내부의 `/host-external-wt/{index}`에 마운트합니다.\n- **발견** — `git worktree list --porcelain`는 저장소 범위로 동작하므로, 현재 프로젝트에 속한 worktree만 표시됩니다.\n- **이름 지정** — T3 Code worktree는 이름이 지정된 브랜치를 사용하므로, Coasts UI와 CLI에서 브랜치 이름으로 표시됩니다.\n- **할당** — `coast assign`은 외부 바인드 마운트 경로에서 `/workspace`를 다시 마운트합니다.\n- **gitignored 동기화** — 절대 경로를 사용해 호스트 파일시스템에서 실행되므로, 바인드 마운트 없이도 작동합니다.\n- **고아 감지** — git watcher는 `.git` gitdir 포인터를 기준으로 필터링하면서 외부 디렉터리를 재귀적으로 스캔합니다. T3 Code가 워크스페이스를 제거하면 Coasts는 인스턴스 할당을 자동으로 해제합니다.\n\n## 예시\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code (로컬, 특별한 처리 없음)\n- `~/.codex/worktrees/` — Codex (외부, 바인드 마운트됨)\n- `~/.t3/worktrees/my-app/` — T3 Code (외부, 바인드 마운트됨; `my-app`을 저장소 폴더 이름으로 바꾸세요)\n\n## 제한 사항\n\n- Coasts 내부의 런타임 구성에 T3 Code 전용 환경 변수를 사용하는 것에 의존하지 마세요. Coasts는 포트, 워크스페이스 경로, 서비스 디스커버리를 독립적으로 관리하므로, 대신 Coastfile `[ports]`와 `coast exec`를 사용하세요.\n", + "harnesses/SHEP.md": "# Shep\n\n## 빠른 설정\n\n[Coast CLI](../GETTING_STARTED.md)가 필요합니다. Coasts를 자동으로 설정하려면 이 프롬프트를 에이전트의 채팅에 복사하세요:\n\n```prompt-copy\nshep_setup_prompt.txt\n```\n\nCLI에서도 스킬 내용을 가져올 수 있습니다: `coast skills-prompt`.\n\n설정 후에는 새 스킬과 프로젝트 지침이 적용되도록 **에디터를 종료했다가 다시 여세요**.\n\n---\n\n[Shep](https://shep-ai.github.io/cli/)는 `~/.shep/repos/{hash}/wt/{branch-slug}`에 worktree를 생성합니다. 해시는 저장소 절대 경로의 SHA-256 앞 16자리 16진수 문자이며, 따라서 저장소별로 결정적이지만 식별하기는 어렵습니다. 주어진 저장소의 모든 worktree는 동일한 해시를 공유하고 `wt/{branch-slug}` 하위 디렉터리로 구분됩니다.\n\nShep CLI에서 `shep feat show `는 worktree 경로를 출력하며, 또는\n`ls ~/.shep/repos`로 저장소별 해시 디렉터리를 나열할 수 있습니다.\n\n해시는 저장소마다 달라지므로, Coasts는 사용자가 해시를 하드코딩할 필요 없이\nshep worktree를 찾기 위해 **glob 패턴**을 사용합니다.\n\n## 설정\n\n`~/.shep/repos/*/wt`를 `worktree_dir`에 추가하세요:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n`*`는 저장소별 해시 디렉터리와 일치합니다. 런타임에 Coasts는 glob을 확장하고,\n일치하는 디렉터리(예: `~/.shep/repos/a21f0cda9ab9d456/wt`)를 찾은 다음 이를\n컨테이너에 bind mount합니다. glob 패턴에 대한 전체 자세한 내용은\n[Worktree Directories](../coastfiles/WORKTREE_DIR.md)를 참조하세요.\n\n`worktree_dir`를 변경한 후에는 bind mount가 적용되도록 기존 인스턴스를 **다시 생성**해야 합니다:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree 목록은 즉시 업데이트됩니다(Coasts가 새 Coastfile을 읽기 때문). 하지만\nShep worktree에 할당하려면 컨테이너 내부의 bind mount가 필요합니다.\n\n## Coasts 지침이 들어가는 위치\n\nShep는 내부적으로 Claude Code를 감싸므로, Claude Code 규칙을 따르세요:\n\n- 짧은 Coast Runtime 규칙은 `CLAUDE.md`에 둡니다\n- 재사용 가능한 `/coasts` 워크플로는 `.claude/skills/coasts/SKILL.md` 또는\n 공유 `.agents/skills/coasts/SKILL.md`에 둡니다\n- 이 저장소가 다른 harness도 함께 사용한다면,\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) 및\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)를 참조하세요\n\n## Coasts가 하는 일\n\n- **실행** -- `coast run `은 최신 빌드에서 새 Coast 인스턴스를 생성합니다. `coast run -w `를 사용하면 Shep worktree를 생성하고 할당하는 작업을 한 번에 할 수 있습니다. [Run](../concepts_and_terminology/RUN.md)을 참조하세요.\n- **Bind mount** -- 컨테이너 생성 시 Coasts는 glob\n `~/.shep/repos/*/wt`를 해석하고 일치하는 각 디렉터리를 컨테이너의\n `/host-external-wt/{index}`에 마운트합니다.\n- **탐색** -- `git worktree list --porcelain`는 저장소 범위로 작동하므로\n 현재 프로젝트에 속한 worktree만 표시됩니다.\n- **이름 지정** -- Shep worktree는 이름 있는 브랜치를 사용하므로 Coasts UI와 CLI에\n 브랜치 이름(예: `feat-green-background`)으로 표시됩니다.\n- **할당** -- `coast assign`은 `/workspace`를 외부 bind mount 경로에서 다시 마운트합니다.\n- **gitignored 동기화** -- 호스트 파일시스템에서 절대 경로로 실행되며 bind mount 없이도 작동합니다.\n- **고아 감지** -- git watcher는 외부 디렉터리를 재귀적으로 스캔하면서\n `.git` gitdir 포인터로 필터링합니다. Shep가 worktree를 삭제하면\n Coasts는 인스턴스 할당을 자동 해제합니다.\n\n## 예시\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/.shep/repos/*/wt` -- Shep (외부, glob 확장을 통한 bind-mounted)\n\n## Shep 경로 구조\n\n```\n~/.shep/repos/\n {sha256-of-repo-path-first-16-chars}/\n wt/\n {branch-slug}/ <-- git worktree\n {branch-slug}/\n```\n\n핵심 사항:\n- 같은 저장소 = 항상 같은 해시(결정적이며 무작위가 아님)\n- 다른 저장소 = 다른 해시\n- 경로 구분자는 해싱 전에 `/`로 정규화됨\n- 해시는 `shep feat show ` 또는 `ls ~/.shep/repos`로 찾을 수 있음\n", + "harnesses/T3_CODE.md": "# T3 코드\n\n## 빠른 설정\n\n[Coast CLI](../GETTING_STARTED.md)가 필요합니다. Coasts를 자동으로 설정하려면 이 프롬프트를 에이전트의 채팅에 복사하세요:\n\n```prompt-copy\nt3_code_setup_prompt.txt\n```\n\nCLI에서 스킬 내용을 가져올 수도 있습니다: `coast skills-prompt`.\n\n설정 후에는 스킬 및 규칙 변경 사항이 적용되도록 **T3 Code를 재시작**하세요.\n\n**참고:** T3 Code는 아직 `.agents/skills/` 또는 `.claude/skills/`의 프로젝트 수준 스킬을 불러오지 못할 수 있습니다. 설정 프롬프트는 또한 스킬을 `~/.codex/skills/coasts/`에 배치하므로 Codex provider에서 전역적으로 사용할 수 있습니다.\n`AGENTS.md`와 `CLAUDE.md`의 Coast Runtime 규칙은 그와 관계없이 모든 작업에 계속 적용됩니다.\n\n---\n\n[T3 Code](https://github.com/pingdotgg/t3code)는 `~/.t3/worktrees//`에 git worktree를 생성하고, 이름이 지정된 브랜치로 체크아웃합니다.\n\nT3 Code는 Codex를 래핑하므로, 항상 적용되는 규칙에는 `AGENTS.md`를 사용하고 재사용 가능한 `/coasts` 워크플로에는 `.agents/skills/coasts/SKILL.md`를 사용합니다.\n\n이러한 worktree는 프로젝트 루트 외부에 위치하므로, Coasts가 이를 발견하고 마운트하려면 명시적인 구성이 필요합니다.\n\n## 설정\n\n`~/.t3/worktrees/`를 `worktree_dir`에 추가하세요. T3 Code는 프로젝트별 하위 디렉터리 아래에 worktree를 중첩하므로, 경로에는 반드시 프로젝트 이름이 포함되어야 합니다. 아래 예시에서 `my-app`은 `~/.t3/worktrees/` 아래에 있는 저장소의 실제 폴더 이름과 일치해야 합니다.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nCoasts는 런타임에 `~`를 확장하며, `~/` 또는 `/`로 시작하는 모든 경로를 외부 경로로 처리합니다. 자세한 내용은 [Worktree Directories](../coastfiles/WORKTREE_DIR.md)를 참조하세요.\n\n`worktree_dir`를 변경한 후에는 바인드 마운트가 적용되도록 기존 인스턴스를 반드시 **재생성**해야 합니다:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nworktree 목록은 즉시 업데이트되지만(Coasts가 새 Coastfile을 읽음), T3 Code worktree에 할당하려면 컨테이너 내부의 바인드 마운트가 필요합니다.\n\n## Coasts 가이드의 위치\n\nT3 Code에는 다음 레이아웃을 사용하세요:\n\n- 짧은 Coast Runtime 규칙은 `AGENTS.md`에 둡니다\n- 재사용 가능한 `/coasts` 워크플로는 `.agents/skills/coasts/SKILL.md`에 둡니다\n- Coasts를 위해 별도의 T3 전용 프로젝트 명령 또는 슬래시 명령 계층을 추가하지 마세요\n- 이 저장소가 여러 하니스를 사용한다면\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) 및\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)를 참조하세요.\n\n## Coasts가 수행하는 작업\n\n- **실행** — `coast run `은 최신 빌드에서 새 Coast 인스턴스를 생성합니다. `coast run -w `를 사용하면 T3 Code worktree를 생성하고 할당하는 작업을 한 번에 수행할 수 있습니다. 자세한 내용은 [Run](../concepts_and_terminology/RUN.md)을 참조하세요.\n- **바인드 마운트** — 컨테이너 생성 시, Coasts는 `~/.t3/worktrees/`를 컨테이너 내부의 `/host-external-wt/{index}`에 마운트합니다.\n- **발견** — `git worktree list --porcelain`는 저장소 범위로 동작하므로, 현재 프로젝트에 속한 worktree만 표시됩니다.\n- **이름 지정** — T3 Code worktree는 이름이 지정된 브랜치를 사용하므로, Coasts UI와 CLI에서 브랜치 이름으로 표시됩니다.\n- **할당** — `coast assign`은 외부 바인드 마운트 경로에서 `/workspace`를 다시 마운트합니다.\n- **gitignored 동기화** — 절대 경로를 사용해 호스트 파일시스템에서 실행되므로, 바인드 마운트 없이도 작동합니다.\n- **고아 감지** — git watcher는 `.git` gitdir 포인터를 기준으로 필터링하면서 외부 디렉터리를 재귀적으로 스캔합니다. T3 Code가 워크스페이스를 제거하면 Coasts는 인스턴스 할당을 자동으로 해제합니다.\n\n## 예시\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code (로컬, 특별한 처리 없음)\n- `~/.codex/worktrees/` — Codex (외부, 바인드 마운트됨)\n- `~/.t3/worktrees/my-app/` — T3 Code (외부, 바인드 마운트됨; `my-app`을 저장소 폴더 이름으로 바꾸세요)\n\n## 제한 사항\n\n- Coasts 내부의 런타임 구성에 T3 Code 전용 환경 변수를 사용하는 것에 의존하지 마세요. Coasts는 포트, 워크스페이스 경로, 서비스 디스커버리를 독립적으로 관리하므로, 대신 Coastfile `[ports]`와 `coast exec`를 사용하세요.\n", + "harnesses/claude_code_setup_prompt.txt": "이 프로젝트에서 Claude Code용 Coasts 스킬을 설정하고 있습니다. 모든\n명령은 프로젝트 루트에서 실행하세요.\n\n## Step 1: Coast CLI 확인\n\n다음 명령을 실행하세요:\n\n coast --version\n\n`coast` 명령을 찾을 수 없으면, 여기서 중지하고 사용자에게 다음과 같이 알려주세요:\n\n \"Coast CLI가 설치되어 있지 않습니다. 먼저 설치하세요: https://coasts.dev/docs/getting-started\"\n\nCLI를 사용할 수 있을 때까지 계속 진행하지 마세요.\n\n## Step 2: 스킬 콘텐츠 가져오기\n\n다음 명령을 실행하세요:\n\n coast skills-prompt\n\n출력에는 두 부분이 있습니다:\n\n- **Coast Runtime 규칙** — 시작부터 `---`로 시작하는 줄 직전까지의 모든 내용\n- **Coasts 스킬** — `---` 프론트매터 블록부터 이후의 모든 내용 (`---` 줄과 그 뒤의 모든 내용 포함)\n\n아래 단계들을 위해 두 부분을 모두 저장하세요.\n\n## Step 3: 사용자에게 묻기\n\n사용자에게 물어보세요: 이것을 **전역으로** 설정할까요(이 머신의 모든 프로젝트에서 사용 가능) 아니면 **이 프로젝트에만** 설정할까요?\n\n## Step 4: 파일 배치\n\n대상 파일이 이미 존재하는 경우, 덮어쓰는 대신 Coast Runtime 섹션을 추가하세요 — 하지만 먼저 `# Coast Runtime` 섹션이 이미 있는지 확인하고, 있으면 건너뛰세요.\n\n**전역 설정:**\n- Coast Runtime 규칙을 `~/.claude/CLAUDE.md`에 추가\n- Coasts 스킬을 `~/.claude/skills/coasts/SKILL.md`에 작성\n\n**프로젝트 설정:**\n- Coast Runtime 규칙을 프로젝트 루트의 `CLAUDE.md`에 추가\n- Coasts 스킬을 `.claude/skills/coasts/SKILL.md`에 작성\n\n## Step 5: Coastfile 업데이트\n\n프로젝트 루트의 `Coastfile`을 읽으세요. `worktree_dir` 필드를\n`[coast]` 섹션에서 확인하세요.\n\n`.claude/worktrees`가 `worktree_dir`에 **아직** 포함되어 있지 않다면:\n\n- `worktree_dir`가 단일 문자열이면, 배열로 변환한 뒤\n `.claude/worktrees`를 추가하세요. 예를 들어, `worktree_dir = \".worktrees\"`는\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]`가 됩니다.\n- `worktree_dir`가 이미 배열이면, 여기에 `.claude/worktrees`를 추가하세요.\n- `worktree_dir`가 아예 없다면,\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]`를 추가하세요.\n\n이것은 상대 경로(프로젝트 루트 내부)이므로 컨테이너 재생성은\n필요하지 않습니다 — 변경 사항은 worktree 목록에 즉시 반영됩니다.\n\n## Step 6: 확인\n\n파일을 배치한 후, 무엇이 생성되었고 어디에 생성되었는지에 대한 요약을 사용자에게 보여주세요.\n\n사용자에게 다음과 같이 알려주세요: 스킬과 `CLAUDE.md`\n변경 사항이 적용되려면 **새 Claude Code 세션을 시작하세요**.\n", + "harnesses/codex_setup_prompt.txt": "이 프로젝트에서 OpenAI Codex용 Coasts 스킬을 설정하고 있습니다. 모든\n명령은 프로젝트 루트에서 실행하세요.\n\n## Step 1: Coast CLI 확인\n\n다음 명령을 실행하세요:\n\n coast --version\n\n`coast` 명령을 찾을 수 없으면, 여기서 중지하고 사용자에게 다음과 같이 알려주세요:\n\n \"Coast CLI가 설치되어 있지 않습니다. 먼저 설치하세요: https://coasts.dev/docs/getting-started\"\n\nCLI를 사용할 수 있을 때까지 계속 진행하지 마세요.\n\n## Step 2: 스킬 내용 가져오기\n\n다음 명령을 실행하세요:\n\n coast skills-prompt\n\n출력은 두 부분으로 구성됩니다:\n\n- **Coast Runtime 규칙** — 시작부터 `---`로 시작하는 줄 **직전까지**의 모든 내용\n- **Coasts 스킬** — `---` 프론트매터 블록부터 그 이후의 모든 내용 (`---` 줄과 그 뒤의 모든 내용을 포함)\n\n아래 단계들을 위해 두 부분을 모두 저장하세요.\n\n## Step 3: 파일 배치\n\nCodex 설정은 항상 프로젝트 수준입니다. 대상 파일이 이미 존재하는 경우, 덮어쓰지 말고 Coast Runtime 섹션을 추가하세요 — 하지만 먼저 `# Coast Runtime` 섹션이 이미 있는지 확인하고, 있으면 건너뛰세요.\n\n- 프로젝트 루트의 `AGENTS.md`에 Coast Runtime 규칙을 추가합니다\n- Coasts 스킬을 `.agents/skills/coasts/SKILL.md`에 작성합니다\n- `.agents/skills/coasts/agents/openai.yaml`을 다음 내용으로 생성합니다:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"이 저장소에 대한 Coasts를 검사, 할당 및 열기\"\n default_prompt: \"사용자가 Coast를 찾거나, 할당하거나, 여는 데 도움이 필요할 때 이 스킬을 사용하세요.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## Step 4: Coastfile 업데이트\n\n프로젝트 루트의 `Coastfile`을 읽으세요. `[coast]` 섹션의\n`worktree_dir` 필드를 확인하세요.\n\n`~/.codex/worktrees`가 아직 `worktree_dir`에 **없다면**:\n\n- `worktree_dir`가 단일 문자열이면, 배열로 변환하고\n `~/.codex/worktrees`를 추가하세요. 예를 들어, `worktree_dir = \".worktrees\"`는\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]`가 됩니다.\n- `worktree_dir`가 이미 배열이면, 여기에 `~/.codex/worktrees`를 추가하세요.\n- `worktree_dir`가 아예 없으면,\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]`를 추가하세요.\n\n이것은 외부 경로이므로, 이 프로젝트에 대해 Coast 인스턴스가 이미 실행 중이라면\n새 바인드 마운트가 적용되도록 `coast run`으로 다시 생성해야 합니다. 이 점을 사용자에게 알리세요.\n\n## Step 5: 확인\n\n파일을 배치한 후, 무엇이 생성되었고 어디에 생성되었는지에 대한 요약을 사용자에게 보여주세요.\n\n사용자에게 다음을 알리세요: 변경된 스킬과 AGENTS.md가 적용되도록 **Codex를 종료했다가 다시 여세요**.\n", + "harnesses/conductor_setup_prompt.txt": "이 프로젝트에서 Conductor용 Coasts 스킬을 설정하고 있습니다. 모든\n명령은 프로젝트 루트에서 실행하세요.\n\n## Step 1: Coast CLI 확인\n\n다음 명령을 실행하세요:\n\n coast --version\n\n`coast` 명령을 찾을 수 없으면 여기서 중단하고 사용자에게 다음과 같이 알리세요:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nCLI를 사용할 수 있을 때까지 계속 진행하지 마세요.\n\n## Step 2: 스킬 내용 가져오기\n\n다음 명령을 실행하세요:\n\n coast skills-prompt\n\n출력은 두 부분으로 구성됩니다:\n\n- **Coast Runtime 규칙** — 시작부터 `---`로 시작하는 줄 직전까지의 모든 내용\n- **Coasts 스킬** — `---` 프론트매터 블록부터 이후의 모든 내용 (`---` 줄과 그 이후의 모든 내용 포함)\n\n아래 단계들을 위해 두 부분을 모두 저장하세요.\n\n## Step 3: 사용자에게 묻기\n\n사용자에게 물어보세요: Conductor에서 어떤 제공자를 사용하시나요?\n\n- **Claude** (Anthropic)\n- **Codex** (OpenAI)\n- **Both**\n- **Other** — 사용자가 다른 제공자를 말하면,\n `coast docs --path SKILLS_FOR_HOST_AGENTS.md` 및\n `coast docs --path harnesses/README.md`를 실행하여 해당 제공자가\n 프로젝트 지침과 스킬을 어디에 두기를 기대하는지 확인한 다음, 같은 패턴을 따르세요\n\n## Step 4: 파일 배치\n\nConductor 설정은 항상 프로젝트 수준입니다. 대상 파일이 이미 존재하면 덮어쓰지 말고\nCoast Runtime 섹션을 추가하세요. 단, 먼저\n`# Coast Runtime` 섹션이 이미 있는지 확인하고 있으면 건너뛰세요.\n\n**사용자가 Claude(또는 both)를 선택한 경우:**\n- 프로젝트 루트의 `CLAUDE.md`에 Coast Runtime 규칙을 추가하세요\n- Coasts 스킬을 `.claude/skills/coasts/SKILL.md`에 작성하세요\n\n**사용자가 Codex(또는 both)를 선택한 경우:**\n- 프로젝트 루트의 `AGENTS.md`에 Coast Runtime 규칙을 추가하세요\n- Coasts 스킬을 `.agents/skills/coasts/SKILL.md`에 작성하세요\n- 다음 내용으로 `.agents/skills/coasts/agents/openai.yaml`을 생성하세요:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## Step 5: 확인\n\n파일을 배치한 후, 무엇이 생성되었고 어디에 생성되었는지 사용자에게 요약해서 보여주세요.\n\n변경 사항이 적용되도록 사용자에게 다음을 알려주세요: **Conductor를 완전히 종료한 뒤 다시 여세요**.\n`/coasts` 명령이 바로 나타나지 않으면, 다시 종료했다가 다시 여세요.\n\n## Step 6: Coastfile 업데이트\n\n프로젝트 루트의 `Coastfile`을 읽으세요. `[coast]` 섹션의 `worktree_dir`\n필드를 확인하세요. 또한 `name` 필드도 읽으세요 — 워크트리 경로를 구성하는 데 필요합니다.\n\nConductor 워크트리 디렉터리는 `~/conductor/workspaces/`이며,\n여기서 ``은 Coastfile의 `name` 필드 값입니다.\n\n해당 경로가 아직 `worktree_dir`에 나열되어 있지 않다면:\n\n- `worktree_dir`가 단일 문자열이면 배열로 변환하고\n Conductor 경로를 추가하세요. 예를 들어, `worktree_dir = \".worktrees\"`는\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]`가 됩니다.\n- `worktree_dir`가 이미 배열이면 Conductor 경로를 여기에 추가하세요.\n- `worktree_dir`가 전혀 없으면 실제 프로젝트 이름을 사용해\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/\"]`를 추가하세요.\n\n이것은 외부 경로이므로, 이 프로젝트에 대해 이미 실행 중인 Coast 인스턴스가 있다면\n새 바인드 마운트가 적용되도록 `coast run`으로 다시 생성해야 합니다.\n이 점을 사용자에게 알려주세요.\n\n## Step 7: 새 파일 커밋\n\nConductor는 각 세션을 격리된 git worktree에서 실행합니다. 커밋되지 않은 파일은\n새 세션으로 유지되지 않습니다. 방금 생성한 파일이 앞으로의 모든 워크스페이스에서\n사용 가능하도록 커밋하세요:\n\n git add CLAUDE.md .claude/ AGENTS.md .agents/ 2>/dev/null; git status\n\n어떤 파일이 스테이징되었는지 사용자에게 보여주고, 커밋하기 전에 확인을 요청하세요.\n커밋 메시지는 `[dh] feat: add Coasts skill for Conductor`와 같은 형식을 사용하세요.\n", + "harnesses/cursor_setup_prompt.txt": "이 프로젝트에서 Cursor용 Coasts 스킬을 설정하고 있습니다. 모든\n명령은 프로젝트 루트에서 실행하세요.\n\n## Step 1: Coast CLI 확인\n\n이 명령을 실행하세요:\n\n coast --version\n\n`coast` 명령을 찾을 수 없으면, 여기서 중단하고 사용자에게 다음과 같이 알리세요:\n\n \"Coast CLI가 설치되어 있지 않습니다. 먼저 설치하세요: https://coasts.dev/docs/getting-started\"\n\nCLI를 사용할 수 있기 전까지는 계속 진행하지 마세요.\n\n## Step 2: 스킬 콘텐츠 가져오기\n\n이 명령을 실행하세요:\n\n coast skills-prompt\n\n출력은 두 부분으로 구성됩니다:\n\n- **Coast Runtime 규칙** — 시작부터 `---`로 시작하는 줄 직전까지의 모든 내용\n- **Coasts 스킬** — `---` 프런트매터 블록부터 이후의 모든 내용 (`---` 줄과 그 뒤의 모든 내용 포함)\n\n아래 단계에 사용할 수 있도록 두 부분을 모두 저장하세요.\n\n## Step 3: 사용자에게 묻기\n\n사용자에게 물어보세요: 이것을 **전역으로** 설정할까요(이 컴퓨터의 모든 프로젝트에서 사용 가능) 아니면 **이 프로젝트에만** 설정할까요?\n\n## Step 4: 파일 배치\n\n대상 파일이 이미 존재하는 경우, 덮어쓰지 말고 Coast Runtime 섹션을 덧붙이세요. 단, 먼저 `# Coast Runtime` 섹션이 이미 있는지 확인하고, 있으면 건너뛰세요.\n\n**전역 설정:**\n- Coast Runtime 규칙을 사용자의 전역 Cursor 규칙에 덧붙이세요\n- Coasts 스킬을 `~/.cursor/skills/coasts/SKILL.md`에 작성하세요\n\n**프로젝트 설정:**\n- Coast Runtime 규칙을 프로젝트 루트의 `AGENTS.md`에 덧붙이세요(또는 사용자가 Cursor 네이티브 규칙을 선호한다면 `.cursor/rules/coast.md` — 사용자에게 물어보세요)\n- Coasts 스킬을 `.cursor/skills/coasts/SKILL.md`에 작성하세요\n\n## Step 5: Coastfile 업데이트\n\n프로젝트 루트의 `Coastfile`을 읽으세요. `[coast]` 섹션의 `worktree_dir` 필드를\n확인하세요. 또한 `name` 필드도 읽으세요 — 워크트리 경로를 구성하는 데\n필요합니다.\n\nCursor 워크트리 디렉터리는 `~/.cursor/worktrees/`이며, 여기서 ``은\nCoastfile의 `name` 필드 값입니다.\n\n해당 경로가 아직 `worktree_dir`에 나열되어 있지 않다면:\n\n- `worktree_dir`가 단일 문자열인 경우, 배열로 변환하고\n Cursor 경로를 추가하세요. 예를 들어, `worktree_dir = \".worktrees\"`는\n `worktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]`가 됩니다.\n- `worktree_dir`가 이미 배열인 경우, Cursor 경로를 여기에 추가하세요.\n- `worktree_dir`가 아예 없는 경우,\n 실제 프로젝트 이름을 사용하여\n `worktree_dir = [\".worktrees\", \"~/.cursor/worktrees/\"]`를 추가하세요.\n\n이것은 외부 경로이므로, 이 프로젝트에 대해 이미 실행 중인 Coast 인스턴스가 있다면\n새 바인드 마운트가 적용되도록 `coast run`으로 다시 생성해야 합니다.\n이 점을 사용자에게 알려주세요.\n\n## Step 6: 확인\n\n파일을 배치한 후, 무엇이 생성되었고 어디에 생성되었는지 사용자에게 요약해서 보여주세요.\n\n사용자에게 다음을 알리세요: 변경된 스킬과 규칙이 적용되려면 **Cursor를 다시 시작**하세요.\n", + "harnesses/shep_setup_prompt.txt": "이 프로젝트에서 Shep용 Coasts 스킬을 설정하고 있습니다. 모든\n명령은 프로젝트 루트에서 실행하세요.\n\n## Step 1: Coast CLI 확인\n\n다음 명령을 실행하세요:\n\n coast --version\n\n`coast` 명령을 찾을 수 없으면, 여기서 중단하고 사용자에게 다음과 같이 알려주세요:\n\n \"Coast CLI가 설치되어 있지 않습니다. 먼저 설치하세요: https://coasts.dev/docs/getting-started\"\n\nCLI를 사용할 수 있을 때까지 계속 진행하지 마세요.\n\n## Step 2: 스킬 콘텐츠 가져오기\n\n다음 명령을 실행하세요:\n\n coast skills-prompt\n\n출력은 두 부분으로 나뉩니다:\n\n- **Coast Runtime 규칙** — 시작부터 `---`로 시작하는 줄 **직전까지의** 모든 내용\n- **Coasts 스킬** — `---` 프런트매터 블록부터 이후의 모든 내용 (`---` 줄과 그 뒤의 모든 내용 포함)\n\n아래 단계들을 위해 두 부분을 모두 저장하세요.\n\n## Step 3: 파일 배치\n\nShep는 Claude Code를 래핑하므로, Claude Code 파일 레이아웃을 사용하세요. 대상 파일이\n이미 존재하는 경우, 덮어쓰지 말고 Coast Runtime 섹션을 추가하세요. 하지만\n먼저 `# Coast Runtime` 섹션이 이미 있는지 확인하고, 있으면 건너뛰세요.\n\n- 프로젝트 루트의 `CLAUDE.md`에 Coast Runtime 규칙을 추가합니다\n- Coasts 스킬을 `.agents/skills/coasts/SKILL.md`에 작성합니다 (또는\n 프로젝트가 이미 해당 레이아웃을 사용하는 경우 `.claude/skills/coasts/SKILL.md`)\n\n## Step 4: Coastfile 업데이트\n\n프로젝트 루트의 `Coastfile`을 읽으세요. `[coast]` 섹션의\n`worktree_dir` 필드를 확인하세요.\n\n`~/.shep/repos/*/wt`가 `worktree_dir`에 **아직** 포함되어 있지 않다면:\n\n- `worktree_dir`가 단일 문자열이면, 배열로 변환하고\n `~/.shep/repos/*/wt`를 추가하세요. 예를 들어, `worktree_dir = \".worktrees\"`는\n `worktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]`가 됩니다.\n- `worktree_dir`가 이미 배열이라면, 여기에 `~/.shep/repos/*/wt`를 추가하세요.\n- `worktree_dir`가 아예 없다면,\n `worktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]`를 추가하세요.\n\n`*`는 저장소별 해시 디렉터리와 일치하는 glob 패턴입니다. Coasts는\n런타임에 이를 확장합니다.\n\n이것은 외부 경로이므로, 이 프로젝트에 대해 Coast 인스턴스가 이미 실행 중이라면\n새 bind mount가 적용되도록 `coast run`으로 다시 생성해야 합니다. 이 점을 사용자에게 알려주세요.\n\n## Step 5: 확인\n\n파일을 배치한 후, 무엇이 생성되었고 어디에 생성되었는지 사용자에게 요약해서 보여주세요.\n\n사용자에게 다음을 알려주세요: **에디터를 종료했다가 다시 여세요** 그래야 스킬과 `CLAUDE.md`\n변경 사항이 적용됩니다.\n", + "harnesses/t3_code_setup_prompt.txt": "이 프로젝트에서 T3 Code용 Coasts 스킬을 설정하고 있습니다. 모든\n명령은 프로젝트 루트에서 실행하세요.\n\n## Step 1: Coast CLI 확인\n\n다음 명령을 실행하세요:\n\n coast --version\n\n`coast` 명령을 찾을 수 없다면, 여기서 중단하고 사용자에게 다음과 같이 알려주세요:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nCLI를 사용할 수 있을 때까지 계속 진행하지 마세요.\n\n## Step 2: 스킬 콘텐츠 가져오기\n\n다음 명령을 실행하세요:\n\n coast skills-prompt\n\n출력은 두 부분으로 나뉩니다:\n\n- **Coast Runtime rules** — 시작부터 `---`로 시작하는 줄 직전까지의 모든 내용\n- **Coasts skill** — `---` 프론트매터 블록부터 이후의 모든 내용 (`---` 줄과 그 이후의 모든 내용 포함)\n\n아래 단계에서 사용할 수 있도록 두 부분을 모두 저장하세요.\n\n## Step 3: 사용자에게 묻기\n\nT3 Code는 여러 제공자를 지원합니다. 사용자에게 물어보세요: T3 Code에서\n어떤 제공자를 사용하시나요?\n\n- **Codex** (OpenAI)\n- **Claude** (Anthropic)\n- **Both**\n- **Other** — 사용자가 다른 제공자를 언급하면,\n `coast docs --path SKILLS_FOR_HOST_AGENTS.md` 및\n `coast docs --path harnesses/README.md`를 실행하여 해당 제공자가\n 프로젝트 지침과 스킬을 어디에서 기대하는지 확인한 다음, 동일한 패턴을 따르세요\n\n## Step 4: 파일 배치\n\nT3 Code 설정은 항상 프로젝트 수준입니다. 대상 파일이 이미 존재하면,\n덮어쓰는 대신 Coast Runtime 섹션을 덧붙이세요 — 하지만 먼저\n`# Coast Runtime` 섹션이 이미 있는지 확인하고, 있다면 건너뛰세요.\n\n**사용자가 Codex를 선택한 경우(또는 both):**\n- 프로젝트 루트의 `AGENTS.md`에 Coast Runtime 규칙을 덧붙이세요\n- Coasts 스킬을 `.agents/skills/coasts/SKILL.md`에 작성하세요 (프로젝트 수준)\n- Coasts 스킬을 `~/.codex/skills/coasts/SKILL.md`에도 작성하세요 (전역\n 폴백 — T3 Code가 아직 프로젝트 수준 `.agents/skills/`를 스캔하지 못할 수 있음)\n- 다음 내용으로 `.agents/skills/coasts/agents/openai.yaml`을 생성하세요:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n**사용자가 Claude를 선택한 경우(또는 both):**\n- 프로젝트 루트의 `CLAUDE.md`에 Coast Runtime 규칙을 덧붙이세요\n- Coasts 스킬을 `.claude/skills/coasts/SKILL.md`에 작성하세요 (프로젝트 수준)\n- Coasts 스킬을 `~/.claude/skills/coasts/SKILL.md`에도 작성하세요 (전역\n 폴백 — T3 Code가 아직 프로젝트 수준 `.claude/skills/`를 안정적으로 스캔하지 못할 수 있음)\n\n**참고:** T3 Code는 아직 `.agents/skills/` 또는\n`.claude/skills/`의 프로젝트 수준 스킬을 로드하지 못할 수 있습니다. `AGENTS.md`와 `CLAUDE.md`의 규칙은 그래도\n모든 작업에 항상 적용됩니다. 전역 `~/.codex/skills/coasts/` 폴백은\nCodex 제공자가 스킬을 찾을 수 있도록 보장합니다.\n\n## Step 5: Coastfile 업데이트\n\n프로젝트 루트의 `Coastfile`을 읽으세요. `[coast]` 섹션의 `worktree_dir` 필드를\n확인하세요. 또한 `name` 필드도 읽으세요 — 워크트리 경로를 구성하는 데 필요합니다.\n\nT3 Code 워크트리 디렉터리는 `~/.t3/worktrees/`이며, 여기서 ``은\nCoastfile의 `name` 필드 값입니다.\n\n해당 경로가 `worktree_dir`에 **아직** 나열되어 있지 않다면:\n\n- `worktree_dir`가 단일 문자열이면, 배열로 변환하고\n T3 Code 경로를 덧붙이세요. 예를 들어, `worktree_dir = \".worktrees\"`는\n `worktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]`가 됩니다.\n- `worktree_dir`가 이미 배열이면, 여기에 T3 Code 경로를 덧붙이세요.\n- `worktree_dir`가 아예 없으면,\n `worktree_dir = [\".worktrees\", \"~/.t3/worktrees/\"]`를\n 실제 프로젝트 이름을 사용하여 추가하세요.\n\n이것은 외부 경로이므로, 이 프로젝트에 대해 Coast 인스턴스가 이미 실행 중이라면\n새 bind mount가 적용되도록 `coast run`으로 다시 생성해야 합니다.\n이 점을 사용자에게 알려주세요.\n\n## Step 6: 확인\n\n파일 배치가 끝나면, 무엇이 생성되었고 어디에 생성되었는지 사용자에게\n요약해서 보여주세요. 전역 `~/.codex/skills/coasts/` 사본은\nT3 Code가 아직 프로젝트 수준 스킬을 로드하지 못하는 문제를 위한\n우회책이라고 설명하세요.\n\n사용자에게 다음을 알려주세요: 스킬 및 규칙 변경 사항이 적용되도록\n**T3 Code를 다시 시작하세요**.\n", "learn-coasts-videos/README.md": "# Coasts 비디오 과정\n\nCoasts의 핵심 아이디어를 다루는 짧은 비디오 과정입니다. 각 레슨은 3분 이내입니다. 전체 그림을 보려면 순서대로 시청하거나, 필요한 주제로 바로 이동하세요.\n\n```youtube\nMBGKSKau4sU\n```\n\n## 레슨\n\n1. [Coasts](coasts.md) — Coast가 무엇인지와 핵심 모델이 어떻게 작동하는지.\n2. [Ports](ports.md) — Coasts가 포트 격리와 병렬 런타임 접근을 어떻게 처리하는지.\n3. [Assign](assign.md) — 실행 중인 Coast를 워크트리 간에 전환하기.\n4. [Checkout](checkout.md) — 활발히 사용하기 위해 Coast를 정식 포트로 가져오기.\n5. [Volumes](volumes.md) — Coasts가 볼륨과 지속적인 서비스 상태를 어떻게 다루는지.\n6. [Secrets](secrets.md) — Coast 내부에서 시크릿 관리하기.\n7. [Getting Started](getting-started.md) — 실제 프로젝트에서 Coasts를 사용해 보는 실습형 안내.\n8. [Coast UI](coast-ui.md) — Coastguard UI와 그것이 표시하는 런타임 정보.\n", "learn-coasts-videos/assign.md": "# 할당\n\n```youtube\nLYCeequ54nk\n```\n\n할당은 런타임을 종료하지 않고 실행 중인 Coast를 한 워크트리에서 다른 워크트리로 이동합니다. 이 비디오는 할당이 어떻게 작동하는지와 Coast를 다른 브랜치로 넘기기 위해 언제 사용하는지를 다룹니다.\n\n전체 참조는 [할당 및 할당 해제](../concepts_and_terminology/ASSIGN.md)를 참조하세요.\n", "learn-coasts-videos/checkout.md": "# 체크아웃\n\n```youtube\nJRAXkM4U1UE\n```\n\n체크아웃은 프로젝트의 표준 포트를 특정 Coast 인스턴스에 매핑합니다. 이 비디오는 포트 번호를 전혀 변경하지 않고도 브라우저, API 클라이언트, 테스트 스위트가 모두 올바른 환경에 연결되도록 하나의 Coast를 앞으로 가져오는 방법을 보여줍니다.\n\n전체 참조는 [Checkout](../concepts_and_terminology/CHECKOUT.md)를 참조하세요.\n", @@ -1912,6 +1948,11 @@ "path": "harnesses/MULTIPLE_HARNESSES.md", "type": "file" }, + { + "name": "SHEP.md", + "path": "harnesses/SHEP.md", + "type": "file" + }, { "name": "T3_CODE.md", "path": "harnesses/T3_CODE.md", @@ -1992,11 +2033,11 @@ "files": { "README.md": "# Документация Coasts\n\n```youtube\nMBGKSKau4sU\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## Установка\n\n- `curl -fsSL https://coasts.dev/install | sh`\n- `coast daemon install`\n\n*Если вы решите не запускать `coast daemon install`, вы несёте ответственность за ручной запуск демона командой `coast daemon start` каждый раз.*\n\n## Что такое Coasts?\n\nA Coast (**контейнеризованный хост**) — это локальная среда выполнения для разработки. Coasts позволяют запускать несколько изолированных окружений для одного и того же проекта на одной машине.\n\nCoasts особенно полезны для сложных стеков `docker-compose` с множеством взаимозависимых сервисов, но они столь же эффективны и для неконтейнеризованных локальных dev-настроек. Coasts поддерживают широкий набор [паттернов конфигурации среды выполнения](concepts_and_terminology/RUNTIMES_AND_SERVICES.md), чтобы вы могли сформировать идеальное окружение для нескольких агентов, работающих параллельно.\n\nCoasts создавались для локальной разработки, а не как хостинговый облачный сервис. Ваши окружения запускаются локально на вашей машине.\n\nПроект Coasts — это бесплатное, локальное ПО под лицензией MIT, не привязанное ни к провайдеру агентов, ни к harness’у для агентов, без AI-апсейлов.\n\nCoasts работают с любым агентным workflow для кодинга, который использует worktrees. Никакой специальной конфигурации на стороне harness не требуется.\n\n## Почему Coasts для Worktrees\n\nGit worktrees отлично изолируют изменения кода, но сами по себе они не решают изоляцию среды выполнения.\n\nКогда вы запускаете несколько worktrees параллельно, вы быстро сталкиваетесь с проблемами эргономики:\n\n- [Конфликты портов](concepts_and_terminology/PORTS.md) между сервисами, которым нужны одни и те же порты хоста.\n- Настройка базы данных и [томов](concepts_and_terminology/VOLUMES.md) для каждого worktree, которой утомительно управлять.\n- Окружения для интеграционных тестов, которым нужна кастомная «проводка» среды выполнения под каждый worktree.\n- Настоящий ад переключения worktrees и пересборки runtime-контекста каждый раз. См. [Assign and Unassign](concepts_and_terminology/ASSIGN.md).\n\nЕсли Git — это контроль версий для вашего кода, то Coasts — это как Git для сред выполнения ваших worktrees.\n\nКаждое окружение получает свои собственные порты, так что вы можете инспектировать среду выполнения любого worktree параллельно. Когда вы [check out](concepts_and_terminology/CHECKOUT.md) среду выполнения worktree, Coasts переназначают её на канонические порты вашего проекта.\n\nCoasts абстрагируют конфигурацию среды выполнения в простой модульный слой поверх worktrees, чтобы каждый worktree мог запускаться с нужной ему изоляцией без ручного сопровождения сложной настройки для каждого worktree.\n\n## Требования\n\n- macOS или Linux\n- Docker Desktop на macOS или Docker Engine с плагином Compose на Linux\n- Проект, использующий Git\n- Node.js\n- `socat` (`brew install socat` на macOS, `sudo apt install socat` на Ubuntu)\n\n```text\nПримечание для Linux: Динамические порты работают на Linux из коробки.\nЕсли вам нужны канонические порты ниже `1024`, см. документацию по checkout для необходимой конфигурации хоста.\n```\n\n## Контейнеризация агентов?\n\nВы можете контейнеризовать агента с помощью Coast. На первый взгляд это может показаться отличной идеей, но во многих случаях вам на самом деле не нужно запускать вашего coding-агента внутри контейнера.\n\nПоскольку Coasts делят [файловую систему](concepts_and_terminology/FILESYSTEM.md) с вашей хост-машиной через общий volume mount, самый простой и надёжный workflow — запускать агента на хосте и поручать ему выполнять ресурсоёмкие задачи среды выполнения (например, интеграционные тесты) внутри экземпляра Coast с помощью [`coast exec`](concepts_and_terminology/EXEC_AND_DOCKER.md).\n\nОднако, если вы всё же хотите запускать агента в контейнере, Coasts полностью поддерживают это через [Agent Shells](concepts_and_terminology/AGENT_SHELLS.md). Для такой схемы можно собрать невероятно сложный rig, включая [конфигурацию MCP-сервера](concepts_and_terminology/MCP_SERVERS.md), но она может не обеспечивать чистую интероперабельность с программным обеспечением оркестрации, которое существует сегодня. Для большинства workflow агенты на стороне хоста проще и надёжнее.\n\n## Coasts vs Dev Containers\n\nCoasts — это не dev containers, и это не одно и то же.\n\nDev containers обычно предназначены для подключения IDE к одному контейнеризованному workspace разработки. Coasts — headless и оптимизированы как лёгковесные окружения для параллельного использования агентами с worktrees — несколько изолированных, worktree-aware сред выполнения, запущенных бок о бок, с быстрым переключением checkout и контролями изоляции runtime для каждого экземпляра.\n\n## Demo Repo\n\nЕсли вам нужен небольшой пример проекта, чтобы попробовать Coasts, начните с [`coasts-demo` repository](https://github.com/coast-guard/coasts-demo).\n\n## Coasts Video Course\n\nЕсли вы предпочитаете видео, [Coasts Video Course](learn-coasts-videos/README.md) охватывает каждую ключевую концепцию менее чем за три минуты.\n", "GETTING_STARTED.md": "# Начало работы с Coasts\n\n```youtube\nJe921fgJ4RY\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## Установка\n\n```bash\ncurl -fsSL https://coasts.dev/install | sh\ncoast daemon install\n```\n\n*Если вы решите не запускать `coast daemon install`, вы будете обязаны вручную запускать демон с помощью `coast daemon start` каждый раз.*\n\n## Требования\n\n- macOS или Linux\n- Docker Desktop на macOS или Docker Engine с плагином Compose на Linux\n- Проект, использующий Git\n- Node.js\n- `socat` (`brew install socat` на macOS, `sudo apt install socat` на Ubuntu)\n\n```text\nПримечание для Linux: Динамические порты работают на Linux из коробки.\nЕсли вам нужны канонические порты ниже `1024`, см. документацию по checkout для необходимой конфигурации хоста.\n```\n\n## Настройка Coasts в проекте\n\nДобавьте Coastfile в корень вашего проекта. Убедитесь, что вы не находитесь в worktree во время установки.\n\n```text\nmy-project/\n├── Coastfile <-- это то, что читает Coast\n├── docker-compose.yml\n├── Dockerfile\n├── src/\n│ └── ...\n└── ...\n```\n\n`Coastfile` указывает на ваши существующие локальные ресурсы разработки и добавляет конфигурацию, специфичную для Coasts — полный формат см. в [документации Coastfiles](coastfiles/README.md):\n\n```toml\n[coast]\nname = \"my-project\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\ndb = 5432\n```\n\nCoastfile — это лёгкий TOML-файл, который *обычно* указывает на ваш существующий `docker-compose.yml` (он также работает и с неконтейнеризованными локальными dev-настройками) и описывает изменения, необходимые для параллельного запуска вашего проекта — сопоставления портов, стратегии томов и секреты. Разместите его в корне проекта.\n\nСамый быстрый способ создать Coastfile для вашего проекта — поручить это вашему агенту для кодинга.\n\nCLI Coasts поставляется со встроенным промптом, который обучает любого AI-агента полной схеме Coastfile и CLI. Скопируйте его в чат вашего агента, и он проанализирует ваш проект и сгенерирует Coastfile.\n\n```prompt-copy\ninstallation_prompt.txt\n```\n\nВы также можете получить тот же вывод из CLI, запустив `coast installation-prompt`.\n\n## Ваш первый Coast\n\nПеред запуском вашего первого Coast остановите любую уже запущенную среду разработки. Если вы используете Docker Compose, выполните `docker-compose down`. Если у вас запущены локальные dev-серверы, остановите их. Coasts управляют собственными портами и будут конфликтовать со всем, что уже слушает.\n\nКогда ваш Coastfile готов:\n\n```bash\ncoast build\ncoast run dev-1\n```\n\nПроверьте, что ваш экземпляр запущен:\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ~/dev/my-project\n```\n\nПосмотрите, где слушают ваши сервисы:\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\nКаждый экземпляр получает собственный набор динамических портов, поэтому несколько экземпляров могут работать бок о бок. Чтобы сопоставить экземпляр с каноническими портами вашего проекта, сделайте checkout:\n\n```bash\ncoast checkout dev-1\n```\n\nЭто означает, что runtime теперь находится в состоянии checkout, и канонические порты вашего проекта (например, `3000`, `5432`) будут маршрутизироваться на этот экземпляр Coast.\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ✓ ~/dev/my-project\n```\n\nЧтобы открыть UI наблюдаемости Coastguard для вашего проекта:\n\n```bash\ncoast ui\n```\n\n## Что дальше?\n\n- Настройте [skill для вашего host-агента](SKILLS_FOR_HOST_AGENTS.md), чтобы он знал, как взаимодействовать с Coasts\n", - "SKILLS_FOR_HOST_AGENTS.md": "# Навыки для хост-агентов\n\nЕсли вы используете AI-агентов для программирования на хосте, пока ваше приложение работает внутри Coasts, вашему агенту обычно нужны две специфичные для Coast части настройки:\n\n1. всегда активный раздел Coast Runtime в файле проектных инструкций или файле правил вашего harness\n2. переиспользуемый навык рабочего процесса Coast, такой как `/coasts`, если harness поддерживает проектные навыки\n\nБез первой части агент редактирует файлы, но забывает использовать `coast exec`.\nБез второй каждое назначение Coast, лог и UI-процесс приходится заново\nобъяснять в чате.\n\nЭто руководство делает настройку конкретной и специфичной для Coast: какой\nфайл создать, какой текст в него поместить и как это меняется в зависимости от harness.\n\n## Why agents need this\n\nCoasts предоставляет общий [filesystem](concepts_and_terminology/FILESYSTEM.md) между\nвашей хост-машиной и контейнером Coast. Ваш агент редактирует файлы на хосте,\nа запущенные внутри Coast сервисы сразу видят изменения. Но агенту всё равно\nнеобходимо:\n\n1. определить, какой экземпляр Coast соответствует текущему checkout\n2. запускать тесты, сборки и runtime-команды внутри этого Coast\n3. читать логи и статус сервисов из Coast\n4. безопасно обрабатывать назначение worktree, когда Coast ещё не подключён\n\n## What goes where\n\n- `AGENTS.md`, `CLAUDE.md` или `.cursor/rules/coast.md` — короткие правила Coast,\n которые должны применяться в каждой задаче, даже если ни один навык не вызван\n- навык (`.agents/skills/...`, `.claude/skills/...` или `.cursor/skills/...`)\n — сам переиспользуемый workflow Coast, такой как `/coasts`\n- файл команды (`.claude/commands/...` или `.cursor/commands/...`) — необязательная\n явная точка входа для harness, которые это поддерживают; один из простых вариантов —\n сделать так, чтобы команда переиспользовала навык\n\nЕсли один репозиторий использует больше одного harness, храните канонический\nнавык Coast в одном месте и публикуйте его там, где нужно. См.\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md).\n\n## 1. Always-on Coast Runtime rules\n\nДобавьте следующий блок в всегда активный файл проектных инструкций или\nфайл правил соответствующего harness (`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/coast.md` или эквивалент):\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\nЭтот блок должен находиться в всегда активном файле, потому что эти правила\nдолжны применяться в каждой задаче, а не только когда агент явно входит в workflow `/coasts`.\n\n## 2. Reusable `/coasts` skill\n\nКогда harness поддерживает проектные навыки, сохраните содержимое навыка как\n`SKILL.md` в каталоге ваших навыков. Полный текст навыка находится в\n[skills_prompt.txt](skills_prompt.txt) (если вы в режиме CLI, используйте\n`coast skills-prompt`) — всё после блока Coast Runtime является содержимым навыка,\nначиная с frontmatter `---`.\n\nЕсли вы используете Codex или поверхности, специфичные для OpenAI, вы можете\nпри желании добавить `agents/openai.yaml` рядом с навыком для отображаемых\nметаданных или политики вызова. Эти метаданные должны находиться рядом с\nнавыком, а не заменять его.\n\n## Harness quick start\n\n| Harness | Always-on file | Reusable Coast workflow | Notes |\n|---------|----------------|-------------------------|-------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Нет отдельного файла проектной команды, который можно было бы рекомендовать для документации Coast. См. [Codex](harnesses/CODEX.md). |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md` необязателен, но храните логику в навыке. См. [Claude Code](harnesses/CLAUDE_CODE.md). |\n| Cursor | `AGENTS.md` или `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` или общий `.agents/skills/coasts/SKILL.md` | `.cursor/commands/coasts.md` необязателен. `.cursor/worktrees.json` предназначен для bootstrap worktree в Cursor, а не для политики Coast. См. [Cursor](harnesses/CURSOR.md). |\n| Conductor | `CLAUDE.md` | Начните с `CLAUDE.md`; используйте скрипты и настройки Conductor для поведения, специфичного для Conductor | Не предполагайте полную поддержку проектных команд Claude Code. Если новая команда не появляется, полностью закройте и снова откройте Conductor. См. [Conductor](harnesses/CONDUCTOR.md). |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Это самая ограниченная поверхность harness из перечисленных здесь. Используйте layout в стиле Codex и не придумывайте отдельный слой команд T3 для документации Coast. См. [T3 Code](harnesses/T3_CODE.md). |\n\n## Let the agent set itself up\n\nСамый быстрый способ — позволить агенту самому записать правильные файлы.\nСкопируйте приведённый ниже промпт в чат вашего агента — он включает блок Coast Runtime,\nблок навыка `coasts` и специфичные для harness инструкции о том, где должна\nнаходиться каждая часть.\n\n```prompt-copy\nskills_prompt.txt\n```\n\nВы также можете получить тот же вывод из CLI, выполнив `coast skills-prompt`.\n\n## Manual setup\n\n- **Codex:** поместите раздел Coast Runtime в `AGENTS.md`, затем поместите\n переиспользуемый навык `coasts` в `.agents/skills/coasts/SKILL.md`.\n- **Claude Code:** поместите раздел Coast Runtime в `CLAUDE.md`, затем поместите\n переиспользуемый навык `coasts` в `.claude/skills/coasts/SKILL.md`. Добавляйте\n `.claude/commands/coasts.md` только если вам специально нужен файл команды.\n- **Cursor:** поместите раздел Coast Runtime в `AGENTS.md`, если хотите наиболее\n переносимые инструкции, или в `.cursor/rules/coast.md`, если хотите\n project rule в стиле Cursor. Поместите переиспользуемый workflow `coasts` в\n `.cursor/skills/coasts/SKILL.md` для репозитория только под Cursor или в\n `.agents/skills/coasts/SKILL.md`, если репозиторий используется совместно с другими harness.\n Добавляйте `.cursor/commands/coasts.md` только если вам специально нужен явный\n файл команды.\n- **Conductor:** поместите раздел Coast Runtime в `CLAUDE.md`. Используйте\n скрипты Repository Settings в Conductor для bootstrap или поведения запуска,\n специфичного для Conductor. Если вы добавили команду, а она не появляется,\n полностью закройте и снова откройте приложение.\n- **T3 Code:** используйте тот же layout, что и для Codex: `AGENTS.md` плюс\n `.agents/skills/coasts/SKILL.md`. Рассматривайте T3 Code здесь как тонкий\n harness в стиле Codex, а не как отдельную поверхность команд Coast.\n- **Multiple harnesses:** храните канонический навык в\n `.agents/skills/coasts/SKILL.md`. Cursor может загружать его напрямую; при необходимости\n опубликуйте его для Claude Code через `.claude/skills/coasts/`.\n\n## Further reading\n\n- Прочитайте [руководство по Harnesses](harnesses/README.md), чтобы увидеть матрицу по каждому harness\n- Прочитайте [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md), чтобы узнать о шаблоне общей структуры\n- Прочитайте [документацию Coastfiles](coastfiles/README.md), чтобы изучить полную\n схему конфигурации\n- Изучите команды [Coast CLI](concepts_and_terminology/CLI.md) для управления\n экземплярами\n- Ознакомьтесь с [Coastguard](concepts_and_terminology/COASTGUARD.md), веб-интерфейсом для\n наблюдения и управления вашими Coasts\n", + "SKILLS_FOR_HOST_AGENTS.md": "# Навыки для хост-агентов\n\nЕсли вы используете AI-агентов для программирования на хосте, пока ваше приложение работает внутри Coasts, вашему агенту обычно нужны две специфичные для Coast части настройки:\n\n1. всегда активный раздел Coast Runtime в файле проектных инструкций или файле правил вашего harness\n2. переиспользуемый навык рабочего процесса Coast, такой как `/coasts`, если harness поддерживает проектные навыки\n\nБез первой части агент редактирует файлы, но забывает использовать `coast exec`.\nБез второй каждое назначение Coast, лог и UI-процесс приходится заново\nобъяснять в чате.\n\nЭто руководство делает настройку конкретной и специфичной для Coast: какой\nфайл создать, какой текст в него поместить и как это меняется в зависимости от harness.\n\n## Why agents need this\n\nCoasts предоставляет общий [filesystem](concepts_and_terminology/FILESYSTEM.md) между\nвашей хост-машиной и контейнером Coast. Ваш агент редактирует файлы на хосте,\nа запущенные внутри Coast сервисы сразу видят изменения. Но агенту всё равно\nнеобходимо:\n\n1. определить, какой экземпляр Coast соответствует текущему checkout\n2. запускать тесты, сборки и runtime-команды внутри этого Coast\n3. читать логи и статус сервисов из Coast\n4. безопасно обрабатывать назначение worktree, когда Coast ещё не подключён\n\n## What goes where\n\n- `AGENTS.md`, `CLAUDE.md` или `.cursor/rules/coast.md` — короткие правила Coast,\n которые должны применяться в каждой задаче, даже если ни один навык не вызван\n- навык (`.agents/skills/...`, `.claude/skills/...` или `.cursor/skills/...`)\n — сам переиспользуемый workflow Coast, такой как `/coasts`\n- файл команды (`.claude/commands/...` или `.cursor/commands/...`) — необязательная\n явная точка входа для harness, которые это поддерживают; один из простых вариантов —\n сделать так, чтобы команда переиспользовала навык\n\nЕсли один репозиторий использует больше одного harness, храните канонический\nнавык Coast в одном месте и публикуйте его там, где нужно. См.\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md).\n\n## 1. Always-on Coast Runtime rules\n\nДобавьте следующий блок в всегда активный файл проектных инструкций или\nфайл правил соответствующего harness (`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/coast.md` или эквивалент):\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n coast exec --service # service shell\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Use `coast exec --service ` when you need to run inside an app/service container.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\nЭтот блок должен находиться в всегда активном файле, потому что эти правила\nдолжны применяться в каждой задаче, а не только когда агент явно входит в workflow `/coasts`.\n\n## 2. Reusable `/coasts` skill\n\nКогда harness поддерживает проектные навыки, сохраните содержимое навыка как\n`SKILL.md` в каталоге ваших навыков. Полный текст навыка находится в\n[skills_prompt.txt](skills_prompt.txt) (если вы в режиме CLI, используйте\n`coast skills-prompt`) — всё после блока Coast Runtime является содержимым навыка,\nначиная с frontmatter `---`.\n\nЕсли вы используете Codex или поверхности, специфичные для OpenAI, вы можете\nпри желании добавить `agents/openai.yaml` рядом с навыком для отображаемых\nметаданных или политики вызова. Эти метаданные должны находиться рядом с\nнавыком, а не заменять его.\n\n## Harness quick start\n\n| Harness | Always-on file | Reusable Coast workflow | Notes |\n|---------|----------------|-------------------------|-------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Нет отдельного файла проектной команды, который можно было бы рекомендовать для документации Coast. См. [Codex](harnesses/CODEX.md). |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md` необязателен, но храните логику в навыке. См. [Claude Code](harnesses/CLAUDE_CODE.md). |\n| Cursor | `AGENTS.md` или `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` или общий `.agents/skills/coasts/SKILL.md` | `.cursor/commands/coasts.md` необязателен. `.cursor/worktrees.json` предназначен для bootstrap worktree в Cursor, а не для политики Coast. См. [Cursor](harnesses/CURSOR.md). |\n| Conductor | `CLAUDE.md` | Начните с `CLAUDE.md`; используйте скрипты и настройки Conductor для поведения, специфичного для Conductor | Не предполагайте полную поддержку проектных команд Claude Code. Если новая команда не появляется, полностью закройте и снова откройте Conductor. См. [Conductor](harnesses/CONDUCTOR.md). |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Это самая ограниченная поверхность harness из перечисленных здесь. Используйте layout в стиле Codex и не придумывайте отдельный слой команд T3 для документации Coast. См. [T3 Code](harnesses/T3_CODE.md). |\n\n## Let the agent set itself up\n\nСамый быстрый способ — позволить агенту самому записать правильные файлы.\nСкопируйте приведённый ниже промпт в чат вашего агента — он включает блок Coast Runtime,\nблок навыка `coasts` и специфичные для harness инструкции о том, где должна\nнаходиться каждая часть.\n\n```prompt-copy\nskills_prompt.txt\n```\n\nВы также можете получить тот же вывод из CLI, выполнив `coast skills-prompt`.\n\n## Manual setup\n\n- **Codex:** поместите раздел Coast Runtime в `AGENTS.md`, затем поместите\n переиспользуемый навык `coasts` в `.agents/skills/coasts/SKILL.md`.\n- **Claude Code:** поместите раздел Coast Runtime в `CLAUDE.md`, затем поместите\n переиспользуемый навык `coasts` в `.claude/skills/coasts/SKILL.md`. Добавляйте\n `.claude/commands/coasts.md` только если вам специально нужен файл команды.\n- **Cursor:** поместите раздел Coast Runtime в `AGENTS.md`, если хотите наиболее\n переносимые инструкции, или в `.cursor/rules/coast.md`, если хотите\n project rule в стиле Cursor. Поместите переиспользуемый workflow `coasts` в\n `.cursor/skills/coasts/SKILL.md` для репозитория только под Cursor или в\n `.agents/skills/coasts/SKILL.md`, если репозиторий используется совместно с другими harness.\n Добавляйте `.cursor/commands/coasts.md` только если вам специально нужен явный\n файл команды.\n- **Conductor:** поместите раздел Coast Runtime в `CLAUDE.md`. Используйте\n скрипты Repository Settings в Conductor для bootstrap или поведения запуска,\n специфичного для Conductor. Если вы добавили команду, а она не появляется,\n полностью закройте и снова откройте приложение.\n- **T3 Code:** используйте тот же layout, что и для Codex: `AGENTS.md` плюс\n `.agents/skills/coasts/SKILL.md`. Рассматривайте T3 Code здесь как тонкий\n harness в стиле Codex, а не как отдельную поверхность команд Coast.\n- **Multiple harnesses:** храните канонический навык в\n `.agents/skills/coasts/SKILL.md`. Cursor может загружать его напрямую; при необходимости\n опубликуйте его для Claude Code через `.claude/skills/coasts/`.\n\n## Further reading\n\n- Прочитайте [руководство по Harnesses](harnesses/README.md), чтобы увидеть матрицу по каждому harness\n- Прочитайте [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md), чтобы узнать о шаблоне общей структуры\n- Прочитайте [документацию Coastfiles](coastfiles/README.md), чтобы изучить полную\n схему конфигурации\n- Изучите команды [Coast CLI](concepts_and_terminology/CLI.md) для управления\n экземплярами\n- Ознакомьтесь с [Coastguard](concepts_and_terminology/COASTGUARD.md), веб-интерфейсом для\n наблюдения и управления вашими Coasts\n", "VIDEO_TUTORIALS.md": "# Видеоуроки\n\nНа этой странице собраны официальные обучающие видео Coasts с YouTube-канала Coasts.\n\nЕсли вы предпочитаете короткий видеообзор перед тем, как читать остальную документацию, начните с видео-обзора и видео по началу работы, затем переходите к тематическим роликам по конкретным функциям ниже.\n\n## Ссылки\n\n- [Coasts YouTube channel](https://www.youtube.com/@coasts-dev) - Официальный канал с видео Coasts.\n- [Coasts playlist](https://www.youtube.com/playlist?list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw) - Полный плейлист с уроками в одном месте.\n\n## Видео\n\n- [Coasts Overview](https://www.youtube.com/watch?v=MBGKSKau4sU&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=1&pp=iAQB) (2:42) - Краткое введение на высоком уровне: что такое Coasts и зачем они могут понадобиться.\n- [Coasts](https://www.youtube.com/watch?v=kYlB5U9O92E&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=2&pp=iAQB) (1:29) - Короткий обзор основной модели Coasts.\n- [Ports](https://www.youtube.com/watch?v=pBKkBiJ3o-g&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=3&pp=iAQB) (1:46) - Как Coasts обеспечивают изоляцию портов и параллельный доступ во время выполнения.\n- [Assign](https://www.youtube.com/watch?v=LYCeequ54nk&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=4&pp=iAQB) (1:57) - Как переключить запущенный Coast между worktree.\n- [Checkout](https://www.youtube.com/watch?v=JRAXkM4U1UE&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=5&pp=iAQB) (1:46) - Как вывести один Coast на ваши канонические порты для активного использования.\n- [Volumes](https://www.youtube.com/watch?v=k1es1Wf0zp0&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=6&pp=iAQB) (2:00) - Как Coasts работают с томами и постоянным состоянием сервисов.\n- [Secrets](https://www.youtube.com/watch?v=4lAfHUjqn50&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=7&pp=iAQB) (2:09) - Управление секретами внутри Coast.\n- [Getting Started](https://www.youtube.com/watch?v=Je921fgJ4RY&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=8&pp=iAQB) (2:40) - Короткое вводное руководство по началу работы с Coasts.\n- [Coast UI](https://www.youtube.com/watch?v=Ts-YWkhHR8I&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=9&pp=iAQB0gcJCa4KAYcqIYzv) (1:46) - Обзор интерфейса Coastguard и информации о среде выполнения, которую он показывает.\n\nЭта страница отражает текущее содержимое официального плейлиста и может обновляться по мере добавления новых обучающих видео.\n", - "doc_ordering.txt": "# Верхний уровень\nREADME.md\nGETTING_STARTED.md\nSKILLS_FOR_HOST_AGENTS.md\n\n# Изучение Coasts\nlearn-coasts-videos/README.md\nlearn-coasts-videos/coasts.md\nlearn-coasts-videos/ports.md\nlearn-coasts-videos/assign.md\nlearn-coasts-videos/checkout.md\nlearn-coasts-videos/volumes.md\nlearn-coasts-videos/secrets.md\nlearn-coasts-videos/getting-started.md\nlearn-coasts-videos/coast-ui.md\n\n# Обвязки\nharnesses/README.md\nharnesses/CODEX.md\nharnesses/CONDUCTOR.md\nharnesses/CLAUDE_CODE.md\nharnesses/CURSOR.md\nharnesses/T3_CODE.md\nharnesses/MULTIPLE_HARNESSES.md\n\n# Концепции и терминология\nconcepts_and_terminology/README.md\nconcepts_and_terminology/COASTS.md\nconcepts_and_terminology/RUN.md\nconcepts_and_terminology/REMOVE.md\nconcepts_and_terminology/FILESYSTEM.md\nconcepts_and_terminology/DAEMON.md\nconcepts_and_terminology/CLI.md\nconcepts_and_terminology/COASTGUARD.md\nconcepts_and_terminology/PORTS.md\nconcepts_and_terminology/PRIMARY_PORT_AND_DNS.md\nconcepts_and_terminology/ASSIGN.md\nconcepts_and_terminology/CHECKOUT.md\nconcepts_and_terminology/LOOKUP.md\nconcepts_and_terminology/VOLUMES.md\nconcepts_and_terminology/SHARED_SERVICES.md\nconcepts_and_terminology/SECRETS.md\nconcepts_and_terminology/BUILDS.md\nconcepts_and_terminology/COASTFILE_TYPES.md\nconcepts_and_terminology/RUNTIMES_AND_SERVICES.md\nconcepts_and_terminology/BARE_SERVICES.md\nconcepts_and_terminology/MIXED_SERVICE_TYPES.md\nconcepts_and_terminology/LOGS.md\nconcepts_and_terminology/EXEC_AND_DOCKER.md\nconcepts_and_terminology/AGENT_SHELLS.md\nconcepts_and_terminology/MCP_SERVERS.md\nconcepts_and_terminology/PERFORMANCE_OPTIMIZATIONS.md\nconcepts_and_terminology/TROUBLESHOOTING.md\n\n# Coastfiles\ncoastfiles/README.md\ncoastfiles/PROJECT.md\ncoastfiles/WORKTREE_DIR.md\ncoastfiles/PORTS.md\ncoastfiles/SHARED_SERVICES.md\ncoastfiles/SERVICES.md\ncoastfiles/SECRETS.md\ncoastfiles/VOLUMES.md\ncoastfiles/ASSIGN.md\ncoastfiles/INHERITANCE.md\ncoastfiles/AGENT_SHELL.md\ncoastfiles/MCP.md\n\n# Рецепты\nrecipes/README.md\nrecipes/FULLSTACK_MONOREPO.md\n", - "installation_prompt.txt": "Вы устанавливаете Coasts в этот проект. Coast (контейнеризованный хост) — это CLI-инструмент, который запускает несколько изолированных сред разработки на одной машине, используя Docker-in-Docker контейнеры. Каждая среда получает собственные порты, тома и рантайм — идеально для параллельных workflow с worktree.\n\nВаша задача: проанализировать этот проект и сгенерировать Coastfile (TOML-файл с именем \"Coastfile\" в корне проекта).\n\n=== ДОКУМЕНТАЦИЯ ===\n\nУ Coast есть встроенная документация, доступная из CLI. Используйте её, чтобы понять полную схему Coastfile, стратегии томов, поведение assign и другие параметры конфигурации перед генерацией Coastfile.\n\nПросмотрите дерево документации:\n\n coast docs\n\nЭта команда выводит полное дерево документации. Начните с чтения файлов README — они предоставляют индексы, которые помогут найти нужную документацию по каждой теме:\n\n coast docs --path README.md\n coast docs --path coastfiles/README.md\n coast docs --path concepts_and_terminology/README.md\n\nПрочитайте конкретный документ:\n\n coast docs --path coastfiles/PROJECT.md\n coast docs --path coastfiles/VOLUMES.md\n\nПоиск по документации (семантический поиск — опишите, что вы ищете, на естественном языке):\n\n coast search-docs \"how do volume strategies work\"\n coast search-docs \"shared postgres across instances\"\n coast search-docs \"secret injection from environment variables\"\n\nИспользуйте документацию, чтобы принимать обоснованные решения о конфигурации Coastfile для этого проекта. Раздел coastfiles/ подробно покрывает каждую директиву Coastfile.\n\n=== СХЕМА COASTFILE (краткая справка) ===\n\n[coast] — Обязательно. Метаданные проекта.\n\n name (string, required) Идентификатор проекта, используемый в именовании контейнеров/томов.\n compose (string, optional) Путь к docker-compose.yml относительно Coastfile.\n runtime (string, optional) \"dind\" (по умолчанию), \"sysbox\" или \"podman\".\n root (string, optional) Переопределение корня проекта (относительный или абсолютный путь).\n worktree_dir (string, optional) Директория для git worktree (по умолчанию: \".worktrees\"). Автоопределяется по существующим worktree во время выполнения.\n\n[coast.setup] — Необязательно. Настройка самого DinD-контейнера.\n\n packages (array of strings) Пакеты Alpine для установки (например, [\"nodejs\", \"npm\", \"git\"]).\n run (array of strings) Произвольные команды для запуска во время настройки.\n\n[ports] — Обязательно (как минимум один). Карта логического имени в номер порта.\n Эти порты пробрасываются на хост, когда coast checkout выполнен.\n\n Пример:\n [ports]\n web = 3000\n api = 8080\n postgres = 5432\n\n[volumes.*] — Необязательно. Конфигурация по каждому тому.\n\n strategy \"isolated\" (по умолчанию) или \"shared\"\n service Имя сервиса из Compose, который владеет этим томом.\n mount Путь монтирования внутри контейнера сервиса.\n snapshot_source (только isolated) Инициализировать из существующего имени тома.\n\n Пример:\n [volumes.postgres_data]\n strategy = \"isolated\"\n service = \"db\"\n mount = \"/var/lib/postgresql/data\"\n\n[secrets.*] — Необязательно. Извлечение и инъекция секретов.\n\n extractor \"file\", \"env\", \"command\" или \"macos-keychain\"\n inject \"env:VAR_NAME\" или \"file:/path/in/container\"\n ttl Необязательное время истечения (например, \"1h\", \"30m\").\n\n Параметры, специфичные для extractor:\n file: path = \"./path/to/secret\"\n env: var = \"HOST_ENV_VAR\"\n command: run = \"echo secret-value\"\n macos-keychain: item = \"keychain-item-name\"\n\n Пример:\n [secrets.db_password]\n extractor = \"env\"\n var = \"DB_PASSWORD\"\n inject = \"env:DATABASE_PASSWORD\"\n\n[inject] — Необязательно. Инъекция не-секретных файлов/переменных окружения с хоста.\n\n env Массив имён переменных окружения хоста для проброса.\n files Массив путей к файлам на хосте для монтирования.\n\n Пример:\n [inject]\n env = [\"NODE_ENV\", \"DEBUG\"]\n files = [\"~/.ssh/id_ed25519\", \"~/.gitconfig\"]\n\n[shared_services.*] — Необязательно. Сервисы на хостовом Docker daemon, общие для всех инстансов.\n\n image Docker image.\n ports Массив номеров портов.\n volumes Массив монтирований томов.\n env Inline-таблица переменных окружения.\n auto_create_db (bool) Автоматически создать базу данных на инстанс.\n inject Инъекция строки подключения в контейнеры coast.\n\n Пример:\n [shared_services.postgres]\n image = \"postgres:16-alpine\"\n ports = [5432]\n volumes = [\"postgres_data:/var/lib/postgresql/data\"]\n env = { POSTGRES_USER = \"dev\", POSTGRES_PASSWORD = \"dev\", POSTGRES_DB = \"app\" }\n auto_create_db = true\n inject = \"env:DATABASE_URL\"\n\n[assign] — Необязательно. Управляет тем, что происходит при переключении ветки (coast assign).\n\n default \"none\", \"restart\" или \"rebuild\"\n [assign.services] Переопределения по сервисам.\n [assign.rebuild_triggers] Глоб-шаблоны файлов по сервисам, которые триггерят rebuild.\n\n Пример:\n [assign]\n default = \"none\"\n [assign.services]\n api = \"restart\"\n worker = \"rebuild\"\n [assign.rebuild_triggers]\n worker = [\"Dockerfile\", \"package.json\"]\n\n[services.*] — Необязательно. Сервисы как «голые» процессы (docker-compose не нужен).\n\n command Команда shell для запуска.\n port Номер порта.\n restart \"on-failure\" или \"always\".\n\n Пример:\n [services.web]\n command = \"node server.js\"\n port = 3000\n restart = \"on-failure\"\n\n=== ПРИМЕР: Минимальный (без compose) ===\n\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[ports]\napp = 3000\n\n=== ПРИМЕР: С docker-compose ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\npostgres = 5432\nredis = 6379\n\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n\n=== ПРИМЕР: С секретами ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\n\n[secrets.api_key]\nextractor = \"env\"\nvar = \"API_KEY\"\ninject = \"env:API_KEY\"\n\n[secrets.ssh_key]\nextractor = \"file\"\npath = \"~/.ssh/id_ed25519\"\ninject = \"file:/run/secrets/ssh_key\"\n\n=== КЛЮЧЕВЫЕ КОМПРОМИССЫ ДЛЯ ОБСУЖДЕНИЯ С ПОЛЬЗОВАТЕЛЕМ ===\n\nПеред генерацией Coastfile спросите пользователя о любых неоднозначных вариантах конфигурации. Вот основные:\n\nСтратегия базы данных и инфраструктуры — есть три варианта для сервисов вроде postgres и redis:\n - Изолированные тома (по умолчанию): каждый инстанс Coast получает собственную копию данных внутри своего DinD-контейнера. Инстансы не могут мешать друг другу. Лучше всего, когда вы хотите состояние базы данных на ветку.\n - Общие тома: все инстансы читают и пишут в один и тот же том внутри своих DinD-контейнеров. Экономит место на диске, но параллельные записи из нескольких инстансов могут повредить данные.\n - Общие сервисы: запускайте базу данных на хостовом Docker daemon, а не внутри каждого Coast. Все инстансы подключаются к одному общему серверу. Использует меньше всего памяти, поддерживает auto_create_db для баз данных на инстанс на одном postgres, а данные переживают удаление инстанса. Лучше всего для больших команд или машин с ограниченной памятью.\n - Если в проекте есть база данных, спросите пользователя, какой подход им нужен. Объясните компромиссы — isolated самый безопасный, shared services наиболее эффективен по памяти.\n\nСтратегия assign — что происходит при переключении Coast между worktree:\n - \"none\": ничего не делать (для сервисов вроде postgres/redis, которые не меняются между ветками).\n - \"restart\": перезапустить контейнер (для интерпретируемых сервисов, которым нужен лишь перезапуск процесса).\n - \"rebuild\": пересобрать Docker image и перезапустить (для сервисов, где смена ветки влияет на Dockerfile или зависимости сборки).\n - Если в проекте несколько сервисов, спросите, какие из них нужно пересобирать, а какие — перезапускать при переключении ветки.\n\n=== ИНСТРУКЦИИ ===\n\n1. Посмотрите на структуру проекта. Если есть docker-compose.yml, прочитайте его, чтобы определить сервисы, порты и тома.\n2. Определите существующую директорию git worktree. Запустите `git worktree list`, чтобы проверить, настроены ли в проекте git worktree.\n - Если worktree существуют, изучите их пути, чтобы определить общую родительскую директорию (например, если worktree находятся в `../.worktrees/feat-a` и `../.worktrees/feat-b`, то worktree_dir равен `\"../.worktrees\"`).\n - Установите `worktree_dir` в Coastfile в соответствии с обнаруженной директорией.\n - Если worktree отсутствуют, не указывайте `worktree_dir` (Coast по умолчанию использует \".worktrees\"). НЕ используйте \".coasts\" — это засоряет проект директориeй с брендингом Coast.\n3. Прочитайте соответствующую документацию Coast (используйте `coast docs` и `coast search-docs`), чтобы понять стратегии томов, поведение assign и любые параметры конфигурации, применимые к стеку этого проекта.\n4. Спросите пользователя о любых неоднозначных вариантах конфигурации (см. компромиссы выше). Не угадывайте — объясните варианты и дайте им выбрать.\n5. Сгенерируйте Coastfile в корне проекта на основе анализа проекта и ввода пользователя.\n6. Если в проекте нет docker-compose.yml, используйте [services.*] для определений «голых» процессов или [coast.setup] для установки зависимостей.\n7. Запустите `coast build`. Если не удаётся, проверьте ошибку и обратитесь к документации (`coast search-docs \"\"`) для устранения неполадок.\n8. Запустите `coast run dev-1`. Если не удаётся, проверьте ошибку и обратитесь к документации.\n9. Запустите `coast ui`, чтобы открыть панель Coastguard (это для пользователя, когда вы закончите).\n", - "skills_prompt.txt": "# Coast Runtime\n\nЭтот проект использует Coasts — контейнеризированные runtime-среды для запуска сервисов, тестов\nи других runtime-команд. Файловая система является общей между хостом и\nконтейнером, поэтому изменения файлов с любой стороны сразу видны обеим.\n\n## Discovery\n\nПеред первой runtime-командой в сессии выполните:\n\n coast lookup\n\nЭто выводит имя экземпляра, порты и примеры команд. Используйте имя экземпляра\nиз вывода для всех последующих команд.\n\n## What runs where\n\nФайловая система общая, поэтому используйте `coast exec` только для того, что требует\nruntime контейнера (базы данных, сервисы, интеграционные тесты). Всё остальное\nзапускается напрямую на хосте.\n\nИспользуйте `coast exec` для:\n- Тестов, которым нужны работающие сервисы (юнит-тесты, интегрированные с сервисами или dbs, интеграционные тесты, API-тесты)\n- Перезапуска сервисов или операций compose\n- Всего, что обращается к базам данных, кешам или другим контейнерным сервисам\n\nЗапускайте напрямую на хосте:\n- Линтинг, проверку типов, форматирование\n- Git-операции\n- Playwright и браузерные тесты\n- Установку зависимостей на стороне хоста (npm install, pip install)\n- Поиск по файлам, генерацию кода, статический анализ\n\nПример:\n\n coast exec -- sh -c \"cd && npm test\" # нужна DB\n npm run lint # хост подходит\n npx playwright test # хост подходит\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nЕсли `coast lookup` не возвращает совпадений, выполните `coast ls`, чтобы посмотреть, что существует.\n\nЕсли для этого проекта уже запущен неназначенный Coast, предпочтительнее\nназначить ему ваш worktree, а не создавать новый:\n\n coast assign -w \n\nУже занятый Coast тоже можно переназначить с помощью `coast assign`, но сначала уточните\nу пользователя, потому что это прервёт работу текущего слота.\n\nЕсли ни один Coast не запущен, спросите пользователя перед созданием — Coasts могут\nтребовать много памяти:\n\n coast run -w \n\nПроект должен быть собран до того, как можно будет создавать экземпляры. Если `coast run` завершается с ошибкой\nиз-за отсутствия сборки, сначала выполните `coast build`.\n\n## Coastfile setup\n\nЕсли у проекта ещё нет Coastfile или если вам нужно изменить\nCoastfile, сначала прочитайте документацию по Coastfile:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nПрежде чем делать предположения о поведении Coast, изучите документацию:\n\n coast docs # список всех страниц документации\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # семантический поиск\n\n## Rules\n\n- Всегда запускайте `coast lookup` перед первой runtime-командой в сессии.\n- Используйте `coast exec` только для того, что требует runtime контейнера.\n- Запускайте линтинг, проверку типов, форматирование и git напрямую на хосте.\n- Используйте `coast docs` или `coast search-docs`, прежде чем делать предположения о поведении Coast.\n- Не запускайте сервисы напрямую на хосте, если проект предполагает использование Coast.\n\n---\nname: coasts\ndescription: Inspect and control Coast instances for the current checkout. Use\n when the user says \"/coasts\", asks to assign or reassign a Coast, wants to\n run commands or read logs in the matching Coast, wants to create a new Coast,\n or explicitly asks to open Coast UI.\n---\n\n# Coasts\n\nИспользуйте CLI Coast напрямую. Не добавляйте обёртки.\n\n## Orient Yourself\n\nНачните с изучения CLI и документации:\n\n coast # посмотреть все доступные команды\n coast docs # список всех страниц документации\n coast search-docs \"your question\" # семантический поиск\n\nЕсли что-то в поведении Coast непонятно, читайте документацию, прежде чем делать предположения:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\nНаправляйте запросы в один из этих режимов:\n\n1. **Использовать Coast** — выполните `coast lookup`, затем используйте `coast exec`, `coast ps`\n или `coast logs` с подходящим экземпляром.\n2. **Создать или назначить** — выполните `coast ls`, затем `coast run`, чтобы создать новый\n Coast, или `coast assign`, чтобы переназначить существующий.\n3. **Открыть UI** — выполните `coast ui`.\n\n## What Runs Where\n\nХост и Coast используют общую файловую систему. Используйте `coast exec` только для того,\nчто требует работающих внутри контейнера сервисов.\n\n**Используйте `coast exec` для:**\n- Интеграционных тестов, API-тестов и всего, чему нужны базы данных или сервисы\n- Перезапуска сервисов, операций compose\n- Команд, которые взаимодействуют с процессами, существующими только в контейнере\n\n**Запускайте на хосте:**\n- Линтинг (`eslint`, `rubocop`, `golangci-lint`)\n- Проверку типов (`tsc --noEmit`, `go vet`)\n- Форматирование (`prettier`, `gofmt`)\n- Git-операции\n- Playwright и браузерные тесты\n- Статический анализ, генерацию кода\n- Установку пакетов (`npm install`, `pip install`)\n\n## Create and Assign\n\nКогда `coast lookup` не возвращает совпадений:\n\n1. Выполните `coast ls`, чтобы посмотреть доступные слоты.\n2. Предпочитайте `coast run -w `, чтобы создать и назначить за один шаг.\n3. Если сборки ещё нет, сначала выполните `coast build`.\n4. После создания снова выполните `coast lookup` для подтверждения.\n\nКогда вы хотите переключить существующий Coast на другой worktree:\n\n coast assign -w \n\nЭто также работает для уже назначенного или checked-out Coast, но сначала спросите пользователя,\nпрежде чем переназначать занятый слот.\n\n## Coastfile Setup\n\nЕсли проекту нужен новый или изменённый Coastfile, сначала прочитайте документацию:\n\n coast docs --path coastfiles/README.md\n\nДокументация по Coastfile охватывает настройку compose, порты, тома, секреты, общие\nсервисы, bare-сервисы и наследование.\n\n## Safety Rules\n\n- Выполняйте `coast lookup` перед любыми действиями и снова после любого изменения топологии.\n- Спрашивайте перед `coast assign`, `coast unassign` или `coast checkout`, если это\n нарушит работу существующего слота.\n- Предпочитайте создание нового Coast повторному использованию checked-out или уже назначенного\n экземпляра, если только пользователь явно не хочет переназначить существующий слот.\n- Используйте `coast docs` или `coast search-docs`, прежде чем делать предположения.\n", + "doc_ordering.txt": "# Верхний уровень\nREADME.md\nGETTING_STARTED.md\nSKILLS_FOR_HOST_AGENTS.md\n\n# Изучение Coasts\nlearn-coasts-videos/README.md\nlearn-coasts-videos/coasts.md\nlearn-coasts-videos/ports.md\nlearn-coasts-videos/assign.md\nlearn-coasts-videos/checkout.md\nlearn-coasts-videos/volumes.md\nlearn-coasts-videos/secrets.md\nlearn-coasts-videos/getting-started.md\nlearn-coasts-videos/coast-ui.md\n\n# Обвязки\nharnesses/README.md\nharnesses/CODEX.md\nharnesses/CONDUCTOR.md\nharnesses/CLAUDE_CODE.md\nharnesses/CURSOR.md\nharnesses/T3_CODE.md\nharnesses/SHEP.md\nharnesses/MULTIPLE_HARNESSES.md\n\n# Концепции и терминология\nconcepts_and_terminology/README.md\nconcepts_and_terminology/COASTS.md\nconcepts_and_terminology/RUN.md\nconcepts_and_terminology/REMOVE.md\nconcepts_and_terminology/FILESYSTEM.md\nconcepts_and_terminology/DAEMON.md\nconcepts_and_terminology/CLI.md\nconcepts_and_terminology/COASTGUARD.md\nconcepts_and_terminology/PORTS.md\nconcepts_and_terminology/PRIMARY_PORT_AND_DNS.md\nconcepts_and_terminology/ASSIGN.md\nconcepts_and_terminology/CHECKOUT.md\nconcepts_and_terminology/LOOKUP.md\nconcepts_and_terminology/VOLUMES.md\nconcepts_and_terminology/SHARED_SERVICES.md\nconcepts_and_terminology/SECRETS.md\nconcepts_and_terminology/BUILDS.md\nconcepts_and_terminology/COASTFILE_TYPES.md\nconcepts_and_terminology/RUNTIMES_AND_SERVICES.md\nconcepts_and_terminology/BARE_SERVICES.md\nconcepts_and_terminology/MIXED_SERVICE_TYPES.md\nconcepts_and_terminology/LOGS.md\nconcepts_and_terminology/EXEC_AND_DOCKER.md\nconcepts_and_terminology/AGENT_SHELLS.md\nconcepts_and_terminology/MCP_SERVERS.md\nconcepts_and_terminology/PERFORMANCE_OPTIMIZATIONS.md\nconcepts_and_terminology/TROUBLESHOOTING.md\n\n# Coastfiles\ncoastfiles/README.md\ncoastfiles/PROJECT.md\ncoastfiles/WORKTREE_DIR.md\ncoastfiles/PORTS.md\ncoastfiles/SHARED_SERVICES.md\ncoastfiles/SERVICES.md\ncoastfiles/SECRETS.md\ncoastfiles/VOLUMES.md\ncoastfiles/ASSIGN.md\ncoastfiles/INHERITANCE.md\ncoastfiles/AGENT_SHELL.md\ncoastfiles/MCP.md\n\n# Рецепты\nrecipes/README.md\nrecipes/FULLSTACK_MONOREPO.md\n", + "installation_prompt.txt": "Вы устанавливаете Coasts в этот проект. Coast (контейнеризованный хост) — это CLI-инструмент, который запускает несколько изолированных сред разработки на одной машине, используя Docker-in-Docker контейнеры. Каждая среда получает собственные порты, тома и рантайм — идеально для параллельных workflow с worktree.\n\nВаша задача: проанализировать этот проект и сгенерировать Coastfile (TOML-файл с именем \"Coastfile\" в корне проекта).\n\n=== ДОКУМЕНТАЦИЯ ===\n\nУ Coast есть встроенная документация, доступная из CLI. Используйте её, чтобы понять полную схему Coastfile, стратегии томов, поведение assign и другие параметры конфигурации перед генерацией Coastfile.\n\nПросмотрите дерево документации:\n\n coast docs\n\nЭта команда выводит полное дерево документации. Начните с чтения файлов README — они предоставляют индексы, которые помогут найти нужную документацию по каждой теме:\n\n coast docs --path README.md\n coast docs --path coastfiles/README.md\n coast docs --path concepts_and_terminology/README.md\n\nПрочитайте конкретный документ:\n\n coast docs --path coastfiles/PROJECT.md\n coast docs --path coastfiles/VOLUMES.md\n\nПоиск по документации (семантический поиск — опишите, что вы ищете, на естественном языке):\n\n coast search-docs \"how do volume strategies work\"\n coast search-docs \"shared postgres across instances\"\n coast search-docs \"secret injection from environment variables\"\n\nИспользуйте документацию, чтобы принимать обоснованные решения о конфигурации Coastfile для этого проекта. Раздел coastfiles/ подробно покрывает каждую директиву Coastfile.\n\n=== СХЕМА COASTFILE (краткая справка) ===\n\n[coast] — Обязательно. Метаданные проекта.\n\n name (string, required) Идентификатор проекта, используемый в именовании контейнеров/томов.\n compose (string, optional) Путь к docker-compose.yml относительно Coastfile.\n runtime (string, optional) \"dind\" (по умолчанию), \"sysbox\" или \"podman\".\n root (string, optional) Переопределение корня проекта (относительный или абсолютный путь).\n worktree_dir (string or array, optional) Директория или директории для git worktree (по умолчанию: \".worktrees\"). Принимает либо одну строку, либо массив строк. Автоопределяется по существующим worktree во время выполнения.\n\n[coast.setup] — Необязательно. Настройка самого DinD-контейнера.\n\n packages (array of strings) Пакеты Alpine для установки (например, [\"nodejs\", \"npm\", \"git\"]).\n run (array of strings) Произвольные команды для запуска во время настройки.\n\n[ports] — Обязательно (как минимум один). Карта логического имени в номер порта.\n Эти порты пробрасываются на хост, когда coast checkout выполнен.\n\n Пример:\n [ports]\n web = 3000\n api = 8080\n postgres = 5432\n\n[volumes.*] — Необязательно. Конфигурация по каждому тому.\n\n strategy \"isolated\" (по умолчанию) или \"shared\"\n service Имя сервиса из Compose, который владеет этим томом.\n mount Путь монтирования внутри контейнера сервиса.\n snapshot_source (только isolated) Инициализировать из существующего имени тома.\n\n Пример:\n [volumes.postgres_data]\n strategy = \"isolated\"\n service = \"db\"\n mount = \"/var/lib/postgresql/data\"\n\n[secrets.*] — Необязательно. Извлечение и инъекция секретов.\n\n extractor \"file\", \"env\", \"command\" или \"macos-keychain\"\n inject \"env:VAR_NAME\" или \"file:/path/in/container\"\n ttl Необязательное время истечения (например, \"1h\", \"30m\").\n\n Параметры, специфичные для extractor:\n file: path = \"./path/to/secret\"\n env: var = \"HOST_ENV_VAR\"\n command: run = \"echo secret-value\"\n macos-keychain: item = \"keychain-item-name\"\n\n Пример:\n [secrets.db_password]\n extractor = \"env\"\n var = \"DB_PASSWORD\"\n inject = \"env:DATABASE_PASSWORD\"\n\n[inject] — Необязательно. Инъекция не-секретных файлов/переменных окружения с хоста.\n\n env Массив имён переменных окружения хоста для проброса.\n files Массив путей к файлам на хосте для монтирования.\n\n Пример:\n [inject]\n env = [\"NODE_ENV\", \"DEBUG\"]\n files = [\"~/.ssh/id_ed25519\", \"~/.gitconfig\"]\n\n[shared_services.*] — Необязательно. Сервисы на хостовом Docker daemon, общие для всех инстансов.\n\n image Docker image.\n ports Массив номеров портов.\n volumes Массив монтирований томов.\n env Inline-таблица переменных окружения.\n auto_create_db (bool) Автоматически создать базу данных на инстанс.\n inject Инъекция строки подключения в контейнеры coast.\n\n Пример:\n [shared_services.postgres]\n image = \"postgres:16-alpine\"\n ports = [5432]\n volumes = [\"postgres_data:/var/lib/postgresql/data\"]\n env = { POSTGRES_USER = \"dev\", POSTGRES_PASSWORD = \"dev\", POSTGRES_DB = \"app\" }\n auto_create_db = true\n inject = \"env:DATABASE_URL\"\n\n[assign] — Необязательно. Управляет тем, что происходит при переключении ветки (coast assign).\n\n default \"none\", \"restart\" или \"rebuild\"\n [assign.services] Переопределения по сервисам.\n [assign.rebuild_triggers] Глоб-шаблоны файлов по сервисам, которые триггерят rebuild.\n\n Пример:\n [assign]\n default = \"none\"\n [assign.services]\n api = \"restart\"\n worker = \"rebuild\"\n [assign.rebuild_triggers]\n worker = [\"Dockerfile\", \"package.json\"]\n\n[services.*] — Необязательно. Сервисы как «голые» процессы (docker-compose не нужен).\n\n command Команда shell для запуска.\n port Номер порта.\n restart \"on-failure\" или \"always\".\n\n Пример:\n [services.web]\n command = \"node server.js\"\n port = 3000\n restart = \"on-failure\"\n\n=== ПРИМЕР: Минимальный (без compose) ===\n\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[ports]\napp = 3000\n\n=== ПРИМЕР: С docker-compose ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\npostgres = 5432\nredis = 6379\n\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n\n=== ПРИМЕР: С секретами ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\n\n[secrets.api_key]\nextractor = \"env\"\nvar = \"API_KEY\"\ninject = \"env:API_KEY\"\n\n[secrets.ssh_key]\nextractor = \"file\"\npath = \"~/.ssh/id_ed25519\"\ninject = \"file:/run/secrets/ssh_key\"\n\n=== КЛЮЧЕВЫЕ КОМПРОМИССЫ ДЛЯ ОБСУЖДЕНИЯ С ПОЛЬЗОВАТЕЛЕМ ===\n\nПеред генерацией Coastfile спросите пользователя о любых неоднозначных вариантах конфигурации. Вот основные:\n\nСтратегия базы данных и инфраструктуры — есть три варианта для сервисов вроде postgres и redis:\n - Изолированные тома (по умолчанию): каждый инстанс Coast получает собственную копию данных внутри своего DinD-контейнера. Инстансы не могут мешать друг другу. Лучше всего, когда вы хотите состояние базы данных на ветку.\n - Общие тома: все инстансы читают и пишут в один и тот же том внутри своих DinD-контейнеров. Экономит место на диске, но параллельные записи из нескольких инстансов могут повредить данные.\n - Общие сервисы: запускайте базу данных на хостовом Docker daemon, а не внутри каждого Coast. Все инстансы подключаются к одному общему серверу. Использует меньше всего памяти, поддерживает auto_create_db для баз данных на инстанс на одном postgres, а данные переживают удаление инстанса. Лучше всего для больших команд или машин с ограниченной памятью.\n - Если в проекте есть база данных, спросите пользователя, какой подход им нужен. Объясните компромиссы — isolated самый безопасный, shared services наиболее эффективен по памяти.\n\nСтратегия assign — что происходит при переключении Coast между worktree:\n - \"none\": ничего не делать (для сервисов вроде postgres/redis, которые не меняются между ветками).\n - \"restart\": перезапустить контейнер (для интерпретируемых сервисов, которым нужен лишь перезапуск процесса).\n - \"rebuild\": пересобрать Docker image и перезапустить (для сервисов, где смена ветки влияет на Dockerfile или зависимости сборки).\n - Если в проекте несколько сервисов, спросите, какие из них нужно пересобирать, а какие — перезапускать при переключении ветки.\n\n=== ИНСТРУКЦИИ ===\n\n1. Посмотрите на структуру проекта. Если есть docker-compose.yml, прочитайте его, чтобы определить сервисы, порты и тома.\n2. Определите существующую директорию git worktree. Запустите `git worktree list`, чтобы проверить, настроены ли в проекте git worktree.\n - Если worktree существуют, изучите их пути, чтобы определить общую родительскую директорию (например, если worktree находятся в `../.worktrees/feat-a` и `../.worktrees/feat-b`, то worktree_dir равен `\"../.worktrees\"`).\n - Установите `worktree_dir` в Coastfile в соответствии с обнаруженной директорией.\n - Если worktree отсутствуют, не указывайте `worktree_dir` (Coast по умолчанию использует \".worktrees\"). НЕ используйте \".coasts\" — это засоряет проект директориeй с брендингом Coast.\n3. Спросите пользователя, использует ли он какой-либо из этих coding harnesses с этим проектом:\n - **Claude Code** — worktree в `.claude/worktrees`\n - **OpenAI Codex** — worktree в `~/.codex/worktrees`\n - **Cursor** — worktree в `~/.cursor/worktrees/` (где `` — это имя coast из `[coast] name`)\n - **Conductor** — worktree в `~/conductor/workspaces/`\n - **T3 Code** — worktree в `~/.t3/worktrees/`\n Для каждого выбранного harness включите его директорию worktree в массив `worktree_dir`. Объедините их с любой директорией, обнаруженной на шаге 2. Если пользователь не выбрал ни одного и на шаге 2 не было обнаружено ни одного worktree, не указывайте `worktree_dir` (Coast по умолчанию использует \".worktrees\").\n4. Прочитайте соответствующую документацию Coast (используйте `coast docs` и `coast search-docs`), чтобы понять стратегии томов, поведение assign и любые параметры конфигурации, применимые к стеку этого проекта.\n5. Спросите пользователя о любых неоднозначных вариантах конфигурации (см. компромиссы выше). Не угадывайте — объясните варианты и дайте им выбрать.\n6. Сгенерируйте Coastfile в корне проекта на основе анализа проекта и ввода пользователя.\n7. Если в проекте нет docker-compose.yml, используйте [services.*] для определений «голых» процессов или [coast.setup] для установки зависимостей.\n8. Запустите `coast build`. Если не удаётся, проверьте ошибку и обратитесь к документации (`coast search-docs \"\"`) для устранения неполадок.\n9. Запустите `coast run dev-1`. Если не удаётся, проверьте ошибку и обратитесь к документации.\n10. Запустите `coast ui`, чтобы открыть панель Coastguard (это для пользователя, когда вы закончите).\n", + "skills_prompt.txt": "# Coast Runtime\n\nЭтот проект использует Coasts — контейнеризированные runtime-среды для запуска сервисов, тестов\nи других runtime-команд. Файловая система является общей между хостом и\nконтейнером, поэтому изменения файлов с любой стороны сразу видны обеим.\n\n## Discovery\n\nПеред первой runtime-командой в сессии выполните:\n\n coast lookup\n\nЭто выводит имя экземпляра, порты и примеры команд. Используйте имя экземпляра\nиз вывода для всех последующих команд.\n\n## What runs where\n\nФайловая система общая, поэтому используйте `coast exec` только для того, что требует\nruntime контейнера (базы данных, сервисы, интеграционные тесты). Всё остальное\nзапускается напрямую на хосте.\n\nИспользуйте `coast exec` для:\n- Тестов, которым нужны работающие сервисы (юнит-тесты, интегрированные с сервисами или dbs, интеграционные тесты, API-тесты)\n- Перезапуска сервисов или операций compose\n- Всего, что обращается к базам данных, кешам или другим контейнерным сервисам\n\nЗапускайте напрямую на хосте:\n- Линтинг, проверку типов, форматирование\n- Git-операции\n- Playwright и браузерные тесты\n- Установку зависимостей на стороне хоста (npm install, pip install)\n- Поиск по файлам, генерацию кода, статический анализ\n\nПример:\n\n coast exec -- sh -c \"cd && npm test\" # нужна DB\n coast exec --service # shell сервиса\n npm run lint # хост подходит\n npx playwright test # хост подходит\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nЕсли `coast lookup` не возвращает совпадений, выполните `coast ls`, чтобы посмотреть, что существует.\n\nЕсли для этого проекта уже запущен неназначенный Coast, предпочтительнее\nназначить ему ваш worktree, а не создавать новый:\n\n coast assign -w \n\nУже занятый Coast тоже можно переназначить с помощью `coast assign`, но сначала уточните\nу пользователя, потому что это прервёт работу текущего слота.\n\nЕсли ни один Coast не запущен, спросите пользователя перед созданием — Coasts могут\nтребовать много памяти:\n\n coast run -w \n\nПроект должен быть собран до того, как можно будет создавать экземпляры. Если `coast run` завершается с ошибкой\nиз-за отсутствия сборки, сначала выполните `coast build`.\n\n## Coastfile setup\n\nЕсли у проекта ещё нет Coastfile или если вам нужно изменить\nCoastfile, сначала прочитайте документацию по Coastfile:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nПрежде чем делать предположения о поведении Coast, изучите документацию:\n\n coast docs # список всех страниц документации\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # семантический поиск\n\n## Rules\n\n- Всегда запускайте `coast lookup` перед первой runtime-командой в сессии.\n- Используйте `coast exec` только для того, что требует runtime контейнера.\n- Используйте `coast exec --service `, когда вам нужно выполнить команду внутри контейнера приложения/сервиса.\n- Запускайте линтинг, проверку типов, форматирование и git напрямую на хосте.\n- Используйте `coast docs` или `coast search-docs`, прежде чем делать предположения о поведении Coast.\n- Не запускайте сервисы напрямую на хосте, если проект предполагает использование Coast.\n\n---\nname: coasts\ndescription: Inspect and control Coast instances for the current checkout. Use\n when the user says \"/coasts\", asks to assign or reassign a Coast, wants to\n run commands or read logs in the matching Coast, wants to create a new Coast,\n or explicitly asks to open Coast UI.\n---\n\n# Coasts\n\nИспользуйте CLI Coast напрямую. Не добавляйте обёртки.\n\n## Orient Yourself\n\nНачните с изучения CLI и документации:\n\n coast # посмотреть все доступные команды\n coast docs # список всех страниц документации\n coast search-docs \"your question\" # семантический поиск\n\nЕсли что-то в поведении Coast непонятно, читайте документацию, прежде чем делать предположения:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\nНаправляйте запросы в один из этих режимов:\n\n1. **Использовать Coast** — выполните `coast lookup`, затем используйте `coast exec`, `coast ps`,\n или `coast logs` с подходящим экземпляром.\n2. **Создать или назначить** — выполните `coast ls`, затем `coast run`, чтобы создать новый\n Coast, или `coast assign`, чтобы переназначить существующий.\n3. **Открыть UI** — выполните `coast ui`.\n\n## What Runs Where\n\nХост и Coast используют общую файловую систему. Используйте `coast exec` только для того,\nчто требует работающих внутри контейнера сервисов.\n\n**Используйте `coast exec` для:**\n- Интеграционных тестов, API-тестов и всего, чему нужны базы данных или сервисы\n- Перезапуска сервисов, операций compose\n- Команд, которые взаимодействуют с процессами, существующими только в контейнере\n\n**Запускайте на хосте:**\n- Линтинг (`eslint`, `rubocop`, `golangci-lint`)\n- Проверку типов (`tsc --noEmit`, `go vet`)\n- Форматирование (`prettier`, `gofmt`)\n- Git-операции\n- Playwright и браузерные тесты\n- Статический анализ, генерацию кода\n- Установку пакетов (`npm install`, `pip install`)\n\n## Create and Assign\n\nКогда `coast lookup` не возвращает совпадений:\n\n1. Выполните `coast ls`, чтобы посмотреть доступные слоты.\n2. Предпочитайте `coast run -w `, чтобы создать и назначить за один шаг.\n3. Если сборки ещё нет, сначала выполните `coast build`.\n4. После создания снова выполните `coast lookup` для подтверждения.\n\nКогда вы хотите переключить существующий Coast на другой worktree:\n\n coast assign -w \n\nЭто также работает для уже назначенного или checked-out Coast, но сначала спросите пользователя,\nпрежде чем переназначать занятый слот.\n\n## Coastfile Setup\n\nЕсли проекту нужен новый или изменённый Coastfile, сначала прочитайте документацию:\n\n coast docs --path coastfiles/README.md\n\nДокументация по Coastfile охватывает настройку compose, порты, тома, секреты, общие\nсервисы, bare-сервисы и наследование.\n\n## Safety Rules\n\n- Выполняйте `coast lookup` перед любыми действиями и снова после любого изменения топологии.\n- Спрашивайте перед `coast assign`, `coast unassign` или `coast checkout`, если это\n нарушит работу существующего слота.\n- Предпочитайте создание нового Coast повторному использованию checked-out или уже назначенного\n экземпляра, если только пользователь явно не хочет переназначить существующий слот.\n- Используйте `coast docs` или `coast search-docs`, прежде чем делать предположения.\n", "coastfiles/README.md": "# Coastfiles\n\nCoastfile — это конфигурационный файл TOML, который находится в корне вашего проекта. Он сообщает Coast всё, что нужно знать для сборки и запуска изолированных сред разработки для этого проекта — какие сервисы запускать, какие порты пробрасывать, как обрабатывать данные и как управлять секретами.\n\nКаждому проекту Coast нужен как минимум один Coastfile. Файл всегда называется `Coastfile` (с заглавной C, без расширения). Если вам нужны варианты для разных рабочих процессов, вы создаёте типизированные Coastfiles, например `Coastfile.light` или `Coastfile.snap`, которые [наследуются от базового](INHERITANCE.md).\n\nЧтобы глубже понять, как Coastfiles связаны с остальной частью Coast, см. [Coasts](../concepts_and_terminology/COASTS.md) и [Builds](../concepts_and_terminology/BUILDS.md).\n\n## Quickstart\n\nНаименьший возможный Coastfile:\n\n```toml\n[coast]\nname = \"my-app\"\n```\n\nЭто даёт вам контейнер DinD, в который можно войти через `coast exec`. Большинству проектов понадобится либо ссылка на `compose`, либо [bare services](SERVICES.md):\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\napi = 8080\n```\n\nИли без compose, используя bare services:\n\n```toml\n[coast]\nname = \"my-app\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\nrestart = \"on-failure\"\n\n[ports]\nweb = 3000\n```\n\nВыполните `coast build`, затем `coast run dev-1`, и у вас будет изолированная среда.\n\n## Example Coastfiles\n\n### Simple bare-service project\n\nПриложение Next.js без compose-файла. Coast устанавливает Node, выполняет `npm install` и напрямую запускает dev-сервер.\n\n```toml\n[coast]\nname = \"my-crm\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --turbopack --port 3002 --hostname 0.0.0.0\"\nport = 3002\nrestart = \"on-failure\"\n\n[ports]\nweb = 3002\n```\n\n### Full-stack compose project\n\nПроект с несколькими сервисами, с общими базами данных, секретами, стратегиями томов и пользовательской настройкой.\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./infra/docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"python3\", \"curl\", \"git\", \"bash\", \"ca-certificates\", \"wget\"]\nrun = [\n \"ARCH=$(uname -m | sed 's/aarch64/arm64/' | sed 's/x86_64/amd64/') && wget -qO /tmp/go.tar.gz https://go.dev/dl/go1.24.1.linux-${ARCH}.tar.gz && tar -C /usr/local -xzf /tmp/go.tar.gz && rm /tmp/go.tar.gz\",\n \"GOBIN=/usr/local/bin go install github.com/air-verse/air@v1.61.7\",\n]\n\n[ports]\nweb = 3000\nbackend = 8080\npostgres = 5432\nredis = 6379\n\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\" }\n\n[shared_services.redis]\nimage = \"redis:7\"\nports = [6379]\n\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n\n[secrets.db_password]\nextractor = \"env\"\nvar = \"DB_PASSWORD\"\ninject = \"env:DB_PASSWORD\"\n\n[omit]\nservices = [\"monitoring\", \"admin-panel\", \"nginx-proxy\"]\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### Lightweight test variant (inheritance)\n\nРасширяет базовый Coastfile, но упрощает его до того, что нужно только для запуска backend-тестов. Без портов, без общих сервисов, с изолированными базами данных.\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n\n[unset]\nports = [\"web\", \"backend\", \"postgres\", \"redis\"]\nshared_services = [\"postgres\", \"redis\"]\n\n[omit]\nservices = [\"redis\", \"backend\", \"web\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend-test = \"rebuild\"\n```\n\n### Snapshot-seeded variant\n\nКаждый экземпляр coast запускается с копией существующих томов базы данных хоста, а затем развивается независимо.\n\n```toml\n[coast]\nextends = \"Coastfile\"\n\n[unset]\nshared_services = [\"postgres\", \"redis\", \"mongodb\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_mongodb_data\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n\n## Conventions\n\n- Файл должен называться `Coastfile` (с заглавной C, без расширения) и находиться в корне проекта.\n- Типизированные варианты используют шаблон `Coastfile.{type}` — например, `Coastfile.light`, `Coastfile.snap`. См. [Inheritance and Types](INHERITANCE.md).\n- Зарезервированное имя `Coastfile.default` не допускается.\n- Повсюду используется синтаксис TOML. Все заголовки секций используют `[brackets]`, а именованные записи используют `[section.name]` (не array-of-tables).\n- Нельзя использовать одновременно `compose` и `[services]` в одном Coastfile — выберите что-то одно.\n- Относительные пути (для `compose`, `root` и т. д.) разрешаются относительно родительского каталога Coastfile.\n\n## Reference\n\n| Page | Sections | What it covers |\n|------|----------|----------------|\n| [Project and Setup](PROJECT.md) | `[coast]`, `[coast.setup]` | Имя, путь к compose, runtime, каталог worktree, настройка контейнера |\n| [Worktree Directories](WORKTREE_DIR.md) | `worktree_dir`, `default_worktree_dir` | Локальные и внешние каталоги worktree, пути с тильдой, интеграция с Codex/Claude |\n| [Ports](PORTS.md) | `[ports]`, `[egress]` | Проброс портов, объявления egress, основной порт |\n| [Volumes](VOLUMES.md) | `[volumes.*]` | Стратегии томов: изолированные, общие и инициализированные из snapshot |\n| [Shared Services](SHARED_SERVICES.md) | `[shared_services.*]` | Базы данных и инфраструктурные сервисы на уровне хоста |\n| [Secrets](SECRETS.md) | `[secrets.*]`, `[inject]` | Извлечение секретов, внедрение и проброс env/файлов хоста |\n| [Bare Services](SERVICES.md) | `[services.*]` | Запуск процессов напрямую без Docker Compose |\n| [Agent Shell](AGENT_SHELL.md) | `[agent_shell]` | Контейнеризированные TUI-рантаймы агента |\n| [MCP Servers](MCP.md) | `[mcp.*]`, `[mcp_clients.*]` | Внутренние и проксируемые с хоста MCP-серверы, клиентские коннекторы |\n| [Assign](ASSIGN.md) | `[assign]` | Поведение при переключении веток для каждого сервиса |\n| [Inheritance and Types](INHERITANCE.md) | `extends`, `includes`, `[unset]`, `[omit]` | Типизированные Coastfiles, композиция и переопределения |\n", "coastfiles/AGENT_SHELL.md": "# Agent Shell\n\n> **В большинстве рабочих процессов вам не нужно контейнеризировать вашего кодингового агента.** Поскольку Coasts разделяют [файловую систему](../concepts_and_terminology/FILESYSTEM.md) с вашей хост-машиной, самый простой подход — запускать агента на хосте и использовать [`coast exec`](../concepts_and_terminology/EXEC_AND_DOCKER.md) для ресурсоёмких задач во время выполнения, таких как интеграционные тесты. Agent shells предназначены для случаев, когда вы специально хотите, чтобы агент работал внутри контейнера — например, чтобы дать ему прямой доступ к внутреннему Docker-демону или полностью изолировать его окружение.\n\nРаздел `[agent_shell]` настраивает агентский TUI — например, Claude Code или Codex — для запуска внутри контейнера Coast. При наличии этого раздела Coast автоматически поднимает постоянную PTY-сессию, выполняющую настроенную команду при запуске инстанса.\n\nДля полного понимания того, как работают agent shells — активная модель агента, отправка ввода, жизненный цикл и восстановление — см. [Agent Shells](../concepts_and_terminology/AGENT_SHELLS.md).\n\n## Configuration\n\nВ разделе есть одно обязательное поле: `command`.\n\n```toml\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\n### `command` (required)\n\nКоманда оболочки, которую нужно запустить в PTY агента. Обычно это CLI кодингового агента, который вы установили через `[coast.setup]`.\n\nКоманда выполняется внутри контейнера DinD в `/workspace` (корень проекта). Это не compose-сервис — она работает рядом с вашим compose-стеком или отдельными сервисами, а не внутри них.\n\n## Lifecycle\n\n- Agent shell автоматически запускается при `coast run`.\n- В [Coastguard](../concepts_and_terminology/COASTGUARD.md) он отображается как постоянная вкладка \"Agent\", которую нельзя закрыть.\n- Если процесс агента завершится, Coast может перезапустить его.\n- Вы можете отправлять ввод в работающий agent shell через `coast agent-shell input`.\n\n## Examples\n\n### Claude Code\n\nУстановите Claude Code в `[coast.setup]`, настройте учётные данные через [secrets](SECRETS.md), затем настройте agent shell:\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"git\", \"bash\"]\nrun = [\n \"npm install -g @anthropic-ai/claude-code\",\n \"mkdir -p /root/.claude\",\n]\n\n[secrets.claude_credentials]\nextractor = \"keychain\"\nservice = \"Claude Code-credentials\"\ninject = \"file:/root/.claude/.credentials.json\"\n\n[agent_shell]\ncommand = \"cd /workspace; exec claude --dangerously-skip-permissions --effort high\"\n```\n\n### Simple agent shell\n\nМинимальный agent shell для проверки, что функция работает:\n\n```toml\n[coast]\nname = \"test-agent\"\n\n[coast.setup]\npackages = [\"bash\"]\n\n[agent_shell]\ncommand = \"exec sh -c 'while true; do echo agent-heartbeat; sleep 5; done'\"\n```\n", "coastfiles/ASSIGN.md": "# Assign\n\nРаздел `[assign]` управляет тем, что происходит с сервисами внутри инстанса Coast, когда вы переключаете ветки с помощью `coast assign`. Каждый сервис можно настроить с разной стратегией в зависимости от того, нужен ли ему полный пересбор, перезапуск, hot-reload или вообще ничего.\n\nО том, как `coast assign` и `coast unassign` работают во время выполнения, см. [Assign](../concepts_and_terminology/ASSIGN.md).\n\n## `[assign]`\n\n### `default`\n\nДействие по умолчанию, применяемое ко всем сервисам при переключении ветки. По умолчанию `\"restart\"`, если весь раздел `[assign]` опущен.\n\n- **`\"none\"`** — ничего не делать. Сервис продолжает работать как есть. Подходит для баз данных и кешей, которые не зависят от кода.\n- **`\"hot\"`** — код уже live-mounted через [filesystem](../concepts_and_terminology/FILESYSTEM.md), поэтому сервис подхватывает изменения автоматически (например, через файловый watcher или hot-reload). Перезапуск контейнера не нужен.\n- **`\"restart\"`** — перезапустить контейнер сервиса. Используйте, когда сервис читает код при старте, но не требует полной пересборки образа.\n- **`\"rebuild\"`** — пересобрать Docker-образ сервиса и перезапустить. Требуется, когда код запекается в образ через `COPY` или `ADD` в Dockerfile.\n\n```toml\n[assign]\ndefault = \"none\"\n```\n\n### `[assign.services]`\n\nПереопределения для конкретных сервисов. Каждый ключ — это имя compose-сервиса, а значение — одно из четырёх действий выше.\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\nЭто позволяет оставить базы данных и кеши нетронутыми (`\"none\"` через значение по умолчанию), пересобирая или перезапуская только те сервисы, которые зависят от изменившегося кода.\n\n### `[assign.rebuild_triggers]`\n\nШаблоны файлов, которые принудительно запускают пересборку для конкретных сервисов, даже если их действие по умолчанию легче. Каждый ключ — имя сервиса, а значение — список путей к файлам или шаблонов.\n\n```toml\n[assign]\ndefault = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\", \"package-lock.json\"]\n```\n\n### `exclude_paths`\n\nСписок путей, которые нужно исключить из синхронизации worktree во время `coast assign`. Полезно в больших монорепозиториях, где некоторые директории не относятся к сервисам, запущенным в Coast, и иначе замедляли бы операцию assign.\n\n```toml\n[assign]\ndefault = \"none\"\nexclude_paths = [\"apps/ide\", \"apps/extension\", \"apps/ide-extension\"]\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n## Examples\n\n### Пересобрать app, остальное не трогать\n\nКогда ваш сервис app запекает код в свой Docker-образ, но ваши базы данных не зависят от изменений кода:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\n### Hot-reload для frontend и backend\n\nКогда оба сервиса используют file watchers (например, dev-сервер Next.js, Go air, nodemon) и код live-mounted:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### Пересборка по триггерам для конкретного сервиса\n\nСервис API обычно просто перезапускается, но если изменились `Dockerfile` или `package.json`, он пересобирается:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napi = \"restart\"\nworker = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\"]\n```\n\n### Полная пересборка для всего\n\nКогда все сервисы запекают код в свои образы:\n\n```toml\n[assign]\ndefault = \"rebuild\"\n```\n", @@ -2008,19 +2049,19 @@ "coastfiles/SERVICES.md": "# Bare Services\n\n> **Примечание:** Bare-сервисы запускаются напрямую внутри контейнера Coast как обычные процессы — они не контейнеризируются. Если ваши сервисы уже упакованы в Docker, используйте вместо этого `compose`. Bare-сервисы лучше всего подходят для простых конфигураций, где вы хотите избежать накладных расходов на написание Dockerfile и docker-compose.yml.\n\nРазделы `[services.*]` определяют процессы, которые Coast запускает напрямую внутри контейнера DinD, без Docker Compose. Это альтернатива использованию файла `compose` — вы не можете использовать оба варианта в одном Coastfile.\n\nBare-сервисы контролируются (supervised) Coast с перехватом логов и необязательными политиками перезапуска. Для более глубокого понимания того, как работают bare-сервисы, их ограничений и того, когда следует мигрировать на compose, см. [Bare Services](../concepts_and_terminology/BARE_SERVICES.md).\n\n## Определение сервиса\n\nКаждый сервис — это именованный раздел TOML внутри `[services]`. Поле `command` является обязательным.\n\n```toml\n[services.web]\ncommand = \"node server.js\"\nport = 3000\n```\n\n### `command` (обязательно)\n\nКоманда оболочки, которую нужно выполнить. Не должна быть пустой или состоять только из пробельных символов.\n\n```toml\n[services.web]\ncommand = \"npx next dev --turbopack --port 3000 --hostname 0.0.0.0\"\n```\n\n### `port`\n\nПорт, на котором сервис слушает. Используется для проверки работоспособности (health checking) и интеграции проброса портов. Если указан, должен быть ненулевым.\n\n```toml\n[services.web]\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\n```\n\n### `restart`\n\nПолитика перезапуска, если процесс завершился. По умолчанию `\"no\"`.\n\n- `\"no\"` — не перезапускать\n- `\"on-failure\"` — перезапускать только если процесс завершился с ненулевым кодом\n- `\"always\"` — всегда перезапускать\n\n```toml\n[services.web]\ncommand = \"node server.js\"\nport = 3000\nrestart = \"on-failure\"\n```\n\n### `install`\n\nКоманды, которые нужно выполнить перед запуском сервиса (например, установка зависимостей). Принимает либо одну строку, либо массив строк.\n\n```toml\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\n```\n\n```toml\n[services.web]\ninstall = [\"npm install\", \"npm run build\"]\ncommand = \"npm start\"\nport = 3000\n```\n\n## Взаимоисключение с compose\n\nCoastfile не может определять одновременно `compose` и `[services]`. Если у вас есть поле `compose` в `[coast]`, добавление любого раздела `[services.*]` является ошибкой. Выберите один подход для каждого Coastfile.\n\nЕсли вам нужно, чтобы часть сервисов была контейнеризована через compose, а часть запускалась как bare, используйте compose для всех — см. [рекомендации по миграции в Bare Services](../concepts_and_terminology/BARE_SERVICES.md) о том, как перейти от bare-сервисов к compose.\n\n## Примеры\n\n### Односервисное приложение Next.js\n\n```toml\n[coast]\nname = \"my-frontend\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --turbopack --port 3002 --hostname 0.0.0.0\"\nport = 3002\nrestart = \"on-failure\"\n\n[ports]\nweb = 3002\n```\n\n### Веб-сервер с фоновым воркером\n\n```toml\n[coast]\nname = \"my-app\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"node server.js\"\nport = 3000\nrestart = \"on-failure\"\n\n[services.worker]\ncommand = \"node worker.js\"\nrestart = \"always\"\n\n[ports]\nweb = 3000\n```\n\n### Python-сервис с многошаговой установкой\n\n```toml\n[coast]\nname = \"ml-service\"\n\n[coast.setup]\npackages = [\"python3\", \"py3-pip\"]\n\n[services.api]\ninstall = [\"pip install -r requirements.txt\", \"python manage.py migrate\"]\ncommand = \"python manage.py runserver 0.0.0.0:8000\"\nport = 8000\nrestart = \"on-failure\"\n\n[ports]\napi = 8000\n```\n", "coastfiles/SHARED_SERVICES.md": "# Общие сервисы\n\nРазделы `[shared_services.*]` определяют инфраструктурные сервисы — базы данных, кэши, брокеры сообщений — которые запускаются на хостовом демоне Docker, а не внутри отдельных контейнеров Coast. Несколько экземпляров Coast подключаются к одному и тому же общему сервису через bridge-сеть.\n\nО том, как общие сервисы работают во время выполнения, об управлении жизненным циклом и об устранении неполадок см. [Shared Services](../concepts_and_terminology/SHARED_SERVICES.md).\n\n## Определение общего сервиса\n\nКаждый общий сервис — это именованный TOML-раздел под `[shared_services]`. Поле `image` обязательно; всё остальное — опционально.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\n```\n\n### `image` (обязательно)\n\nDocker-образ, который нужно запускать на хостовом демоне.\n\n### `ports`\n\nСписок портов, которые сервис открывает. Coast принимает либо просто порты контейнера, либо сопоставления в стиле Docker Compose `\"HOST:CONTAINER\"`.\n\n```toml\n[shared_services.redis]\nimage = \"redis:7-alpine\"\nports = [6379]\n```\n\n```toml\n[shared_services.postgis]\nimage = \"ghcr.io/baosystems/postgis:12-3.3\"\nports = [\"5433:5432\"]\n```\n\n- Простое целое число, например `6379`, является сокращением для `\"6379:6379\"`.\n- Строка сопоставления, например `\"5433:5432\"`, публикует общий сервис на порту хоста `5433`, сохраняя при этом доступ к нему внутри Coast по адресу `service-name:5432`.\n- И порт хоста, и порт контейнера должны быть ненулевыми.\n\n### `volumes`\n\nСтроки привязки (bind) Docker-томов для сохранения данных. Это Docker-тома на уровне хоста, а не тома, управляемые Coast.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\n```\n\n### `env`\n\nПеременные окружения, передаваемые контейнеру сервиса.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\", POSTGRES_DB = \"mydb\" }\n```\n\n### `auto_create_db`\n\nЕсли `true`, Coast автоматически создаёт отдельную базу данных внутри общего сервиса для каждого экземпляра Coast. По умолчанию `false`.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\nauto_create_db = true\n```\n\n### `inject`\n\nВнедряет информацию о подключении к общему сервису в экземпляры Coast в виде переменной окружения или файла. Использует тот же формат `env:NAME` или `file:/path`, что и [secrets](SECRETS.md).\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\ninject = \"env:DATABASE_URL\"\n```\n\n## Жизненный цикл\n\nОбщие сервисы запускаются автоматически, когда запускается первый экземпляр Coast, который на них ссылается. Они продолжают работать после `coast stop` и `coast rm` — удаление экземпляра не влияет на данные общего сервиса. Только `coast shared rm` останавливает и удаляет общий сервис.\n\nБазы данных для отдельных экземпляров, созданные через `auto_create_db`, также сохраняются после удаления экземпляра. Используйте `coast shared-services rm`, чтобы удалить сервис и его данные целиком.\n\n## Когда использовать общие сервисы vs тома\n\nИспользуйте общие сервисы, когда нескольким экземплярам Coast нужно подключаться к одному и тому же серверу базы данных (например, общий Postgres, где каждый экземпляр получает свою собственную базу данных). Используйте [стратегии томов](VOLUMES.md), когда вы хотите управлять тем, как данные compose-внутреннего сервиса разделяются или изолируются.\n\n## Примеры\n\n### Postgres, Redis и MongoDB\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\", POSTGRES_MULTIPLE_DATABASES = \"dev_db,test_db\" }\n\n[shared_services.redis]\nimage = \"redis:7\"\nports = [6379]\nvolumes = [\"infra_redis_data:/data\"]\n\n[shared_services.mongodb]\nimage = \"mongo:latest\"\nports = [27017]\nvolumes = [\"infra_mongodb_data:/data/db\"]\nenv = { MONGO_INITDB_ROOT_USERNAME = \"myapp\", MONGO_INITDB_ROOT_PASSWORD = \"myapp_pass\" }\n```\n\n### Минимальный общий Postgres\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16-alpine\"\nports = [5432]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\", POSTGRES_DB = \"coast_demo\" }\n```\n\n### Общий Postgres с сопоставлением host/container\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16-alpine\"\nports = [\"5433:5432\"]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\", POSTGRES_DB = \"coast_demo\" }\n```\n\n### Общие сервисы с автоматически создаваемыми базами данных\n\n```toml\n[shared_services.db]\nimage = \"postgres:16-alpine\"\nports = [5432]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\" }\nauto_create_db = true\n```\n", "coastfiles/VOLUMES.md": "# Томa\n\nРазделы `[volumes.*]` управляют тем, как именованные Docker-тома обрабатываются между экземплярами Coast. Каждый том настраивается со стратегией, которая определяет, будут ли экземпляры совместно использовать данные или получат собственную независимую копию.\n\nЧтобы увидеть общую картину изоляции данных в Coast — включая общие сервисы как альтернативу — см. [Volumes](../concepts_and_terminology/VOLUMES.md).\n\n## Определение тома\n\nКаждый том — это именованный раздел TOML внутри `[volumes]`. Требуются три поля:\n\n- **`strategy`** — `\"isolated\"` или `\"shared\"`\n- **`service`** — имя compose-сервиса, который использует этот том\n- **`mount`** — путь монтирования тома внутри контейнера\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## Стратегии\n\n### `isolated`\n\nКаждый экземпляр Coast получает свой собственный независимый том. Данные не разделяются между экземплярами. Томa создаются при `coast run` и удаляются при `coast rm`.\n\n```toml\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n```\n\nЭто правильный выбор для большинства томов баз данных — каждый экземпляр получает «чистый лист» и может свободно изменять данные, не влияя на другие экземпляры.\n\n### `shared`\n\nВсе экземпляры Coast используют один общий Docker-том. Любые данные, записанные одним экземпляром, видны всем остальным.\n\n```toml\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n```\n\nОбщие томa никогда не удаляются командой `coast rm`. Они сохраняются, пока вы не удалите их вручную.\n\nCoast выводит предупреждение на этапе сборки, если вы используете `shared` для тома, подключённого к сервису типа базы данных. Совместное использование одного тома базы данных несколькими параллельными экземплярами может привести к повреждению данных. Если вам нужны общие базы данных, используйте вместо этого [shared services](SHARED_SERVICES.md).\n\nХорошие варианты использования общих томов: кэши зависимостей (Go modules, npm cache, pip cache), кэши артефактов сборки и другие данные, где параллельные записи безопасны или маловероятны.\n\n## Наполнение из снапшота\n\nИзолированные томa можно заполнить данными из существующего Docker-тома во время создания экземпляра с помощью `snapshot_source`. Данные исходного тома копируются в новый изолированный том, который затем независимо расходится.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n`snapshot_source` допустим только при `strategy = \"isolated\"`. Указание его для общего тома является ошибкой.\n\nЭто полезно, когда вы хотите, чтобы каждый экземпляр Coast начинал с реалистичного набора данных, скопированного из вашей хостовой базы данных разработки, но при этом вы хотите, чтобы экземпляры могли свободно изменять эти данные, не влияя на источник или друг на друга.\n\n## Примеры\n\n### Изолированные базы данных, общий кэш зависимостей\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n```\n\n### Полный стек с наполнением из снапшота\n\nКаждый экземпляр начинает с копии существующих томов баз данных вашего хоста, а затем независимо расходится.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_mongodb_data\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n\n### Запуск тестов с чистыми базами данных для каждого экземпляра\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"test-redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n", - "coastfiles/WORKTREE_DIR.md": "# Директории worktree\n\nПоле `worktree_dir` в `[coast]` управляет тем, где размещаются git worktree. Coast использует git worktree, чтобы дать каждому инстансу собственную копию кодовой базы на другой ветке без дублирования всего репозитория.\n\n## Синтаксис\n\n`worktree_dir` принимает одну строку или массив строк:\n\n```toml\n# Single directory (default)\nworktree_dir = \".worktrees\"\n\n# Multiple directories\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\nЕсли поле не указано, по умолчанию используется `\".worktrees\"`.\n\n## Типы путей\n\n### Относительные пути\n\nПути, которые не начинаются с `~/` или `/`, разрешаются относительно корня проекта. Это наиболее распространённый вариант, и он не требует специальной обработки — такие пути находятся внутри директории проекта и автоматически доступны внутри контейнера Coast через стандартный bind mount `/host-project`.\n\n```toml\nworktree_dir = \".worktrees\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Пути с тильдой (внешние)\n\nПути, начинающиеся с `~/`, разворачиваются в домашнюю директорию пользователя и рассматриваются как **внешние** директории worktree. Coast добавляет отдельный bind mount, чтобы контейнер мог получить к ним доступ.\n\n```toml\nworktree_dir = [\"~/.codex/worktrees\", \".worktrees\"]\n```\n\nТак выполняется интеграция с инструментами, которые создают worktree вне корня вашего проекта, например OpenAI Codex (который всегда создаёт worktree в `$CODEX_HOME/worktrees`).\n\n### Абсолютные пути (внешние)\n\nПути, начинающиеся с `/`, также считаются внешними и получают собственный bind mount.\n\n```toml\nworktree_dir = [\"/shared/worktrees\", \".worktrees\"]\n```\n\n## Как работают внешние директории\n\nКогда Coast обнаруживает внешнюю директорию worktree (путь с тильдой или абсолютный путь), происходят три вещи:\n\n1. **Bind mount контейнера** — Во время создания контейнера (`coast run`) разрешённый путь на хосте монтируется в контейнер как bind mount в `/host-external-wt/{index}`, где `{index}` — это позиция в массиве `worktree_dir`. Это делает внешние файлы доступными внутри контейнера.\n\n2. **Фильтрация по проекту** — Внешние директории могут содержать worktree для нескольких проектов. Coast использует `git worktree list --porcelain` (которая по своей природе ограничена текущим репозиторием), чтобы обнаружить только те worktree, которые принадлежат этому проекту. Git watcher также проверяет принадлежность, читая файл `.git` каждого worktree и проверяя, что его указатель `gitdir:` разрешается обратно в текущий репозиторий.\n\n3. **Перемонтирование workspace** — Когда вы выполняете `coast assign` к внешнему worktree, Coast перемонтирует `/workspace` из пути внешнего bind mount вместо обычного `/host-project/{dir}/{name}`.\n\n## Именование внешних worktree\n\nВнешние worktree с checkout веткой отображаются по имени своей ветки, так же как и локальные worktree.\n\nВнешние worktree в состоянии **detached HEAD** (обычно это встречается у Codex) отображаются с использованием их относительного пути внутри внешней директории. Например, worktree Codex по адресу `~/.codex/worktrees/a0db/coastguard-platform` отображается как `a0db/coastguard-platform` в UI и CLI.\n\n## `default_worktree_dir`\n\nУправляет тем, какая директория используется, когда Coast создаёт **новый** worktree (например, когда вы назначаете ветку, у которой ещё нет существующего worktree). По умолчанию используется первая запись в `worktree_dir`.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\ndefault_worktree_dir = \".worktrees\"\n```\n\nВнешние директории никогда не используются для создания новых worktree — Coast всегда создаёт worktree в локальной (относительной) директории. Поле `default_worktree_dir` нужно только в том случае, если вы хотите переопределить значение по умолчанию (первую запись).\n\n## Примеры\n\n### Интеграция с Codex\n\nOpenAI Codex создаёт worktree по адресу `~/.codex/worktrees/{hash}/{project-name}`. Чтобы они были видимы и доступны для назначения в Coast:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nПосле этого worktree Codex появятся в модальном окне checkout и в выводе `coast ls`. Вы можете назначить инстанс Coast на worktree Codex, чтобы запускать его код в полноценной среде разработки.\n\nПримечание: после добавления внешней директории контейнер необходимо пересоздать (`coast run`), чтобы bind mount вступил в силу. Простого перезапуска существующего инстанса недостаточно.\n\n### Интеграция с Claude Code\n\nClaude Code создаёт worktree внутри проекта в `.claude/worktrees/`. Поскольку это относительный путь (внутри корня проекта), он работает как любая другая локальная директория worktree — внешний mount не требуется:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Все три вместе\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\n## Живое чтение Coastfile\n\nИзменения `worktree_dir` в вашем Coastfile вступают в силу немедленно для **списка** worktree (API и git watcher читают актуальный Coastfile с диска, а не только кэшированный артефакт сборки). Однако внешние **bind mount** создаются только во время создания контейнера, поэтому для того, чтобы новая внешняя директория стала доступной для монтирования, необходимо пересоздать инстанс.\n", + "coastfiles/WORKTREE_DIR.md": "# Директории worktree\n\nПоле `worktree_dir` в `[coast]` управляет тем, где размещаются git worktree. Coast использует git worktree, чтобы дать каждому инстансу собственную копию кодовой базы на другой ветке без дублирования всего репозитория.\n\n## Синтаксис\n\n`worktree_dir` принимает одну строку или массив строк:\n\n```toml\n# Single directory (default)\nworktree_dir = \".worktrees\"\n\n# Multiple directories\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\nЕсли поле не указано, по умолчанию используется `\".worktrees\"`.\n\n## Типы путей\n\n### Относительные пути\n\nПути, которые не начинаются с `~/` или `/`, разрешаются относительно корня проекта. Это наиболее распространённый вариант, и он не требует специальной обработки — такие пути находятся внутри директории проекта и автоматически доступны внутри контейнера Coast через стандартный bind mount `/host-project`.\n\n```toml\nworktree_dir = \".worktrees\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Пути с тильдой (внешние)\n\nПути, начинающиеся с `~/`, разворачиваются в домашнюю директорию пользователя и рассматриваются как **внешние** директории worktree. Coast добавляет отдельный bind mount, чтобы контейнер мог получить к ним доступ.\n\n```toml\nworktree_dir = [\"~/.codex/worktrees\", \".worktrees\"]\n```\n\nТак выполняется интеграция с инструментами, которые создают worktree вне корня вашего проекта, например OpenAI Codex (который всегда создаёт worktree в `$CODEX_HOME/worktrees`).\n\n### Абсолютные пути (внешние)\n\nПути, начинающиеся с `/`, также считаются внешними и получают собственный bind mount.\n\n```toml\nworktree_dir = [\"/shared/worktrees\", \".worktrees\"]\n```\n\n### Шаблоны glob (внешние)\n\nВнешние пути могут содержать метасимволы glob (`*`, `?`, `[...]`). Coast разворачивает их во время выполнения по файловой системе хоста, создавая bind mount для каждой совпавшей директории.\n\n```toml\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\nЭто полезно, когда инструмент создаёт worktree по пути с компонентом, который различается для каждого проекта (например, хешем). `*` соответствует любому одному имени директории, поэтому `~/.shep/repos/*/wt` соответствует `~/.shep/repos/a21f0cda9ab9d456/wt` и любой другой директории с хешем, содержащей поддиректорию `wt`.\n\nПоддерживаемый синтаксис glob:\n\n- `*` — соответствует любой последовательности символов в пределах одного компонента пути\n- `?` — соответствует любому одному символу\n- `[abc]` — соответствует любому символу из набора\n- `[!abc]` — соответствует любому символу, не входящему в набор\n\nРазворачивание glob происходит везде, где разрешаются директории worktree: при создании контейнера, assign, start, lookup и в git watcher. Совпадения сортируются для детерминированного порядка. Если glob не совпадает ни с одной директорией, он молча пропускается.\n\nКак и для других внешних путей, после добавления шаблона glob контейнер нужно пересоздать (`coast run`), чтобы bind mount вступил в силу.\n\n## Как работают внешние директории\n\nКогда Coast обнаруживает внешнюю директорию worktree (путь с тильдой или абсолютный путь), происходят три вещи:\n\n1. **Bind mount контейнера** — Во время создания контейнера (`coast run`) разрешённый путь на хосте монтируется в контейнер как bind mount в `/host-external-wt/{index}`, где `{index}` — это позиция в массиве `worktree_dir`. Это делает внешние файлы доступными внутри контейнера.\n\n2. **Фильтрация по проекту** — Внешние директории могут содержать worktree для нескольких проектов. Coast использует `git worktree list --porcelain` (которая по своей природе ограничена текущим репозиторием), чтобы обнаружить только те worktree, которые принадлежат этому проекту. Git watcher также проверяет принадлежность, читая файл `.git` каждого worktree и проверяя, что его указатель `gitdir:` разрешается обратно в текущий репозиторий.\n\n3. **Перемонтирование workspace** — Когда вы выполняете `coast assign` к внешнему worktree, Coast перемонтирует `/workspace` из пути внешнего bind mount вместо обычного `/host-project/{dir}/{name}`.\n\n## Именование внешних worktree\n\nВнешние worktree с checkout веткой отображаются по имени своей ветки, так же как и локальные worktree.\n\nВнешние worktree в состоянии **detached HEAD** (обычно это встречается у Codex) отображаются с использованием их относительного пути внутри внешней директории. Например, worktree Codex по адресу `~/.codex/worktrees/a0db/coastguard-platform` отображается как `a0db/coastguard-platform` в UI и CLI.\n\n## `default_worktree_dir`\n\nУправляет тем, какая директория используется, когда Coast создаёт **новый** worktree (например, когда вы назначаете ветку, у которой ещё нет существующего worktree). По умолчанию используется первая запись в `worktree_dir`.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\ndefault_worktree_dir = \".worktrees\"\n```\n\nВнешние директории никогда не используются для создания новых worktree — Coast всегда создаёт worktree в локальной (относительной) директории. Поле `default_worktree_dir` нужно только в том случае, если вы хотите переопределить значение по умолчанию (первую запись).\n\n## Примеры\n\n### Интеграция с Codex\n\nOpenAI Codex создаёт worktree по адресу `~/.codex/worktrees/{hash}/{project-name}`. Чтобы они были видимы и доступны для назначения в Coast:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nПосле этого worktree Codex появятся в модальном окне checkout и в выводе `coast ls`. Вы можете назначить инстанс Coast на worktree Codex, чтобы запускать его код в полноценной среде разработки.\n\nПримечание: после добавления внешней директории контейнер необходимо пересоздать (`coast run`), чтобы bind mount вступил в силу. Простого перезапуска существующего инстанса недостаточно.\n\n### Интеграция с Claude Code\n\nClaude Code создаёт worktree внутри проекта в `.claude/worktrees/`. Поскольку это относительный путь (внутри корня проекта), он работает как любая другая локальная директория worktree — внешний mount не требуется:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Интеграция с Shep\n\nShep создаёт worktree по адресу `~/.shep/repos/{hash}/wt/{branch-slug}`, где хеш уникален для каждого репозитория. Используйте шаблон glob, чтобы сопоставить директорию с хешем:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n### Все harness вместе\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n## Живое чтение Coastfile\n\nИзменения `worktree_dir` в вашем Coastfile вступают в силу немедленно для **списка** worktree (API и git watcher читают актуальный Coastfile с диска, а не только кэшированный артефакт сборки). Однако внешние **bind mount** создаются только во время создания контейнера, поэтому для того, чтобы новая внешняя директория стала доступной для монтирования, необходимо пересоздать инстанс.\n", "concepts_and_terminology/README.md": "# Концепции и терминология\n\nЭтот раздел охватывает ключевые концепции и словарь, используемые во всём Coasts. Если вы новичок в Coasts, начните здесь, прежде чем переходить к конфигурации или расширенному использованию.\n\n- [Coasts](COASTS.md) — самодостаточные рантаймы вашего проекта, каждый со своими портами, томами и назначением worktree.\n- [Run](RUN.md) — создание нового экземпляра Coast из последней сборки с возможностью назначения worktree.\n- [Remove](REMOVE.md) — удаление экземпляра Coast и его изолированного состояния рантайма, когда нужно чистое пересоздание или если вы хотите остановить Coasts.\n- [Filesystem](FILESYSTEM.md) — общая точка монтирования между хостом и Coast, хостовые агенты и переключение worktree.\n- [Coast Daemon](DAEMON.md) — локальная control plane `coastd`, выполняющая операции жизненного цикла.\n- [Coast CLI](CLI.md) — терминальный интерфейс для команд, скриптов и рабочих процессов агентов.\n- [Coastguard](COASTGUARD.md) — веб-интерфейс, запускаемый с помощью `coast ui`, для наблюдаемости и управления.\n- [Ports](PORTS.md) — канонические порты vs динамические порты и как checkout переключает между ними.\n- [Primary Port & DNS](PRIMARY_PORT_AND_DNS.md) — быстрые ссылки на ваш основной сервис, маршрутизация по поддоменам для изоляции cookie и шаблоны URL.\n- [Assign and Unassign](ASSIGN.md) — переключение Coast между worktree и доступные стратегии назначения.\n- [Checkout](CHECKOUT.md) — сопоставление канонических портов с экземпляром Coast и когда это нужно.\n- [Lookup](LOOKUP.md) — определение того, какие экземпляры Coast соответствуют текущему worktree агента.\n- [Volume Topology](VOLUMES.md) — общие сервисы, общие тома, изолированные тома и создание снимков.\n- [Shared Services](SHARED_SERVICES.md) — управляемые хостом инфраструктурные сервисы и устранение неоднозначности томов.\n- [Secrets and Extractors](SECRETS.md) — извлечение секретов с хоста и внедрение их в контейнеры Coast.\n- [Builds](BUILDS.md) — анатомия сборки coast, где живут артефакты, автоочистка и типизированные сборки.\n- [Coastfile Types](COASTFILE_TYPES.md) — компонуемые варианты Coastfile с extends, unset, omit и autostart.\n- [Runtimes and Services](RUNTIMES_AND_SERVICES.md) — рантайм DinD, архитектура Docker-in-Docker и то, как сервисы работают внутри Coast.\n- [Bare Services](BARE_SERVICES.md) — запуск неконтейнеризованных процессов внутри Coast и почему вместо этого следует контейнеризовать.\n- [Logs](LOGS.md) — чтение логов сервисов изнутри Coast, компромисс MCP и просмотрщик логов Coastguard.\n- [Exec & Docker](EXEC_AND_DOCKER.md) — выполнение команд внутри Coast и взаимодействие с внутренним демоном Docker.\n- [Agent Shells](AGENT_SHELLS.md) — контейнеризованные TUI агентов, компромисс OAuth и почему, вероятно, лучше запускать агентов на хосте.\n- [MCP Servers](MCP_SERVERS.md) — настройка инструментов MCP внутри Coast для контейнеризованных агентов, внутренние серверы vs проксируемые через хост.\n- [Troubleshooting](TROUBLESHOOTING.md) — doctor, перезапуск демона, удаление проекта и вариант «ядерного» factory-reset.\n", "concepts_and_terminology/AGENT_SHELLS.md": "# Agent Shells\n\nАгентские оболочки — это оболочки внутри Coast, которые открываются напрямую в TUI-рантайм агента — Claude Code, Codex или любой CLI-агент. Вы настраиваете их через секцию `[agent_shell]` в вашем Coastfile, и Coast запускает процесс агента внутри DinD-контейнера.\n\n**Для большинства случаев использования вам не следует этого делать.** Вместо этого запускайте ваших кодинговых агентов на хост-машине. Общая [файловая система](FILESYSTEM.md) означает, что агент на стороне хоста может редактировать код как обычно, одновременно вызывая [`coast logs`](LOGS.md), [`coast exec`](EXEC_AND_DOCKER.md) и [`coast ps`](RUNTIMES_AND_SERVICES.md) для получения информации о рантайме. Агентские оболочки добавляют монтирование учетных данных, сложности с OAuth и усложнение жизненного цикла, которые вам не нужны, если только у вас нет конкретной причины контейнеризировать самого агента.\n\n## The OAuth Problem\n\nЕсли вы используете Claude Code, Codex или подобные инструменты, которые аутентифицируются через OAuth, токен был выдан для вашей хост-машины. Когда этот же токен используется внутри Linux-контейнера — другой user agent, другое окружение — провайдер может пометить его или отозвать. Вы будете получать периодические сбои аутентификации, которые трудно отлаживать.\n\nДля контейнеризованных агентов более безопасный выбор — аутентификация по API-ключу. Задайте ключ как [секрет](SECRETS.md) в вашем Coastfile и внедрите его в окружение контейнера.\n\nЕсли API-ключи недоступны, вы можете смонтировать OAuth-учетные данные в Coast (см. раздел Configuration ниже), но ожидайте трений. На macOS, если вы используете извлекатель секретов `keychain` для получения OAuth-токенов, каждый `coast build` будет запрашивать пароль вашей macOS Keychain. Это делает процесс сборки утомительным, особенно при частых пересборках. Запрос Keychain — требование безопасности macOS и его нельзя обойти.\n\n## Configuration\n\nДобавьте секцию `[agent_shell]` в ваш Coastfile с командой для запуска:\n\n```toml\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\nКоманда выполняется внутри DinD-контейнера в `/workspace`. Coast создает пользователя `coast` внутри контейнера, копирует учетные данные из `/root/.claude/` в `/home/coast/.claude/` и запускает команду от имени этого пользователя. Если вашему агенту нужны учетные данные, смонтированные в контейнер, используйте `[secrets]` с внедрением файла (см. [Secrets and Extractors](SECRETS.md)) и `[coast.setup]` для установки CLI агента:\n\n```toml\n[coast.setup]\nrun = [\"npm install -g @anthropic-ai/claude-code\"]\n\n[secrets.claude_credentials]\nextractor = \"keychain\"\nservice = \"Claude Code-credentials\"\ninject = \"file:/root/.claude/.credentials.json\"\n\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\nЕсли `[agent_shell]` настроен, Coast автоматически запускает оболочку при старте инстанса. Конфигурация наследуется через `extends` и может быть переопределена для каждого [типа Coastfile](COASTFILE_TYPES.md).\n\n## The Active Agent Model\n\nКаждый инстанс Coast может иметь несколько агентских оболочек, но только одна из них **активна** в любой момент времени. Активная оболочка — это цель по умолчанию для команд, которые не указывают ID `--shell`.\n\n```bash\ncoast agent-shell dev-1 ls\n\n SHELL STATUS ACTIVE\n 1 running ★\n 2 running\n```\n\nПереключить активную оболочку:\n\n```bash\ncoast agent-shell dev-1 activate 2\n```\n\nВы не можете закрыть активную оболочку — сначала активируйте другую. Это предотвращает случайное завершение оболочки, с которой вы взаимодействуете.\n\nВ Coastguard агентские оболочки отображаются как вкладки в панели Exec с метками active/inactive. Нажмите на вкладку, чтобы увидеть ее терминал; используйте выпадающее меню, чтобы активировать, запустить или закрыть оболочки.\n\n![Agent shell in Coastguard](../../assets/coastguard-agent-shell.png)\n*Агентская оболочка, запускающая Claude Code внутри инстанса Coast, доступная из вкладки Exec в Coastguard.*\n\n## Sending Input\n\nОсновной способ программно управлять контейнеризованным агентом — `coast agent-shell input`:\n\n```bash\ncoast agent-shell dev-1 input \"fix the failing test in auth.test.ts\"\n```\n\nЭто записывает текст в TUI активного агента и нажимает Enter. Агент получает его так, как если бы вы набрали его в терминале.\n\nОпции:\n\n- `--no-send` — записать текст без нажатия Enter. Полезно для набора частичного ввода или навигации по меню TUI.\n- `--shell ` — нацелиться на конкретную оболочку вместо активной.\n- `--show-bytes` — вывести точные отправляемые байты для отладки.\n\nВнутри, ввод записывается напрямую в файловый дескриптор master PTY. Текст и нажатие Enter отправляются двумя отдельными операциями записи с разрывом 25 мс, чтобы избежать артефактов paste-mode, которые некоторые TUI-фреймворки проявляют при получении быстрого ввода.\n\n## Other Commands\n\n```bash\ncoast agent-shell dev-1 spawn # create a new shell\ncoast agent-shell dev-1 spawn --activate # create and immediately activate\ncoast agent-shell dev-1 tty # attach interactive TTY to active shell\ncoast agent-shell dev-1 tty --shell 2 # attach to a specific shell\ncoast agent-shell dev-1 read-output # read full scrollback buffer\ncoast agent-shell dev-1 read-last-lines 50 # read last 50 lines of output\ncoast agent-shell dev-1 session-status # check if the shell process is alive\n```\n\n`tty` дает вам живую интерактивную сессию — вы можете печатать прямо в TUI агента. Отсоединяйтесь стандартной escape-последовательностью терминала. `read-output` и `read-last-lines` неинтерактивны и возвращают текст, что полезно для скриптинга и автоматизации.\n\n## Lifecycle and Recovery\n\nСессии агентских оболочек сохраняются в Coastguard при навигации по страницам. Буфер прокрутки (до 512KB) воспроизводится при повторном подключении к вкладке.\n\nКогда вы останавливаете инстанс Coast командой `coast stop`, все PTY-процессы агентских оболочек завершаются, а их записи в базе данных очищаются. `coast start` автоматически запускает свежую агентскую оболочку, если настроен `[agent_shell]`.\n\nПосле перезапуска демона ранее запущенные агентские оболочки будут отображаться как мертвые. Система обнаруживает это автоматически — если активная оболочка мертва, первая живая оболочка повышается до активной. Если ни одна оболочка не жива, запустите новую с помощью `coast agent-shell spawn --activate`.\n\n## Who This Is For\n\nАгентские оболочки предназначены для **продуктов, создающих first-party интеграции** вокруг Coasts — платформ оркестрации, оберток для агентов и инструментов, которые хотят программно управлять контейнеризованными кодинговыми агентами через API `input`, `read-output` и `session-status`.\n\nДля общего параллельного написания кода агентами запускайте агентов на хосте. Это проще, избегает проблем с OAuth, обходится без сложности монтирования учетных данных и полностью использует общую файловую систему. Вы получаете все преимущества Coast (изолированные рантаймы, управление портами, переключение worktree) без каких-либо накладных расходов контейнеризации агента.\n\nСледующий уровень сложности после агентских оболочек — монтирование [MCP servers](MCP_SERVERS.md) в Coast, чтобы контейнеризованный агент имел доступ к инструментам. Это еще сильнее расширяет поверхность интеграции и рассматривается отдельно. Возможность есть, если она вам нужна, но большинству пользователей не следует этого делать.\n", "concepts_and_terminology/ASSIGN.md": "# Назначение и снятие назначения\n\nНазначение и снятие назначения управляют тем, на какое рабочее дерево (worktree) указывает экземпляр Coast. См. [Filesystem](FILESYSTEM.md), чтобы понять, как переключение worktree работает на уровне монтирования.\n\n## Назначение\n\n`coast assign` переключает экземпляр Coast на конкретное worktree. Coast создаёт worktree, если его ещё не существует, обновляет код внутри Coast и перезапускает сервисы согласно настроенной стратегии назначения (assign).\n\n```bash\ncoast assign dev-1 --worktree feature/oauth\n```\n\n```text\nBefore:\n┌─── dev-1 ──────────────────┐\n│ branch: main │\n│ worktree: - │\n└────────────────────────────┘\n\ncoast assign dev-1 --worktree feature/oauth\n\nAfter:\n┌─── dev-1 ──────────────────┐\n│ branch: feature/oauth │\n│ worktree: feature/oauth │\n│ │\n│ postgres → skipped (none) │\n│ web → hot swapped │\n│ api → restarted │\n│ worker → rebuilt │\n└────────────────────────────┘\n```\n\nПосле назначения `dev-1` работает на ветке `feature/oauth` со всеми поднятыми сервисами.\n\n## Снятие назначения\n\n`coast unassign` переключает экземпляр Coast обратно на корень проекта (ваша ветка main/master). Привязка к worktree удаляется, и Coast возвращается к запуску от основного репозитория.\n\n```text\ncoast unassign dev-1\n\n┌─── dev-1 ──────────────────┐\n│ branch: main │\n│ worktree: - │\n└────────────────────────────┘\n```\n\n## Стратегии назначения\n\nКогда Coast назначается на новое worktree, каждому сервису нужно знать, как обработать изменение кода. Это настраивается для каждого сервиса в вашем [Coastfile](COASTFILE_TYPES.md) в разделе `[assign]`:\n\n```toml\n[assign]\ndefault = \"restart\"\n\n[assign.services]\npostgres = \"none\"\nredis = \"none\"\nweb = \"hot\"\nworker = \"rebuild\"\n```\n\n```text\ncoast assign dev-1 --worktree feature/billing\n\n postgres (strategy: none) → skipped, unchanged between branches\n redis (strategy: none) → skipped, unchanged between branches\n web (strategy: hot) → filesystem swapped, file watcher picks it up\n api (strategy: restart) → container restarted\n worker (strategy: rebuild) → image rebuilt, container restarted\n```\n\nДоступные стратегии:\n\n- **none** — ничего не делать. Используйте это для сервисов, которые не меняются между ветками, например Postgres или Redis.\n- **hot** — заменить только файловую систему. Сервис остаётся запущенным и подхватывает изменения через распространение монтирования (mount propagation) и файловые наблюдатели (например, dev-сервер с hot reload).\n- **restart** — перезапустить контейнер сервиса. Используйте это для интерпретируемых сервисов, которым достаточно перезапуска процесса. Это значение по умолчанию.\n- **rebuild** — пересобрать образ сервиса и перезапустить. Используйте это, когда смена ветки затрагивает `Dockerfile` или зависимости времени сборки.\n\nТакже можно указать триггеры пересборки, чтобы сервис пересобирался только при изменении определённых файлов:\n\n```toml\n[assign.rebuild_triggers]\nworker = [\"Dockerfile\", \"package.json\"]\n```\n\nЕсли ни один из триггерных файлов не изменился между ветками, сервис пропускает пересборку, даже если стратегия установлена в `rebuild`.\n\n## Удалённые worktree\n\nЕсли назначенное worktree удалено, демон `coastd` автоматически снимает назначение этого экземпляра обратно на корень основного Git-репозитория.\n\n---\n\n> **Совет: снижение задержки назначения в больших кодовых базах**\n>\n> Внутри, первое назначение на новое worktree подготавливает (bootstrap) выбранные файлы, игнорируемые git, в это worktree, а сервисы с `[assign.rebuild_triggers]` могут запускать `git diff --name-only`, чтобы решить, нужна ли пересборка. В больших кодовых базах этот шаг bootstrap и ненужные пересборки обычно доминируют по времени назначения.\n>\n> Используйте `exclude_paths` в вашем Coastfile, чтобы уменьшить поверхность bootstrap для игнорируемых git файлов, используйте `\"hot\"` для сервисов с файловыми наблюдателями и держите `[assign.rebuild_triggers]` сфокусированными на настоящих входных данных времени сборки. Если вам нужно вручную обновить bootstrap игнорируемых файлов для существующего worktree, выполните `coast assign --force-sync`. Полное руководство см. в [Performance Optimizations](PERFORMANCE_OPTIMIZATIONS.md).\n", "concepts_and_terminology/BARE_SERVICES.md": "# Bare Services\n\nЕсли вы можете контейнеризировать свой проект, вам следует это сделать. Bare-сервисы существуют для проектов, которые ещё не были контейнеризированы и где добавление `Dockerfile` и `docker-compose.yml` в краткосрочной перспективе непрактично. Это ступень, а не конечная точка.\n\nВместо `docker-compose.yml`, который оркестрирует контейнеризированные сервисы, bare-сервисы позволяют вам определять shell-команды в вашем Coastfile, и Coast запускает их как обычные процессы с лёгким супервизором внутри контейнера Coast.\n\n## Why Containerize Instead\n\nСервисы [Docker Compose](RUNTIMES_AND_SERVICES.md) дают вам:\n\n- Воспроизводимые сборки через Dockerfile’ы\n- Health check’и, которых Coast может дождаться при запуске\n- Изоляцию процессов между сервисами\n- Управление томами и сетью, выполняемое Docker\n- Переносимое определение, работающее в CI, staging и production\n\nBare-сервисы не дают ничего из этого. Ваши процессы разделяют одну и ту же файловую систему, восстановление после падения — это shell-цикл, и «работает у меня на машине» столь же вероятно внутри Coast, как и вне его. Если у вашего проекта уже есть `docker-compose.yml`, используйте его.\n\n## When Bare Services Make Sense\n\n- Вы внедряете Coast в проект, который никогда не был контейнеризирован, и хотите сразу начать получать пользу от изоляции worktree и управления портами\n- Ваш проект — это однопроцессный инструмент или CLI, для которого Dockerfile был бы избыточен\n- Вы хотите итеративно контейнеризировать постепенно — начать с bare-сервисов, а позже перейти на compose\n\n## Configuration\n\nBare-сервисы определяются секциями `[services.]` в вашем Coastfile. Coastfile может определять bare-сервисы отдельно или вместе с `compose` — для второго случая см. [Mixed Service Types](MIXED_SERVICE_TYPES.md).\n\n```toml\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\nrestart = \"on-failure\"\n\n[services.worker]\ncommand = \"node worker.js\"\nrestart = \"always\"\n\n[ports]\nweb = 3000\n```\n\nУ каждого сервиса есть четыре поля:\n\n| Field | Required | Description |\n|---|---|---|\n| `command` | yes | Shell-команда для запуска (например, `\"npm run dev\"`) |\n| `port` | no | Порт, на котором слушает сервис, используется для маппинга портов |\n| `restart` | no | Политика перезапуска: `\"no\"` (по умолчанию), `\"on-failure\"` или `\"always\"` |\n| `install` | no | Одна или несколько команд, которые нужно выполнить перед запуском (например, `\"npm install\"` или `[\"npm install\", \"npm run build\"]`) |\n\n### Setup Packages\n\nПоскольку bare-сервисы запускаются как обычные процессы, в контейнере Coast должны быть установлены правильные runtime’ы. Используйте `[coast.setup]`, чтобы объявить системные пакеты:\n\n```toml\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n```\n\nОни устанавливаются до запуска любого сервиса. Без этого ваши команды `npm` или `node` будут падать внутри контейнера.\n\n### Install Commands\n\nПоле `install` выполняется до запуска сервиса и повторно при каждом [`coast assign`](ASSIGN.md) (переключение ветки). Здесь устанавливаются зависимости:\n\n```toml\n[services.api]\ninstall = [\"pip install -r requirements.txt\", \"python manage.py migrate\"]\ncommand = \"python manage.py runserver 0.0.0.0:8000\"\nport = 8000\n```\n\nКоманды install выполняются последовательно. Если какая-либо команда install завершается с ошибкой, сервис не запускается.\n\n### Restart Policies\n\n- **`no`** — сервис запускается один раз. Если он завершается, он остаётся остановленным. Используйте это для одноразовых задач или сервисов, которыми вы хотите управлять вручную.\n- **`on-failure`** — перезапускает сервис, если он завершается с ненулевым кодом. Успешные завершения (код 0) не трогаются. Используется экспоненциальная задержка от 1 секунды до 30 секунд, и попытки прекращаются после 10 последовательных падений.\n- **`always`** — перезапускает при любом завершении, включая успешное. Та же задержка, что и у `on-failure`. Используйте это для долгоживущих серверов, которые не должны останавливаться.\n\nЕсли сервис работает более 30 секунд перед падением, счётчик повторов и задержка сбрасываются — предполагается, что какое-то время он был здоров, и падение является новой проблемой.\n\n## How It Works Under the Hood\n\n```text\n┌─── Coast: dev-1 ──────────────────────────────────────┐\n│ │\n│ /coast-supervisor/ │\n│ ├── web.sh (runs command, tracks PID) │\n│ ├── worker.sh │\n│ ├── start-all.sh (launches all services) │\n│ ├── stop-all.sh (SIGTERM via PID files) │\n│ └── ps.sh (checks PID liveness) │\n│ │\n│ /var/log/coast-services/ │\n│ ├── web.log │\n│ └── worker.log │\n│ │\n│ No inner Docker daemon images are used. │\n│ Processes run directly on the container OS. │\n└───────────────────────────────────────────────────────┘\n```\n\nCoast генерирует обёртки на shell-скриптах для каждого сервиса и помещает их в `/coast-supervisor/` внутри контейнера DinD. Каждая обёртка отслеживает свой PID, перенаправляет вывод в log-файл и реализует политику перезапуска как shell-цикл. Здесь нет Docker Compose, нет внутренних Docker-образов и нет изоляции уровня контейнеров между сервисами.\n\n`coast ps` проверяет живость PID, а не обращается к Docker, и `coast logs` «хвостит» log-файлы, а не вызывает `docker compose logs`. Формат вывода логов совпадает с форматом compose `service | line`, поэтому UI Coastguard работает без изменений.\n\n## Ports\n\nКонфигурация портов работает точно так же, как и в Coast на основе compose. Определите порты, на которых слушают ваши сервисы, в `[ports]`:\n\n```toml\n[services.web]\ncommand = \"npm start\"\nport = 3000\n\n[ports]\nweb = 3000\n```\n\n[Dynamic ports](PORTS.md) выделяются при `coast run`, а [`coast checkout`](CHECKOUT.md) меняет местами канонические порты как обычно. Единственное отличие в том, что между сервисами нет Docker-сети — все они биндятся напрямую на loopback контейнера или `0.0.0.0`.\n\n## Branch Switching\n\nКогда вы запускаете `coast assign` в Coast с bare-сервисами, происходит следующее:\n\n1. Все запущенные сервисы останавливаются через SIGTERM\n2. Worktree переключается на новую ветку\n3. Команды install выполняются снова (например, `npm install` подхватывает зависимости новой ветки)\n4. Все сервисы перезапускаются\n\nЭто эквивалентно тому, что происходит с compose — `docker compose down`, переключение ветки, rebuild, `docker compose up` — но с shell-процессами вместо контейнеров.\n\n## Limitations\n\n- **Нет health check’ов.** Coast не может дождаться, пока bare-сервис станет «здоровым», так же как он может это сделать для compose-сервиса, который определяет health check. Он запускает процесс и надеется на лучшее.\n- **Нет изоляции между сервисами.** Все процессы разделяют одну и ту же файловую систему и namespace процессов внутри контейнера Coast. Некорректно работающий сервис может повлиять на другие.\n- **Нет кеширования сборок.** Сборки Docker Compose кешируются слой за слоем. Команды bare-сервиса `install` выполняются с нуля при каждом assign.\n- **Восстановление после падений примитивное.** Политика перезапуска использует shell-цикл с экспоненциальной задержкой. Это не супервизор процессов вроде systemd или supervisord.\n- **Нет `[omit]` или `[unset]` для сервисов.** Композиция типов Coastfile работает с compose-сервисами, но bare-сервисы не поддерживают исключение отдельных сервисов через типизированные Coastfile.\n\n## Migrating to Compose\n\nКогда вы будете готовы контейнеризировать, путь миграции прямолинеен:\n\n1. Напишите `Dockerfile` для каждого сервиса\n2. Создайте `docker-compose.yml`, который ссылается на них\n3. Замените секции `[services.*]` в вашем Coastfile на поле `compose`, указывающее на ваш compose-файл\n4. Удалите пакеты `[coast.setup]`, которые теперь обрабатываются вашими Dockerfile’ами\n5. Пересоберите с помощью [`coast build`](BUILDS.md)\n\nВаши маппинги портов, конфигурация [volumes](VOLUMES.md), [shared services](SHARED_SERVICES.md) и [secrets](SECRETS.md) полностью переносятся без изменений. Меняется только то, как именно запускаются сами сервисы.\n", "concepts_and_terminology/BUILDS.md": "# Сборки\n\nДумайте о сборке coast как об образе Docker с дополнительной поддержкой. Сборка — это артефакт на основе директории, который объединяет всё необходимое для создания экземпляров Coast: разрешённый [Coastfile](COASTFILE_TYPES.md), переписанный compose-файл, заранее скачанные OCI tarball-архивы образов и внедрённые файлы хоста. Это не сам образ Docker, но он содержит образы Docker (в виде tarball-архивов) плюс метаданные, которые нужны Coast, чтобы связать их вместе.\n\n## Что делает `coast build`\n\nКогда вы запускаете `coast build`, демон выполняет следующие шаги по порядку:\n\n1. Разбирает и проверяет Coastfile.\n2. Читает compose-файл и отфильтровывает исключённые сервисы.\n3. Извлекает [secrets](SECRETS.md) из настроенных extractors и сохраняет их в зашифрованном виде в keystore.\n4. Собирает Docker-образы для compose-сервисов, у которых есть директивы `build:` (на хосте).\n5. Скачивает Docker-образы для compose-сервисов, у которых есть директивы `image:`.\n6. Кэширует все образы как OCI tarball-архивы в `~/.coast/image-cache/`.\n7. Если настроен `[coast.setup]`, собирает пользовательский базовый образ DinD с указанными пакетами, командами и файлами.\n8. Записывает директорию артефакта сборки с манифестом, разрешённым coastfile, переписанным compose-файлом и внедрёнными файлами.\n9. Обновляет символическую ссылку `latest`, чтобы она указывала на новую сборку.\n10. Автоматически очищает старые сборки сверх лимита хранения.\n\n## Где хранятся сборки\n\n```text\n~/.coast/\n images/\n my-project/\n latest -> a3c7d783_20260227143000 (symlink)\n a3c7d783_20260227143000/ (versioned build)\n manifest.json\n coastfile.toml\n compose.yml\n inject/\n b4d8e894_20260226120000/ (older build)\n ...\n image-cache/ (shared tarball cache)\n postgres_16_a1b2c3d4e5f6.tar\n redis_7_f6e5d4c3b2a1.tar\n coast-built_my-project_web_latest_...tar\n```\n\nКаждая сборка получает уникальный **ID сборки** в формате `{coastfile_hash}_{YYYYMMDDHHMMSS}`. Хэш учитывает содержимое Coastfile и разрешённую конфигурацию, поэтому изменения в Coastfile приводят к созданию нового ID сборки.\n\nСимволическая ссылка `latest` всегда указывает на самую свежую сборку для быстрого разрешения. Если ваш проект использует типизированные Coastfile (например, `Coastfile.light`), каждый тип получает собственную символическую ссылку: `latest-light`.\n\nКэш образов в `~/.coast/image-cache/` является общим для всех проектов. Если два проекта используют один и тот же образ Postgres, tarball-архив кэшируется один раз.\n\n## Что содержит сборка\n\nКаждая директория сборки содержит:\n\n- **`manifest.json`** -- полные метаданные сборки: имя проекта, метку времени сборки, хэш coastfile, список кэшированных/собранных образов, имена secret'ов, исключённые сервисы, [стратегии томов](VOLUMES.md) и многое другое.\n- **`coastfile.toml`** -- разрешённый Coastfile (объединённый с родительским, если используется `extends`).\n- **`compose.yml`** -- переписанная версия вашего compose-файла, где директивы `build:` заменены на теги заранее собранных образов, а исключённые сервисы удалены.\n- **`inject/`** -- копии файлов хоста из `[inject].files` (например, `~/.gitconfig`, `~/.npmrc`).\n\n## Сборки не содержат secrets\n\nSecrets извлекаются во время шага сборки, но хранятся в отдельном зашифрованном keystore по пути `~/.coast/keystore.db` -- не внутри директории артефакта сборки. Манифест записывает только **имена** извлечённых secrets, но никогда не их значения.\n\nЭто означает, что артефакты сборки безопасно просматривать без раскрытия чувствительных данных. Secrets расшифровываются и внедряются позже, когда экземпляр Coast создаётся с помощью `coast run`.\n\n## Сборки и Docker\n\nСборка включает три типа Docker-образов:\n\n- **Собранные образы** -- compose-сервисы с директивами `build:` собираются на хосте через `docker build`, получают тег `coast-built/{project}/{service}:latest` и сохраняются как tarball-архивы в кэше образов.\n- **Скачанные образы** -- compose-сервисы с директивами `image:` скачиваются и сохраняются как tarball-архивы.\n- **Образ Coast** -- если настроен `[coast.setup]`, пользовательский Docker-образ собирается поверх `docker:dind` с указанными пакетами, командами и файлами. Получает тег `coast-image/{project}:{build_id}`.\n\nВо время выполнения ([`coast run`](RUN.md)) эти tarball-архивы загружаются во внутренний [демон DinD](RUNTIMES_AND_SERVICES.md) через `docker load`. Именно это позволяет экземплярам Coast запускаться быстро без необходимости скачивать образы из реестра.\n\n## Сборки и экземпляры\n\nКогда вы запускаете [`coast run`](RUN.md), Coast определяет последнюю сборку (или конкретный `--build-id`) и использует её артефакты для создания экземпляра. ID сборки записывается в экземпляр.\n\nВам не нужно пересобирать, чтобы создавать дополнительные экземпляры. Одна сборка может обслуживать множество экземпляров Coast, работающих параллельно.\n\n## Когда нужно пересобирать\n\nПересобирайте только тогда, когда меняются ваш Coastfile, `docker-compose.yml` или конфигурация инфраструктуры. Пересборка требует значительных ресурсов -- она заново скачивает образы, заново собирает Docker-образы и заново извлекает secrets.\n\nИзменения в коде не требуют пересборки. Coast монтирует директорию вашего проекта напрямую в каждый экземпляр, поэтому обновления кода подхватываются сразу.\n\n## Автоматическая очистка\n\nCoast хранит до 5 сборок на каждый тип Coastfile. После каждой успешной команды `coast build` более старые сборки сверх лимита автоматически удаляются.\n\nСборки, которые используются работающими экземплярами, никогда не очищаются независимо от лимита. Если у вас есть 7 сборок, но 3 из них обслуживают активные экземпляры, все эти 3 защищены.\n\n## Ручное удаление\n\nВы можете удалять сборки вручную через `coast rm-build` или через вкладку Builds в Coastguard.\n\n- **Полное удаление проекта** (`coast rm-build `) требует, чтобы все экземпляры были сначала остановлены и удалены. Оно удаляет всю директорию сборки, связанные Docker-образы, тома и контейнеры.\n- **Выборочное удаление** (по ID сборки, доступно в интерфейсе Coastguard) пропускает сборки, которые используются работающими экземплярами.\n\n## Типизированные сборки\n\nЕсли ваш проект использует несколько Coastfile (например, `Coastfile` для конфигурации по умолчанию и `Coastfile.snap` для томов, инициализированных snapshot'ами), каждый тип поддерживает собственную символическую ссылку `latest-{type}` и собственный пул очистки из 5 сборок.\n\n```bash\ncoast build # uses Coastfile, updates \"latest\"\ncoast build --type snap # uses Coastfile.snap, updates \"latest-snap\"\n```\n\nОчистка сборки типа `snap` никогда не затрагивает сборки `default`, и наоборот.\n", - "concepts_and_terminology/CHECKOUT.md": "# Checkout\n\nCheckout управляет тем, какой экземпляр Coast владеет [каноническими портами](PORTS.md) вашего проекта. Когда вы выполняете checkout для Coast, `localhost:3000`, `localhost:5432` и любой другой канонический порт начинают напрямую указывать на этот экземпляр.\n\n```bash\ncoast checkout dev-1\n```\n\n```text\nBefore checkout:\n localhost:3000 ──→ (nothing)\n localhost:5432 ──→ (nothing)\n\nAfter checkout:\n localhost:3000 ──→ dev-1 web\n localhost:5432 ──→ dev-1 db\n```\n\nПереключение checkout происходит мгновенно — Coast завершает и заново запускает легковесные `socat`-форвардеры. Ни один контейнер не перезапускается.\n\n```bash\ncoast checkout dev-2 # instant swap\n\n# localhost:3000 ──→ dev-2 web\n# localhost:5432 ──→ dev-2 db\n```\n\n## Linux Note\n\nДинамические порты в Linux всегда работают без специальных привилегий.\n\nС каноническими портами ниже `1024` ситуация иная. Если ваш Coastfile объявляет порты вроде `80` или `443`, Linux может заблокировать привязку этих портов командой `coast checkout`, пока вы не настроите хост. Обычно это исправляется так:\n\n- увеличить `net.ipv4.ip_unprivileged_port_start`\n- выдать capability на bind бинарнику или процессу форвардинга\n\nCoast явно сообщает об этом, когда хост запрещает bind.\n\nВ WSL Coast использует checkout-мосты, опубликованные через Docker, чтобы браузеры и инструменты Windows могли обращаться к checked-out каноническим портам через `127.0.0.1`, аналогично сценариям Docker Desktop, таким как Sail.\n\n## Do You Need to Check Out?\n\nНе обязательно. У каждого запущенного Coast всегда есть собственные динамические порты, и вы можете обращаться к любому Coast через эти порты в любой момент, ничего не делая checkout.\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\nВы можете открыть `localhost:62217` в браузере, чтобы попасть на веб-сервер dev-1, не делая checkout. Для многих сценариев этого вполне достаточно, и вы можете запускать сколько угодно Coast, ни разу не используя `coast checkout`.\n\n## When Checkout Is Useful\n\nБывают ситуации, когда динамических портов недостаточно и нужны канонические порты:\n\n- **Клиентские приложения, жестко привязанные к каноническим портам.** Если у вас есть клиент, работающий вне Coast — frontend dev server на вашем хосте, мобильное приложение на телефоне или десктопное приложение — и он ожидает `localhost:3000` или `localhost:8080`, менять номера портов повсюду непрактично. Checkout Coast дает вам реальные порты без изменения какой-либо конфигурации.\n\n- **Webhook’и и callback URL.** Такие сервисы, как Stripe, GitHub или OAuth-провайдеры, отправляют callback-запросы на URL, который вы зарегистрировали — обычно что-то вроде `https://your-ngrok-tunnel.io`, перенаправляющее на `localhost:3000`. Если вы переключитесь на динамический порт, callback’и перестанут приходить. Checkout гарантирует, что канонический порт активен для Coast, который вы тестируете.\n\n- **Инструменты для работы с базами данных, отладчики и интеграции IDE.** Многие GUI-клиенты (pgAdmin, DataGrip, TablePlus), отладчики и конфигурации запуска в IDE сохраняют профили подключения с конкретным портом. Checkout позволяет сохранить эти профили и просто переключать, какой Coast стоит за ними — без перенастройки цели подключения отладчика или соединения с базой данных при каждом переключении контекста.\n\n## Releasing Checkout\n\nЕсли вы хотите освободить канонические порты, не выполняя checkout другого Coast:\n\n```bash\ncoast checkout --none\n```\n\nПосле этого ни один Coast не владеет каноническими портами. Все Coast остаются доступными через свои динамические порты.\n\n## Only One at a Time\n\nВ каждый момент времени checkout может быть выполнен ровно для одного Coast. Если checkout сделан для `dev-1` и вы запускаете `coast checkout dev-2`, канонические порты мгновенно переключаются на `dev-2`. Разрыва нет — старые форвардеры завершаются, а новые запускаются в рамках той же операции.\n\n```text\n┌──────────────────────────────────────────────────┐\n│ Your machine │\n│ │\n│ Canonical (checked-out Coast only): │\n│ localhost:3000 ──→ dev-2 web │\n│ localhost:5432 ──→ dev-2 db │\n│ │\n│ Dynamic (always available): │\n│ localhost:62217 ──→ dev-1 web │\n│ localhost:55681 ──→ dev-1 db │\n│ localhost:63104 ──→ dev-2 web │\n│ localhost:57220 ──→ dev-2 db │\n└──────────────────────────────────────────────────┘\n```\n\nДинамические порты не затрагиваются checkout. Меняется только то, куда указывают канонические порты.\n", + "concepts_and_terminology/CHECKOUT.md": "# Checkout\n\nCheckout управляет тем, какой экземпляр Coast владеет [каноническими портами](PORTS.md) вашего проекта. Когда вы выполняете checkout для Coast, `localhost:3000`, `localhost:5432` и любой другой канонический порт начинают напрямую указывать на этот экземпляр.\n\n```bash\ncoast checkout dev-1\n```\n\n```text\nBefore checkout:\n localhost:3000 ──→ (nothing)\n localhost:5432 ──→ (nothing)\n\nAfter checkout:\n localhost:3000 ──→ dev-1 web\n localhost:5432 ──→ dev-1 db\n```\n\nПереключение checkout происходит мгновенно — Coast завершает и заново запускает легковесные `socat`-форвардеры. Ни один контейнер не перезапускается.\n\n```bash\ncoast checkout dev-2 # instant swap\n\n# localhost:3000 ──→ dev-2 web\n# localhost:5432 ──→ dev-2 db\n```\n\n## Linux Note\n\nДинамические порты в Linux всегда работают без специальных привилегий.\n\nС каноническими портами ниже `1024` ситуация иная. Если ваш Coastfile объявляет порты вроде `80` или `443`, Linux может заблокировать привязку этих портов командой `coast checkout`, пока вы не настроите хост. Обычно это исправляется так:\n\n- увеличить `net.ipv4.ip_unprivileged_port_start`\n- выдать capability на bind бинарнику или процессу форвардинга\n\nCoast явно сообщает об этом, когда хост запрещает bind.\n\nВ WSL Coast использует checkout-мосты, опубликованные через Docker, чтобы браузеры и инструменты Windows могли обращаться к checked-out каноническим портам через `127.0.0.1`, аналогично сценариям Docker Desktop, таким как Sail.\n\nДля локальных HTTPS-проектов, использующих Caddy, Coast повторно использует один локальный Caddy CA для каждой установки Coast. После того как вы один раз доверите этот корневой сертификат, заново созданные рабочие пространства в рамках той же установки продолжат его использовать.\n\nКорневой сертификат находится по адресу:\n\n- `~/.coast/caddy/pki/authorities/local/root.crt` для обычной установки\n- `~/.coast-dev/caddy/pki/authorities/local/root.crt` для `coast-dev`\n\nОни намеренно разделены, поэтому доверие к `coast-dev` не означает автоматического доверия к обычной установке `coast`, и наоборот.\n\nЧтобы просмотреть информацию об активном корневом сертификате установки или экспортировать его:\n\n```bash\ncoast cert info\ncoast cert path\ncoast cert fingerprint\ncoast cert export --to ~/Downloads/coast-root.crt\n```\n\nУстановку доверия Coast оставляет на ваше усмотрение. Экспортируйте сертификат, а затем при необходимости импортируйте его в хранилище доверенных сертификатов вашей ОС или браузера.\n\n## Do You Need to Check Out?\n\nНе обязательно. У каждого запущенного Coast всегда есть собственные динамические порты, и вы можете обращаться к любому Coast через эти порты в любой момент, ничего не делая checkout.\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\nВы можете открыть `localhost:62217` в браузере, чтобы попасть на веб-сервер dev-1, не делая checkout. Для многих сценариев этого вполне достаточно, и вы можете запускать сколько угодно Coast, ни разу не используя `coast checkout`.\n\n## When Checkout Is Useful\n\nБывают ситуации, когда динамических портов недостаточно и нужны канонические порты:\n\n- **Клиентские приложения, жестко привязанные к каноническим портам.** Если у вас есть клиент, работающий вне Coast — frontend dev server на вашем хосте, мобильное приложение на телефоне или десктопное приложение — и он ожидает `localhost:3000` или `localhost:8080`, менять номера портов повсюду непрактично. Checkout Coast дает вам реальные порты без изменения какой-либо конфигурации.\n\n- **Webhook’и и callback URL.** Такие сервисы, как Stripe, GitHub или OAuth-провайдеры, отправляют callback-запросы на URL, который вы зарегистрировали — обычно что-то вроде `https://your-ngrok-tunnel.io`, перенаправляющее на `localhost:3000`. Если вы переключитесь на динамический порт, callback’и перестанут приходить. Checkout гарантирует, что канонический порт активен для Coast, который вы тестируете.\n\n- **Инструменты для работы с базами данных, отладчики и интеграции IDE.** Многие GUI-клиенты (pgAdmin, DataGrip, TablePlus), отладчики и конфигурации запуска в IDE сохраняют профили подключения с конкретным портом. Checkout позволяет сохранить эти профили и просто переключать, какой Coast стоит за ними — без перенастройки цели подключения отладчика или соединения с базой данных при каждом переключении контекста.\n\n## Releasing Checkout\n\nЕсли вы хотите освободить канонические порты, не выполняя checkout другого Coast:\n\n```bash\ncoast checkout --none\n```\n\nПосле этого ни один Coast не владеет каноническими портами. Все Coast остаются доступными через свои динамические порты.\n\n## Only One at a Time\n\nВ каждый момент времени checkout может быть выполнен ровно для одного Coast. Если checkout сделан для `dev-1` и вы запускаете `coast checkout dev-2`, канонические порты мгновенно переключаются на `dev-2`. Разрыва нет — старые форвардеры завершаются, а новые запускаются в рамках той же операции.\n\n```text\n┌──────────────────────────────────────────────────┐\n│ Your machine │\n│ │\n│ Canonical (checked-out Coast only): │\n│ localhost:3000 ──→ dev-2 web │\n│ localhost:5432 ──→ dev-2 db │\n│ │\n│ Dynamic (always available): │\n│ localhost:62217 ──→ dev-1 web │\n│ localhost:55681 ──→ dev-1 db │\n│ localhost:63104 ──→ dev-2 web │\n│ localhost:57220 ──→ dev-2 db │\n└──────────────────────────────────────────────────┘\n```\n\nДинамические порты не затрагиваются checkout. Меняется только то, куда указывают канонические порты.\n", "concepts_and_terminology/CLI.md": "# Coast CLI\n\nCoast CLI (`coast`) — это основной интерфейс командной строки для работы с Coasts. Он намеренно минималистичен: разбирает вашу команду, отправляет запрос в [`coastd`](DAEMON.md) и выводит структурированный результат обратно в ваш терминал.\n\n## Для чего он используется\n\nТипичные рабочие процессы полностью управляются из CLI:\n\n```bash\ncoast build # see Builds\ncoast run dev-1 # see Run\ncoast assign dev-1 --worktree feature/oauth # see Assign\ncoast ports dev-1 # see Ports\ncoast checkout dev-1 # see Checkout\ncoast ui # see Coastguard\n```\n\nCLI также включает команды документации, которые полезны как людям, так и агентам:\n\n```bash\ncoast docs\ncoast docs --path concepts_and_terminology/CHECKOUT.md\ncoast search-docs \"canonical vs dynamic ports\"\n```\n\n## Почему он существует отдельно от демона\n\nРазделение CLI и демона даёт несколько важных преимуществ:\n\n- Демон хранит состояние и долгоживущие процессы.\n- CLI остаётся быстрым, компонуемым и удобным для написания скриптов.\n- Вы можете запускать одноразовые команды, не поддерживая состояние терминала активным.\n- Инструменты агентов могут вызывать команды CLI предсказуемыми, удобными для автоматизации способами.\n\n## CLI vs Coastguard\n\nИспользуйте тот интерфейс, который лучше подходит для текущего момента:\n\n- CLI предназначен для полного операционного охвата: всё, что вы можете сделать в Coastguard, также должно быть возможно из CLI.\n- Рассматривайте CLI как интерфейс автоматизации — скрипты, рабочие процессы агентов, задачи CI и пользовательские инструменты разработчика.\n- Рассматривайте [Coastguard](COASTGUARD.md) как интерфейс для человека — визуальная инспекция, интерактивная отладка и операционная наблюдаемость.\n\nОба взаимодействуют с одним и тем же демоном, поэтому работают с одним и тем же базовым состоянием проекта.\n", "concepts_and_terminology/COASTFILE_TYPES.md": "# Типы Coastfile\n\nОдин проект может иметь несколько Coastfile для разных сценариев использования. Каждый вариант называется «типом». Типы позволяют составлять конфигурации, которые разделяют общую базу, но различаются тем, какие сервисы запускаются, как обрабатываются тома или включён ли автозапуск сервисов.\n\n## Как работают типы\n\nСоглашение об именовании: `Coastfile` для типа по умолчанию и `Coastfile.{type}` для вариантов. Суффикс после точки становится именем типа:\n\n- `Coastfile` -- тип по умолчанию\n- `Coastfile.test` -- тестовый тип\n- `Coastfile.snap` -- тип снимка\n- `Coastfile.light` -- облегчённый тип\n\nВы собираете и запускаете типизированные Coast с `--type`:\n\n```bash\ncoast build --type test\ncoast run test-1 --type test\ncoast exec test-1 -- go test ./...\n```\n\n## extends\n\nТипизированный Coastfile наследуется от родителя через `extends`. Всё из родителя объединяется. Дочернему нужно указать только то, что он переопределяет или добавляет.\n\n```toml\n[coast]\nextends = \"Coastfile\"\n```\n\nЭто позволяет не дублировать всю конфигурацию для каждого варианта. Дочерний файл наследует все конфигурации [портов](PORTS.md), [секретов](SECRETS.md), [томов](VOLUMES.md), [общих сервисов](SHARED_SERVICES.md), [стратегий assign](ASSIGN.md), команд настройки и [MCP](MCP_SERVERS.md) от родителя. Всё, что определяет дочерний файл, имеет приоритет над родителем.\n\n## [unset]\n\nУдаляет конкретные элементы, унаследованные от родителя, по имени. Можно unset для `ports`, `shared_services`, `secrets` и `volumes`.\n\n```toml\n[unset]\nports = [\"web\", \"redis\", \"backend\"]\nshared_services = [\"postgres\", \"redis\"]\n```\n\nТак тестовый вариант убирает общие сервисы (чтобы базы данных работали внутри Coast с изолированными томами) и удаляет порты, которые ему не нужны.\n\n## [omit]\n\nПолностью убирает compose-сервисы из сборки. Исключённые сервисы удаляются из compose-файла и вообще не запускаются внутри Coast.\n\n```toml\n[omit]\nservices = [\"redis\", \"backend\", \"mailhog\", \"web\"]\n```\n\nИспользуйте это, чтобы исключить сервисы, которые не имеют отношения к назначению варианта. Тестовый вариант может оставить только базу данных, миграции и раннер тестов.\n\n## autostart\n\nУправляет тем, запускается ли `docker compose up` автоматически при старте Coast. Значение по умолчанию — `true`.\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n```\n\nУстановите `autostart = false` для вариантов, где вы хотите запускать конкретные команды вручную, а не поднимать весь стек. Это часто встречается для раннеров тестов — вы создаёте Coast, затем используете [`coast exec`](EXEC_AND_DOCKER.md), чтобы запускать отдельные наборы тестов.\n\n## Распространённые шаблоны\n\n### Тестовый вариант\n\n`Coastfile.test`, который оставляет только то, что нужно для запуска тестов:\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n\n[unset]\nports = [\"web\", \"redis\", \"backend\"]\nshared_services = [\"postgres\", \"redis\"]\n\n[omit]\nservices = [\"redis\", \"backend\", \"mailhog\", \"web\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[assign]\ndefault = \"none\"\n[assign.services]\ntest-runner = \"rebuild\"\nmigrations = \"rebuild\"\n```\n\nКаждый тестовый Coast получает свою собственную чистую базу данных. Порты не публикуются, потому что тесты обращаются к сервисам через внутреннюю compose-сеть. `autostart = false` означает, что вы запускаете тесты вручную с помощью `coast exec`.\n\n### Вариант снимка\n\n`Coastfile.snap`, который наполняет каждый Coast копией существующих томов базы данных с хоста:\n\n```toml\n[coast]\nextends = \"Coastfile\"\n\n[unset]\nshared_services = [\"postgres\", \"redis\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"my_project_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"my_project_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n```\n\nОбщие сервисы убираются через unset, чтобы базы данных работали внутри каждого Coast. `snapshot_source` наполняет изолированные тома данными из существующих томов хоста на этапе сборки. После создания данные каждого экземпляра расходятся независимо.\n\n### Облегчённый вариант\n\n`Coastfile.light`, который сводит проект к минимуму для конкретного рабочего процесса — возможно, только backend-сервис и его база данных для быстрой итерации.\n\n## Независимые пулы сборок\n\nУ каждого типа есть свой симлинк `latest-{type}` и свой авто-очищаемый пул из 5 сборок:\n\n```bash\ncoast build # обновляет latest, очищает сборки типа по умолчанию\ncoast build --type test # обновляет latest-test, очищает тестовые сборки\ncoast build --type snap # обновляет latest-snap, очищает сборки снимков\n```\n\nСборка типа `test` не влияет на сборки `default` или `snap`. Очистка полностью независима для каждого типа.\n\n## Запуск типизированных Coast\n\nЭкземпляры, созданные с `--type`, помечаются своим типом. Вы можете одновременно запускать экземпляры разных типов для одного и того же проекта:\n\n```bash\ncoast run dev-1 # тип по умолчанию\ncoast run test-1 --type test # тестовый тип\ncoast run snapshot-1 --type snap # тип снимка\n\ncoast ls\n# Все три отображаются, каждый со своим типом, портами и стратегией томов\n```\n\nТак вы можете держать запущенную полноценную dev-среду рядом с изолированными раннерами тестов и экземплярами, заполненными из снимка — всё для одного и того же проекта, всё одновременно.\n", "concepts_and_terminology/COASTGUARD.md": "# Coastguard\n\nCoastguard — это локальный веб-интерфейс Coast (представьте: интерфейс Coast в стиле Docker Desktop), работающий на порту `31415`. Он запускается из CLI:\n\n```bash\ncoast ui\n```\n\n![Coastguard project overview](../../assets/coastguard-overview.png)\n*Панель проекта, показывающая запущенные экземпляры Coast, их ветки/worktrees и состояние checkout.*\n\n![Coastguard port mappings](../../assets/coastguard-ports.png)\n*Страница портов для конкретного экземпляра Coast, показывающая канонические и динамические сопоставления портов для каждого сервиса.*\n\n## Для чего полезен Coastguard\n\nCoastguard предоставляет вам визуальную поверхность управления и наблюдаемости для вашего проекта:\n\n- Просматривайте проекты, экземпляры, статусы, ветки и состояние checkout.\n- Изучайте [сопоставления портов](PORTS.md) и переходите напрямую к сервисам.\n- Просматривайте [логи](LOGS.md), статистику выполнения и инспектируйте данные.\n- Просматривайте [сборки](BUILDS.md), артефакты образов, метаданные [томов](VOLUMES.md) и [секретов](SECRETS.md).\n- Открывайте документацию внутри приложения во время работы.\n\n## Связь с CLI и демоном\n\nCoastguard не заменяет CLI. Он дополняет его как интерфейс для человека.\n\n- [`coast` CLI](CLI.md) — интерфейс автоматизации для скриптов, агентных рабочих процессов и интеграций с инструментами.\n- Coastguard — интерфейс для человека для визуальной инспекции, интерактивной отладки и повседневной операционной видимости.\n- Оба являются клиентами [`coastd`](DAEMON.md), поэтому они остаются синхронизированными.\n", "concepts_and_terminology/COASTS.md": "# Coast'ы\n\nCoast — это самодостаточная среда выполнения вашего проекта. Она работает внутри [контейнера Docker-in-Docker](RUNTIMES_AND_SERVICES.md), и несколько сервисов (ваш веб-сервер, база данных, кэш и т. д.) могут работать внутри одного экземпляра Coast.\n\n```text\n┌─── Coast: dev-1 (branch: feature/oauth) ──────────────┐\n│ │\n│ ┌─────────┐ ┌──────────┐ ┌─────────┐ │\n│ │ web │ │ postgres │ │ redis │ │\n│ │ :3000 │ │ :5432 │ │ :6379 │ │\n│ └─────────┘ └──────────┘ └─────────┘ │\n│ │\n│ dynamic ports: 62217, 55681, 56905 │\n└───────────────────────────────────────────────────────┘\n\n┌─── Coast: dev-2 (branch: feature/billing) ────────────┐\n│ │\n│ ┌─────────┐ ┌──────────┐ ┌─────────┐ │\n│ │ web │ │ postgres │ │ redis │ │\n│ │ :3000 │ │ :5432 │ │ :6379 │ │\n│ └─────────┘ └──────────┘ └─────────┘ │\n│ │\n│ dynamic ports: 63104, 57220, 58412 │\n└───────────────────────────────────────────────────────┘\n```\n\nКаждый Coast предоставляет хост-машине собственный набор [динамических портов](PORTS.md), что означает, что вы можете получить доступ к любому запущенному Coast в любой момент независимо от того, что ещё запущено.\n\nКогда вы [переключаете](CHECKOUT.md) Coast, канонические порты проекта сопоставляются с ним — так что `localhost:3000` обращается к переключённому Coast, а не к динамическому порту.\n\n```text\ncoast checkout dev-1\n\nlocalhost:3000 ──→ dev-1 web\nlocalhost:5432 ──→ dev-1 postgres\nlocalhost:6379 ──→ dev-1 redis\n\ncoast checkout dev-2 (instant swap)\n\nlocalhost:3000 ──→ dev-2 web\nlocalhost:5432 ──→ dev-2 postgres\nlocalhost:6379 ──→ dev-2 redis\n```\n\nОбычно Coast [назначается конкретному worktree](ASSIGN.md). Именно так вы запускаете несколько worktree одного и того же проекта параллельно без конфликтов портов или пересечений томов.\n\nВы создаёте экземпляры Coast с помощью [`coast run`](RUN.md). Когда поднимать и останавливать Coast'ы — решать вам. Вероятно, вы не захотите держать одновременно запущенными 20 Coast'ов ресурсоёмкого по памяти проекта, но каждому своё.\n", "concepts_and_terminology/DAEMON.md": "# Демон Coast\n\nДемон Coast (`coastd`) — это долгоживущий локальный процесс, который выполняет фактическую работу по оркестрации. [CLI](CLI.md) и [Coastguard](COASTGUARD.md) являются клиентами; `coastd` — это плоскость управления, стоящая за ними.\n\n## Архитектура в общих чертах\n\n```text\ncoast CLI (автоматизация) -----+\n +--> демон coastd\nCoastguard UI (человек) -------+ |\n +--> Coasts\n +--> Ports\n +--> State\n```\n\nCLI отправляет запросы в `coastd` через локальный Unix-сокет; Coastguard подключается по WebSocket. Демон применяет изменения к состоянию выполнения.\n\n## Что он делает\n\n`coastd` обрабатывает операции, которым требуется постоянное состояние и фоновая координация:\n\n- Отслеживает экземпляры Coast, сборки и общие сервисы.\n- Создаёт, запускает, останавливает и удаляет среды выполнения Coast.\n- Применяет операции assign/unassign/checkout.\n- Управляет каноническим и динамическим [пробросом портов](PORTS.md).\n- Передаёт потоком [логи](LOGS.md), статус и события выполнения клиентам CLI и UI.\n\nКороче говоря: если вы выполняете `coast run`, `coast assign`, `coast checkout` или `coast ls`, демон — это компонент, который выполняет работу.\n\n## Как он запускается\n\nВы можете запустить демон двумя распространёнными способами:\n\n```bash\n# Register daemon auto-start at login (recommended)\ncoast daemon install\n\n# Manual start mode\ncoast daemon start\n```\n\nЕсли вы пропустите установку демона, вам нужно будет запускать его самостоятельно в каждой сессии перед использованием команд Coast.\n\n## Сообщение об ошибках\n\nЕсли у вас возникли проблемы, пожалуйста, приложите логи демона `coastd` при отправке отчёта об ошибке. Логи содержат контекст, необходимый для диагностики большинства проблем:\n\n```bash\ncoast daemon logs\n```\n", - "concepts_and_terminology/EXEC_AND_DOCKER.md": "# Exec & Docker\n\n`coast exec` переносит вас в shell внутри DinD-контейнера Coast. Ваша рабочая директория — `/workspace` — [bind-mounted корень проекта](FILESYSTEM.md), где находится ваш Coastfile. Это основной способ запускать команды, просматривать файлы или отлаживать сервисы внутри Coast с хост-машины.\n\n`coast docker` — вспомогательная команда для прямого взаимодействия с внутренним демоном Docker.\n\n## `coast exec`\n\nОткрыть shell внутри инстанса Coast:\n\n```bash\ncoast exec dev-1\n```\n\nЭто запускает сессию `sh` в `/workspace`. Контейнеры Coast основаны на Alpine, поэтому shell по умолчанию — `sh`, а не `bash`.\n\nТакже можно выполнить конкретную команду, не входя в интерактивный shell:\n\n```bash\ncoast exec dev-1 ls -la\ncoast exec dev-1 -- npm install\ncoast exec dev-1 -- go test ./...\n```\n\nВсё, что указано после имени инстанса, передаётся как команда. Используйте `--`, чтобы отделить флаги, относящиеся к вашей команде, от флагов, относящихся к `coast exec`.\n\n### Working Directory\n\nShell стартует в `/workspace` — это bind-mounted в контейнер корень вашего проекта на хосте. Это означает, что ваш исходный код, Coastfile и все файлы проекта находятся прямо там:\n\n```text\n/workspace $ ls\nCoastfile README.md apps/ packages/\nCoastfile.light go.work infra/ scripts/\nCoastfile.snap go.work.sum package-lock.json\n```\n\nЛюбые изменения, которые вы делаете в файлах под `/workspace`, сразу отражаются на хосте — это bind mount, а не копия.\n\n### Interactive vs Non-Interactive\n\nКогда stdin — это TTY (вы печатаете в терминале), `coast exec` полностью обходит daemon и запускает `docker exec -it` напрямую для полного проброса TTY. Это означает, что цвета, перемещение курсора, автодополнение по Tab и интерактивные программы работают как ожидается.\n\nКогда stdin направлен по pipe или запускается из скрипта (CI, агентные workflows, `coast exec dev-1 -- some-command | grep foo`), запрос проходит через daemon и возвращает структурированные stdout, stderr и код завершения.\n\n### File Permissions\n\nExec запускается с UID:GID вашего пользователя на хосте, поэтому файлы, созданные внутри Coast, получают корректного владельца на хосте. Никаких несовпадений прав между хостом и контейнером.\n\n## `coast docker`\n\nЕсли `coast exec` даёт вам shell в самом DinD-контейнере, то `coast docker` позволяет запускать команды Docker CLI против **внутреннего** демона Docker — того, который управляет вашими compose-сервисами.\n\n```bash\ncoast docker dev-1 # по умолчанию: docker ps\ncoast docker dev-1 ps # то же самое, что выше\ncoast docker dev-1 compose ps # docker compose ps (внутренние сервисы)\ncoast docker dev-1 images # список образов во внутреннем демоне\ncoast docker dev-1 compose logs web # docker compose logs для сервиса\n```\n\nКаждая переданная команда автоматически получает префикс `docker`. То есть `coast docker dev-1 compose ps` запускает `docker compose ps` внутри контейнера Coast, обращаясь к внутреннему демону.\n\n### `coast exec` vs `coast docker`\n\nРазница в том, на что вы нацеливаетесь:\n\n| Command | Runs as | Target |\n|---|---|---|\n| `coast exec dev-1 ls /workspace` | `sh -c \"ls /workspace\"` в DinD-контейнере | Сам контейнер Coast (файлы проекта, установленные инструменты) |\n| `coast docker dev-1 ps` | `docker ps` в DinD-контейнере | Внутренний демон Docker (контейнеры compose-сервисов) |\n| `coast docker dev-1 compose logs web` | `docker compose logs web` в DinD-контейнере | Логи конкретного compose-сервиса через внутренний демон |\n\nИспользуйте `coast exec` для работы на уровне проекта — запуск тестов, установка зависимостей, просмотр файлов. Используйте `coast docker`, когда нужно увидеть, что делает внутренний демон Docker — статус контейнеров, образы, сети, операции compose.\n\n## Coastguard Exec Tab\n\nВеб-интерфейс Coastguard предоставляет постоянный интерактивный терминал, подключённый по WebSocket.\n\n![Exec tab in Coastguard](../../assets/coastguard-exec.png)\n*Вкладка Coastguard Exec, показывающая shell-сессию в /workspace внутри инстанса Coast.*\n\nТерминал работает на xterm.js и предлагает:\n\n- **Постоянные сессии** — терминальные сессии сохраняются при навигации по страницам и обновлениях браузера. При переподключении воспроизводится буфер прокрутки (scrollback), чтобы вы продолжили с того же места.\n- **Несколько вкладок** — откройте несколько shell одновременно. Каждая вкладка — независимая сессия.\n- Вкладки **[Agent shell](AGENT_SHELLS.md)** — создавайте выделенные agent shell для AI coding agents с отслеживанием статуса active/inactive.\n- **Полноэкранный режим** — разверните терминал на весь экран (Escape для выхода).\n\nПомимо exec-вкладки на уровне инстанса, Coastguard также предоставляет терминальный доступ и на других уровнях:\n\n- **Service exec** — перейдите в отдельный сервис на вкладке Services, чтобы получить shell внутри конкретного внутреннего контейнера (это делает двойной `docker exec` — сначала в DinD-контейнер, затем в контейнер сервиса).\n- **Exec для [Shared service](SHARED_SERVICES.md)** — получите shell внутри контейнера shared service на уровне хоста.\n- **Host terminal** — shell на вашей хост-машине в корне проекта, вообще не заходя в Coast.\n\n## When to Use Which\n\n- **`coast exec`** — запуск команд на уровне проекта (npm install, go test, просмотр файлов, отладка) внутри DinD-контейнера.\n- **`coast docker`** — просмотр или управление внутренним демоном Docker (статус контейнеров, образы, сети, операции compose).\n- **Вкладка Coastguard Exec** — интерактивная отладка с постоянными сессиями, несколькими вкладками и поддержкой agent shell. Лучше всего, когда вы хотите держать открытыми несколько терминалов, одновременно используя остальную часть UI.\n- **`coast logs`** — для чтения вывода сервисов используйте `coast logs` вместо `coast docker compose logs`. См. [Logs](LOGS.md).\n- **`coast ps`** — для проверки статуса сервисов используйте `coast ps` вместо `coast docker compose ps`. См. [Runtimes and Services](RUNTIMES_AND_SERVICES.md).\n", + "concepts_and_terminology/EXEC_AND_DOCKER.md": "# Exec и Docker\n\n`coast exec` открывает вам оболочку внутри DinD-контейнера Coast. Ваш рабочий каталог — `/workspace` — это [примонтированный через bind корень проекта](FILESYSTEM.md), где находится ваш Coastfile. Это основной способ запускать команды, просматривать файлы или отлаживать сервисы внутри Coast с вашей хост-машины.\n\n`coast docker` — это вспомогательная команда для прямого взаимодействия с внутренним демоном Docker.\n\n## `coast exec`\n\nОткройте оболочку внутри экземпляра Coast:\n\n```bash\ncoast exec dev-1\n```\n\nЭто запускает сессию `sh` в `/workspace`. Контейнеры Coast основаны на Alpine, поэтому оболочка по умолчанию — `sh`, а не `bash`.\n\nВы также можете выполнить конкретную команду без входа в интерактивную оболочку:\n\n```bash\ncoast exec dev-1 ls -la\ncoast exec dev-1 -- npm install\ncoast exec dev-1 -- go test ./...\ncoast exec dev-1 --service web\ncoast exec dev-1 --service web -- php artisan test\n```\n\nВсё, что идёт после имени экземпляра, передаётся как команда. Используйте `--`, чтобы отделить флаги, относящиеся к вашей команде, от флагов, относящихся к `coast exec`.\n\nПередайте `--service `, чтобы обратиться к конкретному контейнеру compose-сервиса вместо внешнего контейнера Coast. Передайте `--root`, когда вам нужен необработанный доступ как root контейнера вместо используемого Coast по умолчанию сопоставления UID:GID хоста.\n\n### Рабочий каталог\n\nОболочка запускается в `/workspace`, который является bind-mounted корнем проекта с вашего хоста внутри контейнера. Это означает, что ваш исходный код, Coastfile и все файлы проекта находятся прямо там:\n\n```text\n/workspace $ ls\nCoastfile README.md apps/ packages/\nCoastfile.light go.work infra/ scripts/\nCoastfile.snap go.work.sum package-lock.json\n```\n\nЛюбые изменения, которые вы вносите в файлы под `/workspace`, немедленно отражаются на хосте — это bind mount, а не копия.\n\n### Интерактивный и неинтерактивный режимы\n\nКогда stdin является TTY (вы вводите команды в терминале), `coast exec` полностью обходит демон и запускает `docker exec -it` напрямую для полной передачи TTY. Это означает, что цвета, перемещение курсора, автодополнение по Tab и интерактивные программы работают как ожидается.\n\nКогда stdin передаётся по конвейеру или через скрипт (CI, агентские рабочие процессы, `coast exec dev-1 -- some-command | grep foo`), запрос проходит через демон и возвращает структурированные stdout, stderr и код выхода.\n\n### Права доступа к файлам\n\nExec выполняется с UID:GID пользователя вашего хоста, поэтому файлы, созданные внутри Coast, получают корректного владельца на хосте. Никаких несоответствий прав между хостом и контейнером.\n\n## `coast docker`\n\nЕсли `coast exec` даёт вам оболочку в самом DinD-контейнере, то `coast docker` позволяет запускать команды Docker CLI против **внутреннего** демона Docker — того, который управляет вашими compose-сервисами.\n\n```bash\ncoast docker dev-1 # по умолчанию: docker ps\ncoast docker dev-1 ps # то же самое, что выше\ncoast docker dev-1 compose ps # docker compose ps для активного стека, управляемого Coast\ncoast docker dev-1 images # список образов во внутреннем демоне\ncoast docker dev-1 compose logs web # docker compose logs для сервиса\n```\n\nКаждая команда, которую вы передаёте, автоматически получает префикс `docker`. Поэтому `coast docker dev-1 compose ps` запускает `docker compose ps` внутри контейнера Coast, обращаясь к внутреннему демону.\n\n### `coast exec` и `coast docker`\n\nРазница в том, на что именно вы нацеливаетесь:\n\n| Command | Runs as | Target |\n|---|---|---|\n| `coast exec dev-1 ls /workspace` | `sh -c \"ls /workspace\"` в DinD-контейнере | Сам контейнер Coast (файлы вашего проекта, установленные инструменты) |\n| `coast exec dev-1 --service web` | `docker exec ... sh` в определённом внутреннем контейнере сервиса | Конкретный контейнер compose-сервиса |\n| `coast docker dev-1 ps` | `docker ps` в DinD-контейнере | Внутренний демон Docker (контейнеры ваших compose-сервисов) |\n| `coast docker dev-1 compose logs web` | `docker compose logs web` в DinD-контейнере | Логи конкретного compose-сервиса через внутренний демон |\n\nИспользуйте `coast exec` для работы на уровне проекта — запуска тестов, установки зависимостей, просмотра файлов. Используйте `coast docker`, когда вам нужно увидеть, что делает внутренний демон Docker — состояние контейнеров, образы, сети, операции compose.\n\n## Вкладка Exec в Coastguard\n\nВеб-интерфейс Coastguard предоставляет постоянный интерактивный терминал, подключённый по WebSocket.\n\n![Exec tab in Coastguard](../../assets/coastguard-exec.png)\n*Вкладка Coastguard Exec, показывающая сессию оболочки в `/workspace` внутри экземпляра Coast.*\n\nТерминал работает на xterm.js и предлагает:\n\n- **Постоянные сессии** — сессии терминала сохраняются при переходах по страницам и обновлении браузера. При повторном подключении буфер прокрутки воспроизводится, так что вы продолжаете с того места, где остановились.\n- **Несколько вкладок** — откройте сразу несколько оболочек. Каждая вкладка — это независимая сессия.\n- **Вкладки [оболочки агента](AGENT_SHELLS.md)** — создавайте выделенные оболочки агента для ИИ-агентов программирования с отслеживанием активного/неактивного состояния.\n- **Полноэкранный режим** — разверните терминал на весь экран (Escape для выхода).\n\nПомимо вкладки exec на уровне экземпляра, Coastguard также предоставляет доступ к терминалу на других уровнях:\n\n- **Service exec** — перейдите в отдельный сервис из вкладки Services, чтобы получить оболочку внутри этого конкретного внутреннего контейнера (это выполняет двойной `docker exec` — сначала в DinD-контейнер, затем в контейнер сервиса).\n- **Exec для [общего сервиса](SHARED_SERVICES.md)** — получите оболочку внутри контейнера общего сервиса на уровне хоста.\n- **Терминал хоста** — оболочка на вашей хост-машине в корне проекта, вообще без входа в Coast.\n\n## Когда что использовать\n\n- **`coast exec`** — запускайте команды на уровне проекта внутри DinD-контейнера или передавайте `--service`, чтобы открыть оболочку или выполнить команду внутри конкретного контейнера compose-сервиса.\n- **`coast docker`** — просматривайте или управляйте внутренним демоном Docker (состояние контейнеров, образы, сети, операции compose).\n- **Вкладка Coastguard Exec** — интерактивная отладка с постоянными сессиями, несколькими вкладками и поддержкой оболочек агента. Лучший выбор, если вы хотите держать открытыми несколько терминалов, перемещаясь по остальному интерфейсу.\n- **`coast logs`** — для чтения вывода сервисов используйте `coast logs` вместо `coast docker compose logs`. См. [Logs](LOGS.md).\n- **`coast ps`** — для проверки состояния сервисов используйте `coast ps` вместо `coast docker compose ps`. См. [Runtimes and Services](RUNTIMES_AND_SERVICES.md).\n", "concepts_and_terminology/FILESYSTEM.md": "# Файловая система\n\nВаша хост-машина и каждый экземпляр Coast используют одни и те же файлы проекта. Корень проекта на хосте монтируется на чтение-запись в контейнер DinD по пути `/host-project`, а Coast bind-монтирует активное рабочее дерево по пути `/workspace`. Именно это позволяет агенту, запущенному на хост-машине, редактировать код, а сервисам внутри Coast подхватывать изменения в реальном времени.\n\n## Общее монтирование\n\n```text\nHost machine\n│\n├── ~/dev/my-app/ (project root)\n│ ├── src/\n│ ├── Coastfile\n│ ├── docker-compose.yml\n│ └── .worktrees/ (worktrees, gitignored)\n│ ├── feature-auth/\n│ └── feature-billing/\n│\n└── Docker daemon (host)\n │\n └── Coast: dev-1 (docker:dind)\n │\n ├── /host-project ← Docker bind mount of project root (RW, fixed)\n │\n ├── /workspace ← mount --bind /host-project (switchable)\n │ ├── src/ same files, same bytes, instant sync\n │ ├── Coastfile\n │ └── docker-compose.yml\n │\n └── Inner Docker daemon\n └── web service\n └── /app ← compose bind mount from /workspace/src\n```\n\nКорень проекта на хосте монтируется на чтение-запись по пути `/host-project` внутри [контейнера DinD](RUNTIMES_AND_SERVICES.md) при создании контейнера. После запуска контейнера команда `mount --bind /host-project /workspace` внутри контейнера создаёт рабочий путь `/workspace` с общей пропагацией монтирований (`mount --make-rshared`), чтобы внутренние compose-сервисы, которые bind-монтируют подкаталоги `/workspace`, видели корректное содержимое.\n\nЭтот двухэтапный подход существует не просто так: Docker bind mount в `/host-project` фиксируется при создании контейнера и не может быть изменён без пересоздания контейнера. Но Linux bind mount в `/workspace` внутри контейнера можно размонтировать и примонтировать заново к другому подкаталогу — worktree — не затрагивая жизненный цикл контейнера. Именно это делает `coast assign` быстрым.\n\n`/workspace` доступен на чтение-запись. Изменения файлов мгновенно распространяются в обе стороны. Сохраните файл на хосте — и dev-сервер внутри Coast тут же подхватит его. Создайте файл внутри Coast — и он появится на хосте.\n\n## Агенты на хосте и Coast\n\n```text\n┌─── Host machine ──────────────────────────────────────────┐\n│ │\n│ AI Agent (Cursor, Claude Code, etc.) │\n│ │ │\n│ ├── reads/writes files at /src/ │\n│ │ ↕ (instant, same filesystem) │\n│ ├── coast logs dev-1 --service web --tail 50 │\n│ ├── coast ps dev-1 │\n│ └── coast exec dev-1 -- npm test │\n│ │\n├───────────────────────────────────────────────────────────┤\n│ │\n│ Coast: dev-1 │\n│ └── /workspace/src/ ← same bytes as host project/src │\n│ └── web service picks up changes on save │\n│ │\n└───────────────────────────────────────────────────────────┘\n```\n\nПоскольку файловая система общая, ИИ-агент для написания кода, запущенный на хосте, может свободно редактировать файлы, и работающие сервисы внутри Coast немедленно видят изменения. Агенту не нужно запускаться внутри контейнера Coast — он работает с хоста как обычно.\n\nКогда агенту нужна информация времени выполнения — логи, статус сервисов, вывод тестов — он вызывает команды Coast CLI с хоста:\n\n- `coast logs dev-1 --service web --tail 50` для вывода сервиса (см. [Logs](LOGS.md))\n- `coast ps dev-1` для статуса сервисов (см. [Runtimes and Services](RUNTIMES_AND_SERVICES.md))\n- `coast exec dev-1 -- npm test` чтобы запускать команды внутри Coast (см. [Exec & Docker](EXEC_AND_DOCKER.md))\n\nЭто фундаментальное архитектурное преимущество: **редактирование кода происходит на хосте, выполнение — в Coast, а общая файловая система связывает их.** Хост-агенту никогда не нужно быть «внутри» Coast, чтобы выполнять свою работу.\n\n## Переключение worktree\n\nКогда `coast assign` переключает Coast на другое worktree, он перемонтирует `/workspace`, чтобы он указывал на это git worktree вместо корня проекта:\n\n```text\ncoast assign dev-1 --worktree feature-auth\n\nBefore: /workspace ←──mount── /host-project (project root)\nAfter: /workspace ←──mount── /host-project/.worktrees/feature-auth (worktree)\n```\n\nWorktree создаётся на хосте в `{project_root}/.worktrees/{worktree_name}`. Имя каталога `.worktrees` настраивается через `worktree_dir` в вашем Coastfile и должно быть в вашем `.gitignore`.\n\nЕсли worktree новый, Coast перед перемонтированием подготавливает выбранные gitignored-файлы из корня проекта. Он перечисляет игнорируемые файлы с помощью `git ls-files --others --ignored --exclude-standard`, отфильтровывает типичные «тяжёлые» каталоги плюс любые настроенные `exclude_paths`, затем использует `rsync --files-from` с `--link-dest`, чтобы создать жёсткие ссылки на выбранные файлы в worktree. Coast записывает эту подготовку во внутренние метаданные worktree и пропускает её при последующих assign к тому же worktree, если только вы явно не обновите её с помощью `coast assign --force-sync`.\n\nВнутри контейнера `/workspace` «лениво» размонтируется и привязывается заново к подкаталогу worktree по пути `/host-project/.worktrees/{branch_name}`. Это перемонтирование быстрое — оно не пересоздаёт контейнер DinD и не перезапускает внутренний Docker daemon. Compose- и bare-сервисы всё же могут быть пересозданы или перезапущены после перемонтирования, чтобы их bind-монтирования разрешались через новый `/workspace`.\n\nБольшие каталоги зависимостей, такие как `node_modules`, не входят в этот общий путь подготовки. Обычно они обрабатываются через специфичные для сервисов кэши или тома.\n\nЕсли вы используете `[assign.rebuild_triggers]`, Coast также запускает `git diff --name-only ..` на хосте, чтобы решить, можно ли сервис, помеченный `rebuild`, понизить до `restart`. Подробности, влияющие на задержку assign, см. в [Assign and Unassign](ASSIGN.md) и [Performance Optimizations](PERFORMANCE_OPTIMIZATIONS.md).\n\n`coast unassign` возвращает `/workspace` обратно к `/host-project` (корню проекта). `coast start` после остановки повторно применяет корректное монтирование в зависимости от того, назначено ли экземпляру worktree.\n\n## Все монтирования\n\nУ каждого контейнера Coast есть следующие монтирования:\n\n| Path | Type | Access | Purpose |\n|---|---|---|---|\n| `/workspace` | bind mount (in-container) | RW | Корень проекта или worktree. Переключается при assign. |\n| `/host-project` | Docker bind mount | RW | «Сырой» корень проекта. Фиксирован при создании контейнера. |\n| `/image-cache` | Docker bind mount | RO | Предварительно скачанные OCI tarballs из `~/.coast/image-cache/`. |\n| `/coast-artifact` | Docker bind mount | RO | Артефакт сборки с переписанными compose-файлами. |\n| `/coast-override` | Docker bind mount | RO | Сгенерированные compose-переопределения для [shared services](SHARED_SERVICES.md). |\n| `/var/lib/docker` | Named volume | RW | Состояние внутреннего Docker daemon. Сохраняется при удалении контейнера. |\n\nМонтирования только для чтения — это инфраструктура: они содержат артефакт сборки, кэшированные образы и compose-переопределения, которые генерирует Coast. Вы взаимодействуете с ними косвенно через `coast build` и Coastfile. Монтирования на чтение-запись — это место, где живёт ваш код и где внутренний daemon хранит своё состояние.\n", "concepts_and_terminology/LOGS.md": "# Логи\n\nСервисы внутри Coast запускаются во вложенных контейнерах — ваши compose-сервисы управляются внутренним Docker-демоном внутри DinD-контейнера. Это означает, что инструменты логирования на уровне хоста не могут их видеть. Если ваш рабочий процесс включает logging MCP, который читает Docker-логи на хосте, он увидит только внешний DinD-контейнер, а не веб-сервер, базу данных или воркер, работающие внутри него.\n\nРешение — `coast logs`. Любой агент или инструмент, которому нужно читать вывод сервисов из экземпляра Coast, должен использовать Coast CLI вместо доступа к Docker-логам на уровне хоста.\n\n## Компромисс MCP\n\nЕсли вы используете AI-агента с logging MCP (инструмент, который собирает логи Docker-контейнеров с вашего хоста — см. [MCP Servers](MCP_SERVERS.md)), этот MCP не будет работать для сервисов, запущенных внутри Coast. Хостовый Docker-демон видит один контейнер на экземпляр Coast — DinD-контейнер — и его логи представляют собой лишь вывод запуска внутреннего Docker-демона.\n\nЧтобы собирать реальные логи сервисов, укажите агенту использовать:\n\n```bash\ncoast logs --service --tail \n```\n\nНапример, если вашему агенту нужно разобраться, почему падает backend-сервис:\n\n```bash\ncoast logs dev-1 --service backend --tail 100\n```\n\nЭто эквивалент `docker compose logs`, но проксируется через демон Coast во внутренний DinD-контейнер. Если у вас есть правила агента или системные промпты, которые ссылаются на logging MCP, вам нужно добавить инструкцию, которая переопределяет это поведение при работе внутри Coast.\n\n## `coast logs`\n\nCLI предоставляет несколько способов читать логи из экземпляра Coast:\n\n```bash\ncoast logs dev-1 # last 200 lines, all services\ncoast logs dev-1 --service web # last 200 lines, web only\ncoast logs dev-1 --tail 50 # last 50 lines, then follow\ncoast logs dev-1 --tail # all lines, then follow\ncoast logs dev-1 --service backend -f # follow mode (stream new entries)\ncoast logs dev-1 --service web --tail 100 # last 100 lines + follow\n```\n\nБез `--tail` или `-f` команда возвращает последние 200 строк и завершается. С `--tail` она отдаёт запрошенное количество строк, а затем продолжает в реальном времени следовать за новым выводом. `-f` / `--follow` включает режим follow сам по себе.\n\nВывод использует формат логов compose с префиксом сервиса на каждой строке:\n\n```text\nweb | 2026/02/28 01:49:34 Listening on :3000\nbackend | 2026/02/28 01:49:34 [INFO] Server started on :8080\nbackend | 2026/02/28 01:49:34 [ProcessCreditsJob] starting at 2026-02-28T01:49:34Z\nredis | 1:M 28 Feb 2026 01:49:30.123 * Ready to accept connections\n```\n\nТакже можно фильтровать по сервису с помощью устаревшего позиционного синтаксиса (`coast logs dev-1 web`), но предпочтительнее флаг `--service`.\n\n## Вкладка Logs в Coastguard\n\nВеб-интерфейс Coastguard предоставляет более богатые возможности просмотра логов с потоковой передачей в реальном времени по WebSocket.\n\n![Logs tab in Coastguard](../../assets/coastguard-logs.png)\n*Вкладка Logs в Coastguard, транслирующая вывод backend-сервиса с фильтрацией по сервисам и поиском.*\n\nВкладка Logs предлагает:\n\n- **Поток в реальном времени** — логи приходят по WebSocket-соединению по мере их появления, со статус-индикатором, показывающим состояние соединения.\n- **Фильтр сервиса** — выпадающий список, заполняемый по префиксам сервисов в потоке логов. Выберите один сервис, чтобы сфокусироваться на его выводе.\n- **Поиск** — фильтруйте отображаемые строки по тексту или regex (переключите режим regex кнопкой со звёздочкой). Совпадающие фрагменты подсвечиваются.\n- **Счётчики строк** — показывает количество отфильтрованных строк по сравнению с общим числом строк (например, \"200 / 971 lines\").\n- **Очистка** — обрезает файлы логов внутреннего контейнера и сбрасывает просмотр.\n- **Полноэкранный режим** — разворачивает просмотр логов на весь экран.\n\nСтроки логов отображаются с поддержкой ANSI-цветов, подсветкой уровней логов (ERROR — красным, WARN — янтарным, INFO — синим, DEBUG — серым), приглушением временных меток и цветными бейджами сервисов для наглядного различения между сервисами.\n\nОбщие сервисы, работающие на хостовом демоне, имеют собственный просмотр логов, доступный на вкладке Shared Services. Подробности см. в [Shared Services](SHARED_SERVICES.md).\n\n## Как это работает\n\nКогда вы запускаете `coast logs`, демон выполняет `docker compose logs` внутри DinD-контейнера через `docker exec` и транслирует вывод обратно в ваш терминал (или в UI Coastguard по WebSocket).\n\n```text\ncoast logs dev-1 --service web --tail 50\n │\n ├── CLI sends LogsRequest to daemon (Unix socket)\n │\n ├── Daemon resolves instance → container ID\n │\n ├── Daemon exec's into DinD container:\n │ docker compose logs --tail 50 --follow web\n │\n └── Output streams back chunk by chunk\n └── CLI prints to stdout / Coastguard renders in UI\n```\n\nДля [bare services](BARE_SERVICES.md) демон читает (tail) файлы логов в `/var/log/coast-services/` вместо вызова `docker compose logs`. Формат вывода тот же (`service | line`), поэтому фильтрация по сервисам работает одинаково в обоих случаях.\n\n## Связанные команды\n\n- `coast ps ` — проверить, какие сервисы запущены и каков их статус. См. [Runtimes and Services](RUNTIMES_AND_SERVICES.md).\n- [`coast exec `](EXEC_AND_DOCKER.md) — открыть shell внутри контейнера Coast для ручной отладки.\n", "concepts_and_terminology/LOOKUP.md": "# Lookup\n\n`coast lookup` обнаруживает, какие экземпляры Coast запущены для текущего рабочего каталога вызывающего. Это первая команда, которую должен запустить агент на стороне хоста, чтобы сориентироваться — «Я редактирую код здесь, с каким(и) Coast мне взаимодействовать?»\n\n```bash\ncoast lookup\n```\n\nLookup определяет, находитесь ли вы внутри [worktree](ASSIGN.md) или в корне проекта, запрашивает у демона соответствующие экземпляры и выводит результаты с портами, URL и примерами команд.\n\n## Why This Exists\n\nИИ-агент для кодинга, работающий на хосте (Cursor, Claude Code, Codex и т. п.), редактирует файлы через [shared filesystem](FILESYSTEM.md) и вызывает команды Coast CLI для операций во время выполнения. Но сначала агенту нужно ответить на базовый вопрос: **какой экземпляр Coast соответствует каталогу, в котором я работаю?**\n\nБез `coast lookup` агенту пришлось бы запустить `coast ls`, разобрать полную таблицу экземпляров, определить, в каком worktree он находится, и сопоставить это. `coast lookup` делает всё это за один шаг и возвращает структурированный вывод, который агенты могут потреблять напрямую.\n\nЭту команду следует включать в любой верхнеуровневый SKILL.md, AGENTS.md или файл правил для агентных workflow, которые используют Coast. Это точка входа для агента, чтобы определить свой контекст выполнения.\n\n## Output Modes\n\n### Default (human-readable)\n\n```bash\ncoast lookup\n```\n\n```text\nCoast instances for worktree feature/oauth (my-app):\n\n dev-1 running ★ checked out\n\n Primary URL: http://dev-1.localhost:62217\n\n SERVICE CANONICAL DYNAMIC\n ★ web 3000 62217\n api 8080 63889\n postgres 5432 55681\n\n Examples (exec starts at the workspace root where your Coastfile is, cd to your target directory first):\n coast exec dev-1 -- sh -c \"cd && \"\n coast logs dev-1 --service \n coast ps dev-1\n```\n\nРаздел с примерами напоминает агентам (и людям), что `coast exec` стартует из корня workspace — каталога, где находится Coastfile. Чтобы выполнить команду в подкаталоге, сделайте `cd` в него внутри exec.\n\n### Compact (`--compact`)\n\nВозвращает JSON-массив имён экземпляров. Предназначен для скриптов и агентного инструментария, которому нужно лишь знать, на какие экземпляры нацеливаться.\n\n```bash\ncoast lookup --compact\n```\n\n```text\n[\"dev-1\"]\n```\n\nНесколько экземпляров в одном worktree:\n\n```text\n[\"dev-1\",\"dev-2\"]\n```\n\nНет совпадений:\n\n```text\n[]\n```\n\n### JSON (`--json`)\n\nВозвращает полный структурированный ответ в виде красиво отформатированного JSON. Предназначен для агентов, которым нужны порты, URL и статус в машиночитаемом формате.\n\n```bash\ncoast lookup --json\n```\n\n```json\n{\n \"project\": \"my-app\",\n \"worktree\": \"feature/oauth\",\n \"project_root\": \"/Users/dev/my-app\",\n \"instances\": [\n {\n \"name\": \"dev-1\",\n \"status\": \"Running\",\n \"checked_out\": true,\n \"branch\": \"feature/oauth\",\n \"primary_url\": \"http://dev-1.localhost:62217\",\n \"ports\": [\n { \"logical_name\": \"web\", \"canonical_port\": 3000, \"dynamic_port\": 62217, \"is_primary\": true },\n { \"logical_name\": \"api\", \"canonical_port\": 8080, \"dynamic_port\": 63889, \"is_primary\": false }\n ]\n }\n ]\n}\n```\n\n## How It Resolves\n\nLookup поднимается вверх от текущего рабочего каталога, чтобы найти ближайший Coastfile, затем определяет, в каком worktree вы находитесь:\n\n1. Если ваш cwd находится под `{project_root}/{worktree_dir}/{name}/...`, lookup находит экземпляры, назначенные этому worktree.\n2. Если ваш cwd — корень проекта (или любой каталог, не находящийся внутри worktree), lookup находит экземпляры, у которых **не назначен worktree** — те, которые всё ещё указывают на корень проекта.\n\nЭто означает, что lookup работает и из подкаталогов. Если вы находитесь в `my-app/.worktrees/feature-oauth/src/api/`, lookup всё равно определит `feature-oauth` как worktree.\n\n## Exit Codes\n\n| Code | Meaning |\n|------|---------|\n| 0 | Найден один или несколько подходящих экземпляров |\n| 1 | Нет подходящих экземпляров (пустой результат) |\n\nЭто делает lookup пригодным для использования в условиях shell:\n\n```bash\nif coast lookup > /dev/null 2>&1; then\n coast exec dev-1 -- sh -c \"cd src && npm test\"\nfi\n```\n\n## For Agent Workflows\n\nТипичный паттерн интеграции агента:\n\n1. Агент начинает работу в каталоге worktree.\n2. Агент запускает `coast lookup`, чтобы узнать имена экземпляров, порты, URL и примеры команд.\n3. Агент использует имя экземпляра для всех последующих команд Coast: `coast exec`, `coast logs`, `coast ps`.\n\n```text\n┌─── Agent (host machine) ────────────────────────────┐\n│ │\n│ 1. coast lookup │\n│ → instance names, ports, URLs, examples │\n│ 2. coast exec dev-1 -- sh -c \"cd src && npm test\" │\n│ 3. coast logs dev-1 --service web --tail 50 │\n│ 4. coast ps dev-1 │\n│ │\n└──────────────────────────────────────────────────────┘\n```\n\nЕсли агент работает сразу с несколькими worktree, он запускает `coast lookup` из каталога каждого worktree, чтобы определить правильный экземпляр для каждого контекста.\n\nСм. также [Filesystem](FILESYSTEM.md) о том, как хост-агенты взаимодействуют с Coast, [Assign and Unassign](ASSIGN.md) о концепциях worktree, и [Exec & Docker](EXEC_AND_DOCKER.md) о выполнении команд внутри Coast.\n", @@ -2036,13 +2077,20 @@ "concepts_and_terminology/SHARED_SERVICES.md": "# Общие сервисы\n\nОбщие сервисы — это контейнеры баз данных и инфраструктуры (Postgres, Redis, MongoDB и т. д.), которые запускаются в Docker daemon вашего хоста, а не внутри Coast. Экземпляры Coast подключаются к ним через bridge-сеть, поэтому каждый Coast обращается к одному и тому же сервису на одном и том же томе хоста.\n\n![Shared services in Coastguard](../../assets/coastguard-shared-services.png)\n*Вкладка общих сервисов в Coastguard, показывающая управляемые хостом Postgres, Redis и MongoDB.*\n\n## Как они работают\n\nКогда вы объявляете общий сервис в вашем Coastfile, Coast запускает его в daemon хоста и удаляет его из compose-стека, который работает внутри каждого контейнера Coast. Затем Coasts настраиваются так, чтобы маршрутизировать трафик по имени сервиса обратно к общему контейнеру, сохраняя при этом порт сервиса на стороне контейнера внутри Coast.\n\n```text\nHost Docker daemon\n |\n +--> postgres (host volume: infra_postgres_data)\n +--> redis (host volume: infra_redis_data)\n +--> mongodb (host volume: infra_mongodb_data)\n |\n +--> Coast: dev-1 --bridge network--> host postgres, redis, mongodb\n +--> Coast: dev-2 --bridge network--> host postgres, redis, mongodb\n```\n\nПоскольку общие сервисы повторно используют существующие тома хоста, любые данные, которые у вас уже есть после локального запуска `docker-compose up`, сразу доступны вашим Coasts.\n\nЭто различие важно, когда вы используете сопоставленные порты:\n\n```toml\n[shared_services.postgis]\nimage = \"ghcr.io/baosystems/postgis:12-3.3\"\nports = [\"5433:5432\"]\n```\n\n- На хосте общий сервис публикуется на `localhost:5433`.\n- Внутри каждого Coast контейнеры приложения по-прежнему подключаются к `postgis:5432`.\n- Простое целое число, такое как `5432`, является сокращением для тождественного сопоставления `\"5432:5432\"`.\n\n## Когда использовать общие сервисы\n\n- В вашем проекте есть интеграции MCP, которые подключаются к локальной базе данных — общие сервисы позволяют им продолжать работать без динамического определения портов. Если вы публикуете общий сервис на том же порту хоста, который уже используют ваши инструменты (например, `ports = [5432]`), эти инструменты продолжают работать без изменений. Если вы публикуете его на другом порту хоста (например, `\"5433:5432\"`), инструменты на стороне хоста должны использовать этот порт хоста, тогда как Coasts продолжают использовать порт контейнера.\n- Вы хотите более легковесные экземпляры Coast, поскольку им не нужно запускать собственные контейнеры баз данных.\n- Вам не нужна изоляция данных между экземплярами Coast (каждый экземпляр видит одни и те же данные).\n- Вы запускаете coding agents на хосте (см. [Filesystem](FILESYSTEM.md)) и хотите, чтобы они получали доступ к состоянию базы данных без маршрутизации через [`coast exec`](EXEC_AND_DOCKER.md). С общими сервисами существующие инструменты базы данных и MCP агента продолжают работать без изменений.\n\nСм. страницу [Volume Topology](VOLUMES.md), чтобы узнать об альтернативах, когда вам все же нужна изоляция.\n\n## Предупреждение о неоднозначности томов\n\nИмена Docker volumes не всегда глобально уникальны. Если вы запускаете `docker-compose up` из нескольких разных проектов, тома хоста, которые Coast подключает к общим сервисам, могут оказаться не теми, которые вы ожидаете.\n\nПеред запуском Coasts с общими сервисами убедитесь, что последний `docker-compose up`, который вы запускали, был из проекта, который вы собираетесь использовать с Coasts. Это гарантирует, что тома хоста соответствуют тому, что ожидает ваш Coastfile.\n\n## Устранение неполадок\n\nЕсли кажется, что ваши общие сервисы указывают на неправильный том хоста:\n\n1. Откройте интерфейс [Coastguard](COASTGUARD.md) (`coast ui`).\n2. Перейдите на вкладку **Shared Services**.\n3. Выберите затронутые сервисы и нажмите **Remove**.\n4. Нажмите **Refresh Shared Services**, чтобы заново создать их из текущей конфигурации Coastfile.\n\nЭто удалит и заново создаст контейнеры общих сервисов, повторно подключив их к правильным томам хоста.\n", "concepts_and_terminology/TROUBLESHOOTING.md": "# Устранение неполадок\n\nБольшинство проблем с Coasts возникает из‑за устаревшего состояния, «осиротевших» ресурсов Docker или демона, который вышел из синхронизации. Эта страница описывает путь эскалации от лёгких мер до радикальных.\n\n## Doctor\n\nЕсли что-то работает странно — экземпляры отображаются как запущенные, но ничего не отвечает, порты будто «застряли», или UI показывает устаревшие данные — начните с `coast doctor`:\n\n```bash\ncoast doctor\n```\n\nDoctor сканирует базу данных состояния и Docker на предмет несоответствий: осиротевшие записи экземпляров с отсутствующими контейнерами, «висящие» контейнеры без записи состояния и общие сервисы, отмеченные как запущенные, хотя на самом деле они «мертвы». Он автоматически исправляет всё, что находит.\n\nЧтобы посмотреть, что он сделает, не изменяя ничего:\n\n```bash\ncoast doctor --dry-run\n```\n\n## Daemon Restart\n\nЕсли сам демон кажется неотзывчивым или вы подозреваете, что он находится в плохом состоянии, перезапустите его:\n\n```bash\ncoast daemon restart\n```\n\nЭто отправляет сигнал корректного завершения, ждёт выхода демона и запускает новый процесс. Ваши экземпляры и состояние сохраняются.\n\n## Removing a Single Project\n\nЕсли проблема ограничена одним проектом, вы можете удалить его артефакты сборки и связанные ресурсы Docker, не затрагивая ничего другого:\n\n```bash\ncoast rm-build my-project\n```\n\nЭто удаляет каталог артефактов проекта, Docker-образы, тома и контейнеры. Сначала запрашивается подтверждение. Передайте `--force`, чтобы пропустить запрос.\n\n## Missing Shared Service Images\n\nЕсли `coast run` завершается неудачей при создании общего сервиса с ошибкой вроде `No such image: postgres:15`, значит, образ отсутствует в вашем хостовом демоне Docker.\n\nЧаще всего это происходит, когда в вашем `Coastfile` определены `shared_services`, такие как Postgres или Redis, а Docker ещё не скачал эти образы.\n\nСкачайте отсутствующий образ, затем запустите экземпляр снова:\n\n```bash\ndocker pull postgres:15\ndocker pull redis:7\ncoast run my-instance\n```\n\nЕсли вы не уверены, какого именно образа не хватает, вывод упавшей команды `coast run` будет содержать имя образа в ошибке Docker. После неудачной попытки подготовки Coasts автоматически очищает частично созданный экземпляр, поэтому ожидаемо, что экземпляр вернётся в состояние `stopped`.\n\n## Factory Reset with Nuke\n\nКогда ничего больше не помогает — или вы просто хотите полностью чистый лист — `coast nuke` выполняет полный сброс до заводских настроек:\n\n```bash\ncoast nuke\n```\n\nЭто:\n\n1. Остановит демон `coastd`.\n2. Удалит **все** Docker-контейнеры под управлением coast.\n3. Удалит **все** Docker-тома под управлением coast.\n4. Удалит **все** Docker-сети под управлением coast.\n5. Удалит **все** Docker-образы coast.\n6. Удалит весь каталог `~/.coast/` (база данных состояния, сборки, логи, секреты, кэш образов).\n7. Воссоздаст `~/.coast/` и перезапустит демон, чтобы coast сразу снова был готов к использованию.\n\nПоскольку это уничтожает всё, в приглашении подтверждения нужно ввести `nuke`:\n\n```text\n$ coast nuke\nWARNING: This will permanently destroy ALL coast data:\n\n - Stop the coastd daemon\n - Remove all coast-managed Docker containers\n - Remove all coast-managed Docker volumes\n - Remove all coast-managed Docker networks\n - Remove all coast Docker images\n - Delete ~/.coast/ (state DB, builds, logs, secrets, image cache)\n\nType \"nuke\" to confirm:\n```\n\nПередайте `--force`, чтобы пропустить запрос (полезно в скриптах):\n\n```bash\ncoast nuke --force\n```\n\nПосле nuke coast готов к использованию — демон запущен, а домашний каталог существует. Вам просто нужно снова выполнить `coast build` и `coast run` для ваших проектов.\n\n## Reporting Bugs\n\nЕсли вы столкнулись с проблемой, которая не устраняется ничем из перечисленного выше, при сообщении приложите логи демона:\n\n```bash\ncoast daemon logs\n```\n", "concepts_and_terminology/VOLUMES.md": "# Топология томов\n\nCoast предоставляет три стратегии работы с томами, которые определяют, как сервисы с большим объёмом данных (базы данных, кэши и т. д.) хранят и разделяют свои данные между экземплярами Coast. Выбор подходящей стратегии зависит от того, насколько сильная изоляция вам нужна и какой накладной расход вы готовы терпеть.\n\n## Общие сервисы\n\n[Общие сервисы](SHARED_SERVICES.md) запускаются на хостовом демоне Docker, вне какого-либо контейнера Coast. Такие сервисы, как Postgres, MongoDB и Redis, остаются на хостовой машине, а экземпляры Coast направляют свои запросы обратно на хост через bridge-сеть.\n\n```text\nHost machine\n |\n +--> Postgres (host daemon, existing volume)\n +--> Redis (host daemon, existing volume)\n |\n +--> Coast: dev-1 --connects to--> host Postgres, host Redis\n +--> Coast: dev-2 --connects to--> host Postgres, host Redis\n```\n\nМежду экземплярами нет изоляции данных — каждый Coast обращается к одной и той же базе данных. Взамен вы получаете:\n\n- Более лёгкие экземпляры Coast, поскольку они не запускают собственные контейнеры баз данных.\n- Ваши существующие хостовые тома используются напрямую, поэтому любые данные, которые у вас уже есть, становятся доступны сразу.\n- Интеграции MCP, которые подключаются к вашей локальной базе данных, продолжают работать из коробки.\n\nЭто настраивается в вашем [Coastfile](COASTFILE_TYPES.md) в разделе `[shared_services]`.\n\n## Общие тома\n\nОбщие тома монтируют один Docker-том, который разделяется между всеми экземплярами Coast. Сами сервисы (Postgres, Redis и т. д.) запускаются внутри каждого контейнера Coast, но все они читают и записывают данные в один и тот же базовый том.\n\n```text\nCoast: dev-1 --mounts--> shared volume \"my-project-postgres\"\nCoast: dev-2 --mounts--> shared volume \"my-project-postgres\"\n```\n\nЭто изолирует данные Coast от того, что находится на вашей хостовой машине, но экземпляры всё ещё разделяют данные между собой. Это полезно, когда вы хотите чистое отделение от хостовой среды разработки без накладных расходов на тома для каждого экземпляра.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## Изолированные тома\n\nИзолированные тома предоставляют каждому экземпляру Coast свой собственный независимый том. Никакие данные не разделяются между экземплярами или с хостом. Каждый экземпляр стартует пустым (или из снимка — см. ниже) и развивается независимо.\n\n```text\nCoast: dev-1 --mounts--> volume \"dev-1-postgres\"\nCoast: dev-2 --mounts--> volume \"dev-2-postgres\"\n```\n\nЭто лучший выбор для проектов, где много интеграционных тестов и нужна настоящая изоляция томов между параллельными окружениями. Компромисс — более медленный старт и более крупные сборки Coast, поскольку каждый экземпляр поддерживает собственную копию данных.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## Создание снимков\n\nСтратегии shared и isolated по умолчанию начинают с пустых томов. Если вы хотите, чтобы экземпляры стартовали с копией существующего хостового тома, установите `snapshot_source` в имя Docker-тома, из которого нужно копировать:\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\nСнимок создаётся во время [сборки](BUILDS.md). После создания том каждого экземпляра расходится независимо — изменения не распространяются обратно на источник или на другие экземпляры.\n\nCoast пока не поддерживает создание снимков во время выполнения (например, создание снимка тома из запущенного экземпляра). Это запланировано для будущего релиза.\n", - "harnesses/README.md": "# Harnesses\n\nКаждый harness создает git worktree в своем месте. В Coasts массив\n[`worktree_dir`](../coastfiles/WORKTREE_DIR.md) указывает, где их искать --\nвключая внешние пути, такие как `~/.codex/worktrees`, для которых требуются\nдополнительные bind mounts.\n\nУ каждого harness также есть свои соглашения для инструкций на уровне проекта, skills и commands. Матрица ниже показывает, что поддерживает каждый harness, чтобы вы знали, куда помещать указания для Coasts. На каждой странице описаны конфигурация Coastfile, рекомендуемая структура файлов и любые особенности, относящиеся именно к этому harness.\n\nЕсли один репозиторий используется из нескольких harness, см. [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n\n| Harness | Worktree location | Project instructions | Skills | Commands | Page |\n|---------|-------------------|----------------------|--------|----------|------|\n| OpenAI Codex | `~/.codex/worktrees` | `AGENTS.md` | `.agents/skills/` | Skills surface as `/` commands | [Codex](CODEX.md) |\n| Claude Code | `.claude/worktrees` | `CLAUDE.md` | `.claude/skills/` | `.claude/commands/` | [Claude Code](CLAUDE_CODE.md) |\n| Cursor | `~/.cursor/worktrees/` | `AGENTS.md` or `.cursor/rules/` | `.cursor/skills/` or `.agents/skills/` | `.cursor/commands/` | [Cursor](CURSOR.md) |\n| Conductor | `~/conductor/workspaces/` | `CLAUDE.md` | -- | -- | [Conductor](CONDUCTOR.md) |\n| T3 Code | `~/.t3/worktrees/` | `AGENTS.md` | `.agents/skills/` | -- | [T3 Code](T3_CODE.md) |\n\n## Skills vs Commands\n\nSkills и commands оба позволяют определить повторно используемый workflow `/coasts`. Вы можете использовать что-то одно или оба варианта, в зависимости от того, что поддерживает harness.\n\nЕсли ваш harness поддерживает commands и вам нужна явная точка входа `/coasts`,\nодин из простых вариантов — добавить command, который переиспользует skill.\nCommands явно вызываются по имени, поэтому вы точно знаете, когда запускается\nworkflow `/coasts`. Skills также могут автоматически загружаться агентом\nна основе контекста, что полезно, но означает, что у вас меньше контроля над тем,\nкогда подтягиваются инструкции.\n\nВы можете использовать оба варианта. Если так и делаете, пусть command\nпереиспользует skill вместо того, чтобы поддерживать отдельную копию workflow.\n\nЕсли harness поддерживает только skills (T3 Code), используйте skill. Если он не поддерживает\nни то ни другое (Conductor), поместите workflow `/coasts` прямо в файл\nинструкций проекта.\n", - "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) создаёт\nworktree внутри проекта в `.claude/worktrees/`. Поскольку этот каталог\nнаходится внутри репозитория, Coasts может обнаруживать и назначать worktree\nClaude Code без какого-либо внешнего bind mount.\n\nClaude Code также является здесь harness с наиболее чётким разделением на три\nслоя для Coasts:\n\n- `CLAUDE.md` для коротких, всегда активных правил работы с Coasts\n- `.claude/skills/coasts/SKILL.md` для переиспользуемого workflow `/coasts`\n- `.claude/commands/coasts.md` только если вам нужен файл команды как\n дополнительная точка входа\n\n## Настройка\n\nДобавьте `.claude/worktrees` в `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\nПоскольку `.claude/worktrees` является путём относительно проекта, внешний bind mount\nне нужен.\n\n## Куда помещать руководство по Coasts\n\n### `CLAUDE.md`\n\nПоместите сюда правила для Coasts, которые должны применяться в каждой задаче.\nСделайте их короткими и практическими:\n\n- запускать `coast lookup` перед первой runtime-командой в сессии\n- использовать `coast exec` для тестов, сборок и сервисных команд\n- использовать `coast ps` и `coast logs` для обратной связи от runtime\n- спрашивать перед созданием или переназначением Coast, если соответствия не существует\n\n### `.claude/skills/coasts/SKILL.md`\n\nПоместите сюда переиспользуемый workflow `/coasts`. Это правильное место для\nпотока, который:\n\n1. запускает `coast lookup` и повторно использует подходящий Coast\n2. переключается на `coast ls`, когда соответствия нет\n3. предлагает `coast run`, `coast assign`, `coast unassign`, `coast checkout`, и\n `coast ui`\n4. использует CLI Coast напрямую как контракт, а не оборачивает его\n\nЕсли этот репозиторий также использует Codex, T3 Code или Cursor, см.\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) и храните канонический skill в\n`.agents/skills/coasts/`, а затем откройте к нему доступ из Claude Code.\n\n### `.claude/commands/coasts.md`\n\nClaude Code также поддерживает файлы команд проекта. Для документации о Coasts\nсчитайте это необязательным:\n\n- используйте это только если вам действительно нужен файл команды\n- один простой вариант — сделать так, чтобы команда переиспользовала тот же skill\n- если вы дадите команде собственные отдельные инструкции, вы берёте на себя\n поддержку второй копии workflow\n\n## Пример структуры\n\n### Только Claude Code\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\nЕсли этот репозиторий также использует Codex, T3 Code или Cursor, используйте общий шаблон из\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) вместо его дублирования здесь,\nпотому что дублирующиеся provider-specific инструкции становится всё труднее\nподдерживать синхронизированными каждый раз, когда вы добавляете ещё один harness.\n\n## Что делает Coasts\n\n- **Запуск** — `coast run ` создаёт новый экземпляр Coast из последней сборки. Используйте `coast run -w `, чтобы создать и назначить worktree Claude Code за один шаг. См. [Run](../concepts_and_terminology/RUN.md).\n- **Обнаружение** — Coasts читает `.claude/worktrees` как любой другой локальный\n каталог worktree.\n- **Именование** — worktree Claude Code используют то же поведение именования\n локальных worktree, что и другие worktree внутри репозитория в UI и CLI Coasts.\n- **Назначение** — `coast assign` может переключать `/workspace` на worktree Claude Code\n без какого-либо внешнего уровня bind-mount indirection.\n- **Синхронизация gitignored** — работает нормально, потому что worktree находятся внутри\n дерева репозитория.\n- **Обнаружение orphan** — если Claude Code удаляет worktree, Coasts может обнаружить\n отсутствующий gitdir и при необходимости снять назначение.\n\n## Пример\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — worktree Claude Code\n- `~/.codex/worktrees/` — worktree Codex, если вы также используете Codex в этом репозитории\n\n## Ограничения\n\n- Если вы дублируете один и тот же workflow `/coasts` в `CLAUDE.md`,\n `.claude/skills` и `.claude/commands`, эти копии будут расходиться. Держите\n `CLAUDE.md` коротким, а переиспользуемый workflow — в одном skill.\n- Если вы хотите, чтобы один репозиторий чисто работал в нескольких harness,\n предпочитайте общий шаблон из [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", - "harnesses/CODEX.md": "# Codex\n\n[Codex](https://developers.openai.com/codex/app/worktrees/) создаёт worktree в `$CODEX_HOME/worktrees` (обычно `~/.codex/worktrees`). Каждый worktree находится в каталоге с непрозрачным хешем, например `~/.codex/worktrees/a0db/project-name`, начинается с detached HEAD и автоматически очищается в соответствии с политикой хранения Codex.\n\nИз [документации Codex](https://developers.openai.com/codex/app/worktrees/):\n\n> Могу ли я управлять тем, где создаются worktree?\n> Пока нет. Codex создаёт worktree в `$CODEX_HOME/worktrees`, чтобы иметь возможность единообразно управлять ими.\n\nПоскольку эти worktree находятся вне корня проекта, Coasts требуется явная\nконфигурация, чтобы обнаруживать и монтировать их.\n\n## Setup\n\nДобавьте `~/.codex/worktrees` в `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nCoasts разворачивает `~` во время выполнения и рассматривает любой путь,\nначинающийся с `~/` или `/`, как внешний. Подробности см. в [Worktree\nDirectories](../coastfiles/WORKTREE_DIR.md).\n\nПосле изменения `worktree_dir` существующие инстансы необходимо **пересоздать**, чтобы bind mount вступил в силу:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nСписок worktree обновляется сразу (Coasts читает новый Coastfile), но\nназначение на worktree Codex требует bind mount внутри контейнера.\n\n## Where Coasts guidance goes\n\nДля работы с Coasts используйте файл инструкций проекта Codex и общую\nструктуру skills:\n\n- поместите краткие правила Coast Runtime в `AGENTS.md`\n- поместите переиспользуемый workflow `/coasts` в `.agents/skills/coasts/SKILL.md`\n- Codex показывает этот skill как команду `/coasts`\n- если вы используете метаданные, специфичные для Codex, храните их рядом со\n skill в `.agents/skills/coasts/agents/openai.yaml`\n- не создавайте отдельный файл команд проекта только ради документации о\n Coasts; skill — это переиспользуемая поверхность\n- если этот репозиторий также использует Cursor или Claude Code, храните\n канонический skill в `.agents/skills/` и публикуйте его оттуда. См.\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) и\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\nНапример, минимальный `.agents/skills/coasts/agents/openai.yaml` может\nвыглядеть так:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\nЭто делает skill видимым в Codex с более удобной меткой и превращает `/coasts`\nв явную команду. Добавляйте `dependencies.tools` только если skill также нужны\nMCP-серверы или другая настройка инструментов под управлением OpenAI.\n\n## What Coasts does\n\n- **Run** -- `coast run ` создаёт новый инстанс Coast из последней сборки. Используйте `coast run -w `, чтобы за один шаг создать и назначить worktree Codex. См. [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** -- При создании контейнера Coasts монтирует\n `~/.codex/worktrees` в контейнер по пути `/host-external-wt/{index}`.\n- **Discovery** -- `git worktree list --porcelain` привязан к репозиторию, поэтому отображаются только worktree Codex, принадлежащие текущему проекту, даже если каталог содержит worktree для множества проектов.\n- **Naming** -- Worktree с detached HEAD отображаются как их относительный путь внутри внешнего каталога (`a0db/my-app`, `eca7/my-app`). Worktree, основанные на ветках, отображаются по имени ветки.\n- **Assign** -- `coast assign` повторно монтирует `/workspace` из пути внешнего bind mount.\n- **Gitignored sync** -- Выполняется в файловой системе хоста с абсолютными путями, работает без bind mount.\n- **Orphan detection** -- Наблюдатель git рекурсивно сканирует внешние каталоги,\n фильтруя по указателям gitdir в `.git`. Если Codex удаляет\n worktree, Coasts автоматически снимает назначение с инстанса.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code (локально, без специальной обработки)\n- `~/.codex/worktrees/` -- Codex (внешний, с bind mount)\n\n## Limitations\n\n- Codex может очистить worktree в любой момент. Механизм обнаружения orphan в Coasts\n корректно это обрабатывает.\n", - "harnesses/CONDUCTOR.md": "# Conductor\n\n[Conductor](https://conductor.build/) запускает параллельных агентов Claude Code, каждый в своей изолированной рабочей области. Рабочие области — это git worktree, хранящиеся в `~/conductor/workspaces//`. Каждая рабочая область checkout'ится на именованной ветке.\n\nПоскольку эти worktree находятся вне корня проекта, Coasts требуется явная\nконфигурация, чтобы обнаруживать и монтировать их.\n\n## Настройка\n\nДобавьте `~/conductor/workspaces/` в `worktree_dir`. В отличие от Codex (который хранит все проекты в одном плоском каталоге), Conductor размещает worktree во вложенном подкаталоге для каждого проекта, поэтому путь должен включать имя проекта. В примере ниже `my-app` должно совпадать с фактическим именем папки вашего репозитория в `~/conductor/workspaces/`.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nConductor позволяет настраивать путь к рабочим областям для каждого репозитория, поэтому путь по умолчанию `~/conductor/workspaces` может не соответствовать вашей настройке. Проверьте настройки вашего репозитория Conductor, чтобы найти фактический путь, и скорректируйте его соответствующим образом — принцип одинаков независимо от того, где находится каталог.\n\nCoasts разворачивает `~` во время выполнения и считает любой путь, начинающийся с `~/` или `/`, внешним. Подробности см. в [Worktree Directories](../coastfiles/WORKTREE_DIR.md).\n\nПосле изменения `worktree_dir` существующие инстансы нужно **пересоздать**, чтобы bind mount вступил в силу:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nСписок worktree обновляется сразу (Coasts читает новый Coastfile), но\nназначение на worktree Conductor требует bind mount внутри контейнера.\n\n## Куда помещать указания для Coasts\n\nРассматривайте Conductor как отдельный harness для работы с Coasts:\n\n- поместите краткие правила Coast Runtime в `CLAUDE.md`\n- используйте скрипты Conductor Repository Settings для настройки или\n поведения запуска, которое действительно специфично для Conductor\n- не предполагавайте здесь поведение полных project command или project skill\n из Claude Code\n- если вы добавили команду, и она не появилась, полностью закройте и снова\n откройте Conductor перед следующим тестом\n- если этот репозиторий также использует другие harness, см.\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) и\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md), чтобы сохранить\n общий workflow `/coasts` в одном месте\n\n## Что делает Coasts\n\n- **Запуск** — `coast run ` создаёт новый инстанс Coast из последней сборки. Используйте `coast run -w `, чтобы за один шаг создать и назначить worktree Conductor. См. [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — При создании контейнера Coasts монтирует\n `~/conductor/workspaces/` в контейнер по пути\n `/host-external-wt/{index}`.\n- **Обнаружение** — `git worktree list --porcelain` ограничен репозиторием, поэтому отображаются только worktree, принадлежащие текущему проекту.\n- **Именование** — Worktree Conductor используют именованные ветки, поэтому\n они отображаются по имени ветки в UI и CLI Coasts (например,\n `scroll-to-bottom-btn`). Ветка может быть checkout'нута только в одной\n рабочей области Conductor одновременно.\n- **Назначение** — `coast assign` перемонтирует `/workspace` из пути внешнего bind mount.\n- **Синхронизация gitignored** — Выполняется в файловой системе хоста с абсолютными путями, работает без bind mount.\n- **Обнаружение orphan** — Git watcher рекурсивно сканирует внешние каталоги,\n фильтруя по указателям `.git` gitdir. Если Conductor архивирует или\n удаляет рабочую область, Coasts автоматически снимает назначение с инстанса.\n\n## Пример\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor (внешний, с bind mount; замените `my-app` на имя папки вашего репозитория)\n\n## Переменные окружения Conductor\n\n- Избегайте зависимости от специфичных для Conductor переменных окружения (например,\n `CONDUCTOR_PORT`, `CONDUCTOR_WORKSPACE_PATH`) для конфигурации времени\n выполнения внутри Coasts. Coasts независимо управляет портами, путями\n рабочих областей и обнаружением сервисов — используйте вместо этого Coastfile `[ports]` и `coast exec`.\n", - "harnesses/CURSOR.md": "# Cursor\n\n[Cursor](https://cursor.com/docs/agent/overview) может работать напрямую в вашей\nтекущей checkout-копии, а его функция Parallel Agents также может создавать git\nworktree в `~/.cursor/worktrees//`.\n\nДля документации о Coasts это означает, что есть два варианта настройки:\n\n- если вы просто используете Cursor в текущей checkout-копии, специальная\n запись `worktree_dir` для Cursor не требуется\n- если вы используете Cursor Parallel Agents, добавьте директорию worktree Cursor в\n `worktree_dir`, чтобы Coasts мог обнаруживать и назначать эти worktree\n\n## Настройка\n\n### Только текущая checkout-копия\n\nЕсли Cursor просто редактирует checkout-копию, которую вы уже открыли, Coasts не нужен\nникакой специальный путь к worktree для Cursor. Coasts будет рассматривать эту\ncheckout-копию как любой другой корень локального репозитория.\n\n### Cursor Parallel Agents\n\nЕсли вы используете Parallel Agents, добавьте `~/.cursor/worktrees/` в\n`worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nCursor хранит worktree каждого агента в этой директории, отдельной для проекта. Coasts\nраскрывает `~` во время выполнения и рассматривает путь как внешний, поэтому существующие\nинстансы нужно пересоздать, чтобы bind mount вступил в силу:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nСписок worktree обновляется сразу после изменения Coastfile, но\nназначение на worktree Cursor Parallel Agent требует внешнего bind mount\nвнутри контейнера.\n\n## Куда помещать рекомендации Coasts\n\n### `AGENTS.md` или `.cursor/rules/coast.md`\n\nПоместите сюда короткие, всегда активные правила Coast Runtime:\n\n- используйте `AGENTS.md`, если хотите максимально переносимые инструкции проекта\n- используйте `.cursor/rules/coast.md`, если хотите правила проекта в стиле Cursor и\n поддержку UI для настроек\n- не дублируйте один и тот же блок Coast Runtime в обоих местах, если только у вас нет\n для этого ясной причины\n\n### `.cursor/skills/coasts/SKILL.md` или общий `.agents/skills/coasts/SKILL.md`\n\nПоместите сюда переиспользуемый workflow `/coasts`:\n\n- для репозитория только под Cursor естественным местом будет `.cursor/skills/coasts/SKILL.md`\n- для репозитория с несколькими harness храните канонический skill в\n `.agents/skills/coasts/SKILL.md`; Cursor может загружать его напрямую\n- skill должен содержать реальный workflow `/coasts`: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout` и `coast ui`\n\n### `.cursor/commands/coasts.md`\n\nCursor также поддерживает команды проекта. Для документации о Coasts рассматривайте команды как\nнеобязательные:\n\n- добавляйте команду только если хотите явную точку входа `/coasts`\n- один из простых вариантов — сделать так, чтобы команда переиспользовала тот же skill\n- если вы дадите команде собственные отдельные инструкции, вам придется\n поддерживать вторую копию workflow\n\n### `.cursor/worktrees.json`\n\nИспользуйте `.cursor/worktrees.json` для собственной инициализации worktree в Cursor, а не для\nполитики Coasts:\n\n- устанавливать зависимости\n- копировать или создавать symlink для файлов `.env`\n- запускать миграции базы данных или другие одноразовые шаги инициализации\n\nНе переносите правила Coast Runtime или workflow Coast CLI в\n`.cursor/worktrees.json`.\n\n## Пример структуры\n\n### Только Cursor\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # optional\n.cursor/rules/coast.md # optional alternative to AGENTS.md\n.cursor/worktrees.json # optional, for Parallel Agents bootstrap\n```\n\n### Cursor плюс другие harness\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional\n```\n\n## Что делает Coasts\n\n- **Запуск** — `coast run ` создает новый инстанс Coast из последней сборки. Используйте `coast run -w `, чтобы создать и назначить worktree Cursor за один шаг. См. [Run](../concepts_and_terminology/RUN.md).\n- **Текущая checkout-копия** — Никакой специальной обработки Cursor не требуется, когда Cursor\n работает напрямую в открытом вами репозитории.\n- **Bind mount** — Для Parallel Agents Coasts монтирует\n `~/.cursor/worktrees/` в контейнер по пути\n `/host-external-wt/{index}`.\n- **Обнаружение** — `git worktree list --porcelain` по-прежнему ограничен репозиторием, поэтому Coasts\n показывает только те worktree Cursor, которые принадлежат текущему проекту.\n- **Именование** — Worktree Cursor Parallel Agent отображаются по именам своих веток в\n CLI и UI Coasts.\n- **Назначение** — `coast assign` перемонтирует `/workspace` из внешнего пути bind\n mount, когда выбран worktree Cursor.\n- **Синхронизация gitignored** — Продолжает работать в файловой системе хоста с абсолютными\n путями.\n- **Обнаружение orphan** — Если Cursor очищает старые worktree, Coasts может обнаружить\n отсутствующий gitdir и при необходимости снять их назначение.\n\n## Пример\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — worktree Claude Code\n- `~/.codex/worktrees/` — worktree Codex\n- `~/.cursor/worktrees/my-app/` — worktree Cursor Parallel Agent\n\n## Ограничения\n\n- Если вы не используете Cursor Parallel Agents, не добавляйте\n `~/.cursor/worktrees/` только потому, что редактируете в\n Cursor.\n- Держите правила Coast Runtime в одном всегда активном месте: `AGENTS.md` или\n `.cursor/rules/coast.md`. Дублирование в обоих местах ведет к расхождениям.\n- Держите переиспользуемый workflow `/coasts` в skill. `.cursor/worktrees.json` предназначен\n для инициализации Cursor, а не для политики Coasts.\n- Если один репозиторий используется совместно в Cursor, Codex, Claude Code или T3 Code, предпочитайте\n общую структуру из [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", + "harnesses/README.md": "# Harnesses\n\nКаждый harness создает git worktree в своем месте. В Coasts массив\n[`worktree_dir`](../coastfiles/WORKTREE_DIR.md) указывает, где их искать --\nвключая внешние пути, такие как `~/.codex/worktrees`, для которых требуются\nдополнительные bind mounts.\n\nУ каждого harness также есть свои соглашения для инструкций на уровне проекта, skills и commands. Матрица ниже показывает, что поддерживает каждый harness, чтобы вы знали, куда помещать указания для Coasts. На каждой странице описаны конфигурация Coastfile, рекомендуемая структура файлов и любые особенности, относящиеся именно к этому harness.\n\nЕсли один репозиторий используется из нескольких harness, см. [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n\n| Harness | Worktree location | Project instructions | Skills | Commands | Page |\n|---------|-------------------|----------------------|--------|----------|------|\n| OpenAI Codex | `~/.codex/worktrees` | `AGENTS.md` | `.agents/skills/` | Skills surface as `/` commands | [Codex](CODEX.md) |\n| Claude Code | `.claude/worktrees` | `CLAUDE.md` | `.claude/skills/` | `.claude/commands/` | [Claude Code](CLAUDE_CODE.md) |\n| Cursor | `~/.cursor/worktrees/` | `AGENTS.md` or `.cursor/rules/` | `.cursor/skills/` or `.agents/skills/` | `.cursor/commands/` | [Cursor](CURSOR.md) |\n| Conductor | `~/conductor/workspaces/` | `CLAUDE.md` | -- | -- | [Conductor](CONDUCTOR.md) |\n| T3 Code | `~/.t3/worktrees/` | `AGENTS.md` | `.agents/skills/` | -- | [T3 Code](T3_CODE.md) |\n| Shep | `~/.shep/repos/*/wt` | `CLAUDE.md` | `.agents/skills/` or `.claude/skills/` | -- | [Shep](SHEP.md) |\n\n## Skills vs Commands\n\nSkills и commands оба позволяют определить повторно используемый workflow `/coasts`. Вы можете использовать что-то одно или оба варианта, в зависимости от того, что поддерживает harness.\n\nЕсли ваш harness поддерживает commands и вам нужна явная точка входа `/coasts`,\nодин из простых вариантов — добавить command, который переиспользует skill.\nCommands явно вызываются по имени, поэтому вы точно знаете, когда запускается\nworkflow `/coasts`. Skills также могут автоматически загружаться агентом\nна основе контекста, что полезно, но означает, что у вас меньше контроля над тем,\nкогда подтягиваются инструкции.\n\nВы можете использовать оба варианта. Если так и делаете, пусть command\nпереиспользует skill вместо того, чтобы поддерживать отдельную копию workflow.\n\nЕсли harness поддерживает только skills (T3 Code), используйте skill. Если он не поддерживает\nни то ни другое (Conductor), поместите workflow `/coasts` прямо в файл\nинструкций проекта.\n", + "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n## Быстрая настройка\n\nТребуется [Coast CLI](../GETTING_STARTED.md). Скопируйте этот prompt в чат\nвашего агента, чтобы настроить Coasts автоматически:\n\n```prompt-copy\nclaude_code_setup_prompt.txt\n```\n\nВы также можете получить содержимое skill из CLI: `coast skills-prompt`.\n\nПосле настройки **запустите новую сессию Claude Code** — skills и изменения в\n`CLAUDE.md` загружаются при запуске сессии.\n\n---\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) создаёт\nworktree внутри проекта в `.claude/worktrees/`. Поскольку этот каталог\nнаходится внутри репозитория, Coasts может обнаруживать и назначать worktree\nClaude Code без какого-либо внешнего bind mount.\n\nClaude Code также является здесь harness с наиболее чётким разделением на три\nслоя для Coasts:\n\n- `CLAUDE.md` для коротких, всегда активных правил работы с Coasts\n- `.claude/skills/coasts/SKILL.md` для переиспользуемого workflow `/coasts`\n- `.claude/commands/coasts.md` только если вам нужен файл команды как\n дополнительная точка входа\n\n## Настройка\n\nДобавьте `.claude/worktrees` в `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\nПоскольку `.claude/worktrees` является путём относительно проекта, внешний bind mount\nне нужен.\n\n## Куда помещать руководство по Coasts\n\n### `CLAUDE.md`\n\nПоместите сюда правила для Coasts, которые должны применяться в каждой задаче.\nСделайте их короткими и практическими:\n\n- запускать `coast lookup` перед первой runtime-командой в сессии\n- использовать `coast exec` для тестов, сборок и сервисных команд\n- использовать `coast ps` и `coast logs` для обратной связи от runtime\n- спрашивать перед созданием или переназначением Coast, если соответствия не существует\n\n### `.claude/skills/coasts/SKILL.md`\n\nПоместите сюда переиспользуемый workflow `/coasts`. Это правильное место для\nпотока, который:\n\n1. запускает `coast lookup` и повторно использует подходящий Coast\n2. переключается на `coast ls`, когда соответствия нет\n3. предлагает `coast run`, `coast assign`, `coast unassign`, `coast checkout`, и\n `coast ui`\n4. использует CLI Coast напрямую как контракт, а не оборачивает его\n\nЕсли этот репозиторий также использует Codex, T3 Code или Cursor, см.\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) и храните канонический skill в\n`.agents/skills/coasts/`, а затем откройте к нему доступ из Claude Code.\n\n### `.claude/commands/coasts.md`\n\nClaude Code также поддерживает файлы команд проекта. Для документации о Coasts\nсчитайте это необязательным:\n\n- используйте это только если вам действительно нужен файл команды\n- один простой вариант — сделать так, чтобы команда переиспользовала тот же skill\n- если вы дадите команде собственные отдельные инструкции, вы берёте на себя\n поддержку второй копии workflow\n\n## Пример структуры\n\n### Только Claude Code\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\nЕсли этот репозиторий также использует Codex, T3 Code или Cursor, используйте общий шаблон из\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) вместо его дублирования здесь,\nпотому что дублирующиеся provider-specific инструкции становится всё труднее\nподдерживать синхронизированными каждый раз, когда вы добавляете ещё один harness.\n\n## Что делает Coasts\n\n- **Запуск** — `coast run ` создаёт новый экземпляр Coast из последней сборки. Используйте `coast run -w `, чтобы создать и назначить worktree Claude Code за один шаг. См. [Run](../concepts_and_terminology/RUN.md).\n- **Обнаружение** — Coasts читает `.claude/worktrees` как любой другой локальный\n каталог worktree.\n- **Именование** — worktree Claude Code используют то же поведение именования\n локальных worktree, что и другие worktree внутри репозитория в UI и CLI Coasts.\n- **Назначение** — `coast assign` может переключать `/workspace` на worktree Claude Code\n без какого-либо внешнего уровня bind-mount indirection.\n- **Синхронизация gitignored** — работает нормально, потому что worktree находятся внутри\n дерева репозитория.\n- **Обнаружение orphan** — если Claude Code удаляет worktree, Coasts может обнаружить\n отсутствующий gitdir и при необходимости снять назначение.\n\n## Пример\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — worktree Claude Code\n- `~/.codex/worktrees/` — worktree Codex, если вы также используете Codex в этом репозитории\n\n## Ограничения\n\n- Если вы дублируете один и тот же workflow `/coasts` в `CLAUDE.md`,\n `.claude/skills` и `.claude/commands`, эти копии будут расходиться. Держите\n `CLAUDE.md` коротким, а переиспользуемый workflow — в одном skill.\n- Если вы хотите, чтобы один репозиторий чисто работал в нескольких harness,\n предпочитайте общий шаблон из [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", + "harnesses/CODEX.md": "# Codex\n\n## Quick setup\n\nТребуется [Coast CLI](../GETTING_STARTED.md). Скопируйте этот промпт в чат\nвашего агента, чтобы настроить Coasts автоматически:\n\n```prompt-copy\ncodex_setup_prompt.txt\n```\n\nВы также можете получить содержимое skill из CLI: `coast skills-prompt`.\n\nПосле настройки **закройте и заново откройте Codex**, чтобы новый skill и\n`AGENTS.md` вступили в силу.\n\n---\n\n[Codex](https://developers.openai.com/codex/app/worktrees/) создаёт worktree в `$CODEX_HOME/worktrees` (обычно `~/.codex/worktrees`). Каждый worktree находится в каталоге с непрозрачным хешем, например `~/.codex/worktrees/a0db/project-name`, начинается с detached HEAD и автоматически очищается в соответствии с политикой хранения Codex.\n\nИз [документации Codex](https://developers.openai.com/codex/app/worktrees/):\n\n> Могу ли я управлять тем, где создаются worktree?\n> Пока нет. Codex создаёт worktree в `$CODEX_HOME/worktrees`, чтобы иметь возможность единообразно управлять ими.\n\nПоскольку эти worktree находятся вне корня проекта, Coasts требуется явная\nконфигурация, чтобы обнаруживать и монтировать их.\n\n## Setup\n\nДобавьте `~/.codex/worktrees` в `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nCoasts разворачивает `~` во время выполнения и рассматривает любой путь,\nначинающийся с `~/` или `/`, как внешний. Подробности см. в [Worktree\nDirectories](../coastfiles/WORKTREE_DIR.md).\n\nПосле изменения `worktree_dir` существующие инстансы необходимо **пересоздать**, чтобы bind mount вступил в силу:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nСписок worktree обновляется сразу (Coasts читает новый Coastfile), но\nназначение на worktree Codex требует bind mount внутри контейнера.\n\n## Where Coasts guidance goes\n\nДля работы с Coasts используйте файл инструкций проекта Codex и общую\nструктуру skills:\n\n- поместите краткие правила Coast Runtime в `AGENTS.md`\n- поместите переиспользуемый workflow `/coasts` в `.agents/skills/coasts/SKILL.md`\n- Codex показывает этот skill как команду `/coasts`\n- если вы используете метаданные, специфичные для Codex, храните их рядом со\n skill в `.agents/skills/coasts/agents/openai.yaml`\n- не создавайте отдельный файл команд проекта только ради документации о\n Coasts; skill — это переиспользуемая поверхность\n- если этот репозиторий также использует Cursor или Claude Code, храните\n канонический skill в `.agents/skills/` и публикуйте его оттуда. См.\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) и\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\nНапример, минимальный `.agents/skills/coasts/agents/openai.yaml` может\nвыглядеть так:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\nЭто делает skill видимым в Codex с более удобной меткой и превращает `/coasts`\nв явную команду. Добавляйте `dependencies.tools` только если skill также нужны\nMCP-серверы или другая настройка инструментов под управлением OpenAI.\n\n## What Coasts does\n\n- **Run** -- `coast run ` создаёт новый инстанс Coast из последней сборки. Используйте `coast run -w `, чтобы за один шаг создать и назначить worktree Codex. См. [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** -- При создании контейнера Coasts монтирует\n `~/.codex/worktrees` в контейнер по пути `/host-external-wt/{index}`.\n- **Discovery** -- `git worktree list --porcelain` привязан к репозиторию, поэтому отображаются только worktree Codex, принадлежащие текущему проекту, даже если каталог содержит worktree для множества проектов.\n- **Naming** -- Worktree с detached HEAD отображаются как их относительный путь внутри внешнего каталога (`a0db/my-app`, `eca7/my-app`). Worktree, основанные на ветках, отображаются по имени ветки.\n- **Assign** -- `coast assign` повторно монтирует `/workspace` из пути внешнего bind mount.\n- **Gitignored sync** -- Выполняется в файловой системе хоста с абсолютными путями, работает без bind mount.\n- **Orphan detection** -- Наблюдатель git рекурсивно сканирует внешние каталоги,\n фильтруя по указателям gitdir в `.git`. Если Codex удаляет\n worktree, Coasts автоматически снимает назначение с инстанса.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code (локально, без специальной обработки)\n- `~/.codex/worktrees/` -- Codex (внешний, с bind mount)\n\n## Limitations\n\n- Codex может очистить worktree в любой момент. Механизм обнаружения orphan в Coasts\n корректно это обрабатывает.\n", + "harnesses/CONDUCTOR.md": "# Conductor\n\n## Быстрая настройка\n\nТребуется [Coast CLI](../GETTING_STARTED.md). Скопируйте этот prompt в чат\nвашего агента, чтобы настроить Coasts автоматически:\n\n```prompt-copy\nconductor_setup_prompt.txt\n```\n\nВы также можете получить содержимое skill через CLI: `coast skills-prompt`.\n\n> **Важно:** Conductor запускает каждую сессию в изолированном git worktree.\n> Prompt настройки создаёт файлы, которые существуют только в текущем рабочем\n> пространстве — закоммитьте их и влейте в основную ветку, иначе они не будут\n> доступны в новых сессиях.\n\nПосле настройки **полностью закройте и заново откройте Conductor**, чтобы\nизменения вступили в силу. Если команда `/coasts` не появляется, снова\nзакройте и откройте Conductor.\n\n## Setup\n\nДобавьте `~/conductor/workspaces/` в `worktree_dir`. В отличие от Codex (который хранит все проекты в одном плоском каталоге), Conductor размещает worktree во вложенном подкаталоге для каждого проекта, поэтому путь должен включать имя проекта. В примере ниже `my-app` должно совпадать с фактическим именем папки вашего репозитория в `~/conductor/workspaces/`.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nConductor позволяет настраивать путь к рабочим областям для каждого репозитория, поэтому путь по умолчанию `~/conductor/workspaces` может не соответствовать вашей настройке. Проверьте настройки вашего репозитория Conductor, чтобы найти фактический путь, и скорректируйте его соответствующим образом — принцип одинаков независимо от того, где находится каталог.\n\nCoasts разворачивает `~` во время выполнения и считает любой путь, начинающийся с `~/` или `/`, внешним. Подробности см. в [Worktree Directories](../coastfiles/WORKTREE_DIR.md).\n\nПосле изменения `worktree_dir` существующие инстансы нужно **пересоздать**, чтобы bind mount вступил в силу:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nСписок worktree обновляется сразу (Coasts читает новый Coastfile), но\nназначение на worktree Conductor требует bind mount внутри контейнера.\n\n## Where Coasts guidance goes\n\nРассматривайте Conductor как отдельный harness для работы с Coasts:\n\n- поместите краткие правила Coast Runtime в `CLAUDE.md`\n- используйте скрипты Conductor Repository Settings для настройки или\n поведения запуска, которое действительно специфично для Conductor\n- не предполагавайте здесь поведение полных project command или project skill\n из Claude Code\n- если вы добавили команду, и она не появилась, полностью закройте и снова\n откройте Conductor перед следующим тестом\n- если этот репозиторий также использует другие harness, см.\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) и\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md), чтобы сохранить\n общий workflow `/coasts` в одном месте\n\n## What Coasts does\n\n- **Запуск** — `coast run ` создаёт новый инстанс Coast из последней сборки. Используйте `coast run -w `, чтобы за один шаг создать и назначить worktree Conductor. См. [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — При создании контейнера Coasts монтирует\n `~/conductor/workspaces/` в контейнер по пути\n `/host-external-wt/{index}`.\n- **Обнаружение** — `git worktree list --porcelain` ограничен репозиторием, поэтому отображаются только worktree, принадлежащие текущему проекту.\n- **Именование** — Worktree Conductor используют именованные ветки, поэтому\n они отображаются по имени ветки в UI и CLI Coasts (например,\n `scroll-to-bottom-btn`). Ветка может быть checkout'нута только в одной\n рабочей области Conductor одновременно.\n- **Назначение** — `coast assign` перемонтирует `/workspace` из пути внешнего bind mount.\n- **Синхронизация gitignored** — Выполняется в файловой системе хоста с абсолютными путями, работает без bind mount.\n- **Обнаружение orphan** — Git watcher рекурсивно сканирует внешние каталоги,\n фильтруя по указателям `.git` gitdir. Если Conductor архивирует или\n удаляет рабочую область, Coasts автоматически снимает назначение с инстанса.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor (внешний, с bind mount; замените `my-app` на имя папки вашего репозитория)\n\n## Conductor Env Vars\n\n- Избегайте зависимости от специфичных для Conductor переменных окружения (например,\n `CONDUCTOR_PORT`, `CONDUCTOR_WORKSPACE_PATH`) для конфигурации времени\n выполнения внутри Coasts. Coasts независимо управляет портами, путями\n рабочих областей и обнаружением сервисов — используйте вместо этого Coastfile `[ports]` и `coast exec`.\n", + "harnesses/CURSOR.md": "# Cursor\n\n## Быстрая настройка\n\nТребуется [Coast CLI](../GETTING_STARTED.md). Скопируйте этот prompt в чат\nвашего агента, чтобы настроить Coasts автоматически:\n\n```prompt-copy\ncursor_setup_prompt.txt\n```\n\nВы также можете получить содержимое skill из CLI: `coast skills-prompt`.\n\nПосле настройки **перезапустите Cursor**, чтобы изменения skill и правил вступили в силу.\n\n---\n\n[Cursor](https://cursor.com/docs/agent/overview) может работать напрямую в вашей\nтекущей checkout-копии, а его функция Parallel Agents также может создавать git\nworktree в `~/.cursor/worktrees//`.\n\nДля документации о Coasts это означает, что есть два варианта настройки:\n\n- если вы просто используете Cursor в текущей checkout-копии, специальная\n запись `worktree_dir` для Cursor не требуется\n- если вы используете Cursor Parallel Agents, добавьте директорию worktree Cursor в\n `worktree_dir`, чтобы Coasts мог обнаруживать и назначать эти worktree\n\n## Настройка\n\n### Только текущая checkout-копия\n\nЕсли Cursor просто редактирует checkout-копию, которую вы уже открыли, Coasts не нужен\nникакой специальный путь к worktree для Cursor. Coasts будет рассматривать эту\ncheckout-копию как любой другой корень локального репозитория.\n\n### Cursor Parallel Agents\n\nЕсли вы используете Parallel Agents, добавьте `~/.cursor/worktrees/` в\n`worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nCursor хранит worktree каждого агента в этой директории, отдельной для проекта. Coasts\nраскрывает `~` во время выполнения и рассматривает путь как внешний, поэтому существующие\nинстансы нужно пересоздать, чтобы bind mount вступил в силу:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nСписок worktree обновляется сразу после изменения Coastfile, но\nназначение на worktree Cursor Parallel Agent требует внешнего bind mount\nвнутри контейнера.\n\n## Куда помещать рекомендации Coasts\n\n### `AGENTS.md` или `.cursor/rules/coast.md`\n\nПоместите сюда короткие, всегда активные правила Coast Runtime:\n\n- используйте `AGENTS.md`, если хотите максимально переносимые инструкции проекта\n- используйте `.cursor/rules/coast.md`, если хотите правила проекта в стиле Cursor и\n поддержку UI для настроек\n- не дублируйте один и тот же блок Coast Runtime в обоих местах, если только у вас нет\n для этого ясной причины\n\n### `.cursor/skills/coasts/SKILL.md` или общий `.agents/skills/coasts/SKILL.md`\n\nПоместите сюда переиспользуемый workflow `/coasts`:\n\n- для репозитория только под Cursor естественным местом будет `.cursor/skills/coasts/SKILL.md`\n- для репозитория с несколькими harness храните канонический skill в\n `.agents/skills/coasts/SKILL.md`; Cursor может загружать его напрямую\n- skill должен содержать реальный workflow `/coasts`: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout` и `coast ui`\n\n### `.cursor/commands/coasts.md`\n\nCursor также поддерживает команды проекта. Для документации о Coasts рассматривайте команды как\nнеобязательные:\n\n- добавляйте команду только если хотите явную точку входа `/coasts`\n- один из простых вариантов — сделать так, чтобы команда переиспользовала тот же skill\n- если вы дадите команде собственные отдельные инструкции, вам придется\n поддерживать вторую копию workflow\n\n### `.cursor/worktrees.json`\n\nИспользуйте `.cursor/worktrees.json` для собственной инициализации worktree в Cursor, а не для\nполитики Coasts:\n\n- устанавливать зависимости\n- копировать или создавать symlink для файлов `.env`\n- запускать миграции базы данных или другие одноразовые шаги инициализации\n\nНе переносите правила Coast Runtime или workflow Coast CLI в\n`.cursor/worktrees.json`.\n\n## Пример структуры\n\n### Только Cursor\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # optional\n.cursor/rules/coast.md # optional alternative to AGENTS.md\n.cursor/worktrees.json # optional, for Parallel Agents bootstrap\n```\n\n### Cursor плюс другие harness\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional\n```\n\n## Что делает Coasts\n\n- **Запуск** — `coast run ` создает новый инстанс Coast из последней сборки. Используйте `coast run -w `, чтобы создать и назначить worktree Cursor за один шаг. См. [Run](../concepts_and_terminology/RUN.md).\n- **Текущая checkout-копия** — Никакой специальной обработки Cursor не требуется, когда Cursor\n работает напрямую в открытом вами репозитории.\n- **Bind mount** — Для Parallel Agents Coasts монтирует\n `~/.cursor/worktrees/` в контейнер по пути\n `/host-external-wt/{index}`.\n- **Обнаружение** — `git worktree list --porcelain` по-прежнему ограничен репозиторием, поэтому Coasts\n показывает только те worktree Cursor, которые принадлежат текущему проекту.\n- **Именование** — Worktree Cursor Parallel Agent отображаются по именам своих веток в\n CLI и UI Coasts.\n- **Назначение** — `coast assign` перемонтирует `/workspace` из внешнего пути bind\n mount, когда выбран worktree Cursor.\n- **Синхронизация gitignored** — Продолжает работать в файловой системе хоста с абсолютными\n путями.\n- **Обнаружение orphan** — Если Cursor очищает старые worktree, Coasts может обнаружить\n отсутствующий gitdir и при необходимости снять их назначение.\n\n## Пример\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — worktree Claude Code\n- `~/.codex/worktrees/` — worktree Codex\n- `~/.cursor/worktrees/my-app/` — worktree Cursor Parallel Agent\n\n## Ограничения\n\n- Если вы не используете Cursor Parallel Agents, не добавляйте\n `~/.cursor/worktrees/` только потому, что редактируете в\n Cursor.\n- Держите правила Coast Runtime в одном всегда активном месте: `AGENTS.md` или\n `.cursor/rules/coast.md`. Дублирование в обоих местах ведет к расхождениям.\n- Держите переиспользуемый workflow `/coasts` в skill. `.cursor/worktrees.json` предназначен\n для инициализации Cursor, а не для политики Coasts.\n- Если один репозиторий используется совместно в Cursor, Codex, Claude Code или T3 Code, предпочитайте\n общую структуру из [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", "harnesses/MULTIPLE_HARNESSES.md": "# Несколько harness-ов\n\nЕсли один репозиторий используется более чем из одного harness-а, один из\nспособов централизовать настройку Coasts — хранить общий workflow `/coasts` в\nодном месте, а специфичные для harness-а always-on rules — в файлах каждого\nharness-а.\n\n## Рекомендуемая структура\n\n```text\nAGENTS.md\nCLAUDE.md\n.cursor/rules/coast.md # optional Cursor-native always-on rules\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional, thin, harness-specific\n.claude/commands/coasts.md # optional, thin, harness-specific\n```\n\nИспользуйте эту структуру следующим образом:\n\n- `AGENTS.md` — короткие always-on rules для работы с Coasts в Codex и T3\n Code\n- `.cursor/rules/coast.md` — необязательные Cursor-native always-on rules\n- `CLAUDE.md` — короткие always-on rules для работы с Coasts в Claude Code\n и Conductor\n- `.agents/skills/coasts/SKILL.md` — канонический переиспользуемый workflow `/coasts`\n- `.agents/skills/coasts/agents/openai.yaml` — необязательные метаданные Codex/OpenAI\n- `.claude/skills/coasts` — зеркало или symlink для Claude, когда Claude Code\n также нужен тот же skill\n- `.cursor/commands/coasts.md` — необязательный файл команды Cursor; один из\n простых вариантов — переиспользовать тот же skill\n- `.claude/commands/coasts.md` — необязательный явный файл команды; один из\n простых вариантов — переиспользовать тот же skill\n\n## Пошагово\n\n1. Поместите правила Coast Runtime в always-on instruction files.\n - `AGENTS.md`, `CLAUDE.md` или `.cursor/rules/coast.md` должны отвечать за\n правила для \"каждой задачи\": сначала запускать `coast lookup`,\n использовать `coast exec`, читать логи через `coast logs`, спрашивать\n перед `coast assign` или `coast run`, если совпадения нет.\n2. Создайте один канонический skill для Coasts.\n - Поместите переиспользуемый workflow `/coasts` в `.agents/skills/coasts/SKILL.md`.\n - Используйте Coast CLI напрямую внутри этого skill: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout` и `coast ui`.\n3. Показывайте этот skill только там, где harness-у нужен другой путь.\n - Codex, T3 Code и Cursor могут использовать `.agents/skills/` напрямую.\n - Claude Code нужен `.claude/skills/`, поэтому отзеркальте или создайте\n symlink на канонический skill в этом расположении.\n4. Добавляйте файл команды только если вам нужна явная точка входа `/coasts`.\n - Если вы создаёте `.claude/commands/coasts.md` или\n `.cursor/commands/coasts.md`, один из простых вариантов — чтобы команда\n переиспользовала тот же skill.\n - Если вы даёте команде собственные отдельные инструкции, вы берёте на себя\n поддержку второй копии workflow.\n5. Храните специфичную для Conductor настройку в Conductor, а не в skill.\n - Используйте скрипты Conductor Repository Settings для bootstrap или\n поведения при запуске, которое относится к самому Conductor.\n - Храните политику Coasts и использование `coast` CLI в `CLAUDE.md` и\n общем skill.\n\n## Конкретный пример `/coasts`\n\nХороший общий skill `coasts` должен выполнять три задачи:\n\n1. `Use Existing Coast`\n - запустить `coast lookup`\n - если совпадение существует, использовать `coast exec`, `coast ps` и `coast logs`\n2. `Manage Assignment`\n - запустить `coast ls`\n - предложить `coast run`, `coast assign`, `coast unassign` или\n `coast checkout`\n - спрашивать перед повторным использованием или нарушением работы\n существующего slot\n3. `Open UI`\n - запустить `coast ui`\n\nЭто правильное место для workflow `/coasts`. Файлы always-on должны\nсодержать только короткие правила, которые должны применяться даже если skill\nникогда не вызывается.\n\n## Шаблон symlink\n\nЕсли вы хотите, чтобы Claude Code переиспользовал тот же skill, что и Codex,\nT3 Code или Cursor, один из вариантов — symlink:\n\n```bash\nmkdir -p .claude/skills\nln -s ../../.agents/skills/coasts .claude/skills/coasts\n```\n\nЗакоммиченное зеркало тоже подходит, если ваша команда предпочитает не\nиспользовать symlink. Главная цель — просто избежать ненужного расхождения\nмежду копиями.\n\n## Предостережения для конкретных harness-ов\n\n- Claude Code: project skills и необязательные project commands оба допустимы, но\n держите логику в skill.\n- Cursor: используйте `AGENTS.md` или `.cursor/rules/coast.md` для коротких\n правил Coast Runtime, используйте skill для переиспользуемого workflow и\n оставляйте `.cursor/commands` необязательными.\n- Conductor: в первую очередь рассматривайте его как `CLAUDE.md` плюс скрипты\n и настройки Conductor.\n Если вы добавили команду и она не появляется, полностью закройте и снова\n откройте приложение, прежде чем проверять ещё раз.\n- T3 Code: это самый тонкий surface harness-а здесь. Используйте шаблон в\n стиле Codex: `AGENTS.md` плюс `.agents/skills`, и не придумывайте отдельную\n T3-специфичную структуру команд для документации о Coasts.\n- Codex: держите `AGENTS.md` коротким и поместите переиспользуемый workflow в\n `.agents/skills`.\n", - "harnesses/T3_CODE.md": "# T3 Code\n\n[T3 Code](https://github.com/pingdotgg/t3code) создаёт git worktree в\n`~/.t3/worktrees//`, переключённые на именованные ветки.\n\nВ T3 Code поместите всегда активные правила Coast Runtime в `AGENTS.md`, а\nпереиспользуемый workflow `/coasts` — в `.agents/skills/coasts/SKILL.md`.\n\nПоскольку эти worktree находятся вне корня проекта, Coasts требуется явная\nконфигурация, чтобы обнаруживать и монтировать их.\n\n## Setup\n\nДобавьте `~/.t3/worktrees/` в `worktree_dir`. T3 Code размещает worktree во вложенном подкаталоге для каждого проекта, поэтому путь должен включать имя проекта. В примере ниже `my-app` должно совпадать с фактическим именем папки в `~/.t3/worktrees/` для вашего репозитория.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nCoasts разворачивает `~` во время выполнения и рассматривает любой путь,\nначинающийся с `~/` или `/`, как внешний. Подробности см. в [Worktree Directories](../coastfiles/WORKTREE_DIR.md).\n\nПосле изменения `worktree_dir` существующие инстансы необходимо **пересоздать**, чтобы bind mount вступил в силу:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nСписок worktree обновляется сразу (Coasts считывает новый Coastfile), но\nназначение на worktree T3 Code требует bind mount внутри контейнера.\n\n## Where Coasts guidance goes\n\nДля T3 Code используйте такую структуру:\n\n- поместите краткие правила Coast Runtime в `AGENTS.md`\n- поместите переиспользуемый workflow `/coasts` в `.agents/skills/coasts/SKILL.md`\n- не добавляйте отдельный слой команд проекта или slash-команд, специфичный\n для T3, для Coasts\n- если этот репозиторий использует несколько harness, см.\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) и\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\n## What Coasts does\n\n- **Run** — `coast run ` создаёт новый инстанс Coast из последней сборки. Используйте `coast run -w `, чтобы за один шаг создать worktree T3 Code и назначить его. См. [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — При создании контейнера Coasts монтирует\n `~/.t3/worktrees/` в контейнер по пути\n `/host-external-wt/{index}`.\n- **Discovery** — `git worktree list --porcelain` ограничен репозиторием, поэтому отображаются только worktree, принадлежащие текущему проекту.\n- **Naming** — Worktree T3 Code используют именованные ветки, поэтому они отображаются в UI и CLI Coasts по имени ветки.\n- **Assign** — `coast assign` перемонтирует `/workspace` из внешнего пути bind mount.\n- **Gitignored sync** — Выполняется в файловой системе хоста с абсолютными путями, работает без bind mount.\n- **Orphan detection** — Git watcher рекурсивно сканирует внешние директории,\n фильтруя по указателям gitdir в `.git`. Если T3 Code удаляет рабочее\n пространство, Coasts автоматически снимает назначение с инстанса.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code (локальные, без специальной обработки)\n- `~/.codex/worktrees/` — Codex (внешние, с bind mount)\n- `~/.t3/worktrees/my-app/` — T3 Code (внешние, с bind mount; замените `my-app` именем папки вашего репозитория)\n\n## Limitations\n\n- Не полагайтесь на специфичные для T3 Code переменные окружения для\n конфигурации времени выполнения внутри Coasts. Coasts независимо управляет портами, путями рабочих пространств и\n обнаружением сервисов — вместо этого используйте Coastfile `[ports]` и `coast exec`.\n", + "harnesses/SHEP.md": "# Shep\n\n## Быстрая настройка\n\nТребуется [Coast CLI](../GETTING_STARTED.md). Скопируйте этот промпт в чат\nвашего агента, чтобы настроить Coasts автоматически:\n\n```prompt-copy\nshep_setup_prompt.txt\n```\n\nВы также можете получить содержимое навыка из CLI: `coast skills-prompt`.\n\nПосле настройки **закройте и снова откройте редактор**, чтобы новый навык и\nинструкции проекта вступили в силу.\n\n---\n\n[Shep](https://shep-ai.github.io/cli/) создаёт worktree в `~/.shep/repos/{hash}/wt/{branch-slug}`. Хеш — это первые 16 шестнадцатеричных символов SHA-256 от абсолютного пути репозитория, поэтому он детерминирован для каждого репозитория, но непрозрачен. Все worktree для данного репозитория используют один и тот же хеш и различаются по подкаталогу `wt/{branch-slug}`.\n\nВ CLI Shep команда `shep feat show ` выводит путь к worktree, а\n`ls ~/.shep/repos` показывает каталоги хешей для каждого репозитория.\n\nПоскольку хеш различается для каждого репозитория, Coasts использует **glob-шаблон** для обнаружения\nworktree Shep без необходимости жёстко задавать хеш пользователем.\n\n## Настройка\n\nДобавьте `~/.shep/repos/*/wt` в `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n`*` соответствует каталогу хеша для каждого репозитория. Во время выполнения Coasts разворачивает glob,\nнаходит соответствующий каталог (например, `~/.shep/repos/a21f0cda9ab9d456/wt`) и\nмонтирует его в контейнер через bind mount. Подробности о glob-шаблонах см. в\n[Worktree Directories](../coastfiles/WORKTREE_DIR.md).\n\nПосле изменения `worktree_dir` существующие инстансы необходимо **пересоздать**, чтобы bind mount вступил в силу:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nСписок worktree обновляется сразу (Coasts читает новый Coastfile), но\nназначение на worktree Shep требует bind mount внутри контейнера.\n\n## Куда помещать рекомендации Coasts\n\nShep внутри использует Claude Code, поэтому следуйте соглашениям Claude Code:\n\n- размещайте короткие правила Coast Runtime в `CLAUDE.md`\n- размещайте переиспользуемый workflow `/coasts` в `.claude/skills/coasts/SKILL.md` или\n в общем `.agents/skills/coasts/SKILL.md`\n- если этот репозиторий также использует другие harness, см.\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) и\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)\n\n## Что делает Coasts\n\n- **Run** -- `coast run ` создаёт новый инстанс Coast из последней сборки. Используйте `coast run -w `, чтобы создать и назначить worktree Shep за один шаг. См. [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** -- При создании контейнера Coasts разрешает glob\n `~/.shep/repos/*/wt` и монтирует каждый совпавший каталог в контейнер по пути\n `/host-external-wt/{index}`.\n- **Discovery** -- `git worktree list --porcelain` ограничен репозиторием, поэтому\n отображаются только worktree, принадлежащие текущему проекту.\n- **Naming** -- Worktree Shep используют именованные ветки, поэтому они отображаются по имени ветки\n в UI и CLI Coasts (например, `feat-green-background`).\n- **Assign** -- `coast assign` перемонтирует `/workspace` из пути внешнего bind mount.\n- **Gitignored sync** -- Выполняется в файловой системе хоста с абсолютными путями, работает без bind mount.\n- **Orphan detection** -- Git watcher рекурсивно сканирует внешние каталоги,\n фильтруя по указателям gitdir в `.git`. Если Shep удаляет\n worktree, Coasts автоматически снимает назначение с инстанса.\n\n## Пример\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/.shep/repos/*/wt` -- Shep (внешний, подключается через bind mount с помощью разворачивания glob)\n\n## Структура путей Shep\n\n```\n~/.shep/repos/\n {sha256-of-repo-path-first-16-chars}/\n wt/\n {branch-slug}/ <-- git worktree\n {branch-slug}/\n```\n\nКлючевые моменты:\n- Один и тот же репозиторий = один и тот же хеш каждый раз (детерминированный, не случайный)\n- Разные репозитории = разные хеши\n- Разделители пути нормализуются к `/` перед хешированием\n- Хеш можно узнать через `shep feat show ` или `ls ~/.shep/repos`\n", + "harnesses/T3_CODE.md": "# T3 Code\n\n## Quick setup\n\nТребуется [Coast CLI](../GETTING_STARTED.md). Скопируйте этот prompt в чат\nвашего агента, чтобы автоматически настроить Coasts:\n\n```prompt-copy\nt3_code_setup_prompt.txt\n```\n\nВы также можете получить содержимое skill из CLI: `coast skills-prompt`.\n\nПосле настройки **перезапустите T3 Code**, чтобы изменения skill и правил вступили в силу.\n\n**Примечание:** T3 Code может ещё не загружать skills уровня проекта из `.agents/skills/` или\n`.claude/skills/`. Prompt для настройки также помещает skill в\n`~/.codex/skills/coasts/`, чтобы он был доступен глобально для провайдера Codex.\nПравила Coast Runtime в `AGENTS.md` и `CLAUDE.md` по-прежнему применяются к каждой\nзадаче в любом случае.\n\n---\n\n[T3 Code](https://github.com/pingdotgg/t3code) создаёт git worktree в\n`~/.t3/worktrees//`, переключённые на именованные ветки.\n\nT3 Code является обёрткой над Codex, поэтому использует `AGENTS.md` для\nвсегда активных правил и `.agents/skills/coasts/SKILL.md` для\nпереиспользуемого workflow `/coasts`.\n\nПоскольку эти worktree находятся вне корня проекта, Coasts требуется явная\nконфигурация, чтобы обнаруживать и монтировать их.\n\n## Setup\n\nДобавьте `~/.t3/worktrees/` в `worktree_dir`. T3 Code размещает worktree во вложенном подкаталоге для каждого проекта, поэтому путь должен включать имя проекта. В примере ниже `my-app` должно совпадать с фактическим именем папки в `~/.t3/worktrees/` для вашего репозитория.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nCoasts разворачивает `~` во время выполнения и рассматривает любой путь,\nначинающийся с `~/` или `/`, как внешний. Подробности см. в [Worktree Directories](../coastfiles/WORKTREE_DIR.md).\n\nПосле изменения `worktree_dir` существующие инстансы необходимо **пересоздать**, чтобы bind mount вступил в силу:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nСписок worktree обновляется сразу (Coasts считывает новый Coastfile), но\nназначение на worktree T3 Code требует bind mount внутри контейнера.\n\n## Where Coasts guidance goes\n\nДля T3 Code используйте такую структуру:\n\n- поместите краткие правила Coast Runtime в `AGENTS.md`\n- поместите переиспользуемый workflow `/coasts` в `.agents/skills/coasts/SKILL.md`\n- не добавляйте отдельный слой команд проекта или slash-команд, специфичный\n для T3, для Coasts\n- если этот репозиторий использует несколько harness, см.\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) и\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\n## What Coasts does\n\n- **Run** — `coast run ` создаёт новый инстанс Coast из последней сборки. Используйте `coast run -w `, чтобы за один шаг создать worktree T3 Code и назначить его. См. [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — При создании контейнера Coasts монтирует\n `~/.t3/worktrees/` в контейнер по пути\n `/host-external-wt/{index}`.\n- **Discovery** — `git worktree list --porcelain` ограничен репозиторием, поэтому отображаются только worktree, принадлежащие текущему проекту.\n- **Naming** — Worktree T3 Code используют именованные ветки, поэтому они отображаются в UI и CLI Coasts по имени ветки.\n- **Assign** — `coast assign` перемонтирует `/workspace` из внешнего пути bind mount.\n- **Gitignored sync** — Выполняется в файловой системе хоста с абсолютными путями, работает без bind mount.\n- **Orphan detection** — Git watcher рекурсивно сканирует внешние директории,\n фильтруя по указателям gitdir в `.git`. Если T3 Code удаляет рабочее\n пространство, Coasts автоматически снимает назначение с инстанса.\n\n## Example\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code (локальные, без специальной обработки)\n- `~/.codex/worktrees/` — Codex (внешние, с bind mount)\n- `~/.t3/worktrees/my-app/` — T3 Code (внешние, с bind mount; замените `my-app` именем папки вашего репозитория)\n\n## Limitations\n\n- Не полагайтесь на специфичные для T3 Code переменные окружения для\n конфигурации времени выполнения внутри Coasts. Coasts независимо управляет портами, путями рабочих пространств и\n обнаружением сервисов — вместо этого используйте Coastfile `[ports]` и `coast exec`.\n", + "harnesses/claude_code_setup_prompt.txt": "Вы настраиваете навык Coasts для Claude Code в этом проекте. Выполняйте все\nкоманды из корня проекта.\n\n## Шаг 1: Проверьте наличие Coast CLI\n\nВыполните эту команду:\n\n coast --version\n\nЕсли команда `coast` не найдена, остановитесь здесь и сообщите пользователю:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nНе продолжайте, пока CLI не станет доступен.\n\n## Шаг 2: Получите содержимое навыка\n\nВыполните эту команду:\n\n coast skills-prompt\n\nВывод состоит из двух частей:\n\n- **Правила Coasts Runtime** — всё от начала до (но не включая) строки, которая начинается с `---`\n- **Навык Coasts** — всё, начиная с блока frontmatter `---` и далее (включая строки `---` и всё после них)\n\nСохраните обе части для следующих шагов.\n\n## Шаг 3: Спросите пользователя\n\nСпросите пользователя: следует ли настроить это **глобально** (доступно в каждом проекте на этой машине) или **только для этого проекта**?\n\n## Шаг 4: Разместите файлы\n\nЕсли целевой файл уже существует, добавьте раздел Coast Runtime в конец вместо перезаписи — но сначала проверьте, присутствует ли уже раздел `# Coast Runtime`, и если да, пропустите этот шаг.\n\n**Глобальная настройка:**\n- Добавьте правила Coast Runtime в `~/.claude/CLAUDE.md`\n- Запишите навык Coasts в `~/.claude/skills/coasts/SKILL.md`\n\n**Настройка проекта:**\n- Добавьте правила Coast Runtime в `CLAUDE.md` в корне проекта\n- Запишите навык Coasts в `.claude/skills/coasts/SKILL.md`\n\n## Шаг 5: Обновите Coastfile\n\nПрочитайте `Coastfile` в корне проекта. Посмотрите на поле `worktree_dir` в\nразделе `[coast]`.\n\nЕсли `.claude/worktrees` **ещё не** указан в `worktree_dir`:\n\n- Если `worktree_dir` — это одна строка, преобразуйте её в массив и добавьте\n `.claude/worktrees`. Например, `worktree_dir = \".worktrees\"` становится\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]`.\n- Если `worktree_dir` уже является массивом, добавьте в него `.claude/worktrees`.\n- Если `worktree_dir` вообще отсутствует, добавьте\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]`.\n\nЭто относительный путь (внутри корня проекта), поэтому пересоздание контейнера\nне требуется — изменения немедленно вступают в силу для отображения worktree.\n\n## Шаг 6: Подтвердите\n\nПосле размещения файлов покажите пользователю сводку о том, что было создано и где.\n\nСообщите пользователю: **Начните новую сессию Claude Code**, чтобы изменения\nв навыке и CLAUDE.md вступили в силу.\n", + "harnesses/codex_setup_prompt.txt": "Вы настраиваете навык Coasts для OpenAI Codex в этом проекте. Выполняйте все\nкоманды из корня проекта.\n\n## Шаг 1: Проверьте наличие Coast CLI\n\nВыполните эту команду:\n\n coast --version\n\nЕсли команда `coast` не найдена, остановитесь здесь и сообщите пользователю:\n\n \"Coast CLI не установлен. Сначала установите его: https://coasts.dev/docs/getting-started\"\n\nНе продолжайте, пока CLI не станет доступен.\n\n## Шаг 2: Получите содержимое навыка\n\nВыполните эту команду:\n\n coast skills-prompt\n\nВывод состоит из двух частей:\n\n- **Правила Coast Runtime** — всё от начала до строки, которая начинается с `---` (но не включая её)\n- **Навык Coasts** — всё, начиная с блока frontmatter `---` и далее (включая строки `---` и всё после них)\n\nСохраните обе части для следующих шагов ниже.\n\n## Шаг 3: Разместите файлы\n\nНастройка Codex всегда выполняется на уровне проекта. Если целевой файл уже существует, добавьте раздел Coast Runtime вместо перезаписи — но сначала проверьте, присутствует ли уже раздел `# Coast Runtime`, и в таком случае пропустите.\n\n- Добавьте правила Coast Runtime в `AGENTS.md` в корне проекта\n- Запишите навык Coasts в `.agents/skills/coasts/SKILL.md`\n- Создайте `.agents/skills/coasts/agents/openai.yaml` со следующим содержимым:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## Шаг 4: Обновите Coastfile\n\nПрочитайте `Coastfile` в корне проекта. Посмотрите на поле `worktree_dir` в\nразделе `[coast]`.\n\nЕсли `~/.codex/worktrees` **ещё не** указан в `worktree_dir`:\n\n- Если `worktree_dir` — это одиночная строка, преобразуйте её в массив и добавьте\n `~/.codex/worktrees`. Например, `worktree_dir = \".worktrees\"` становится\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]`.\n- Если `worktree_dir` уже является массивом, добавьте в него `~/.codex/worktrees`.\n- Если `worktree_dir` вообще отсутствует, добавьте\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]`.\n\nЭто внешний путь, поэтому, если экземпляр Coast уже запущен для этого\nпроекта, его необходимо пересоздать с помощью `coast run`, чтобы новое bind-монтирование\nвступило в силу. Сообщите об этом пользователю.\n\n## Шаг 5: Подтвердите\n\nПосле размещения файлов покажите пользователю сводку о том, что было создано и где.\n\nСообщите пользователю: **Закройте и снова откройте Codex**, чтобы изменения в навыке и AGENTS.md\nвступили в силу.\n", + "harnesses/conductor_setup_prompt.txt": "Вы настраиваете навык Coasts для Conductor в этом проекте. Запускайте все\nкоманды из корня проекта.\n\n## Шаг 1: Проверка наличия Coast CLI\n\nВыполните эту команду:\n\n coast --version\n\nЕсли команда `coast` не найдена, остановитесь здесь и сообщите пользователю:\n\n \"Coast CLI не установлен. Сначала установите его: https://coasts.dev/docs/getting-started\"\n\nНе продолжайте, пока CLI не станет доступен.\n\n## Шаг 2: Получение содержимого навыка\n\nВыполните эту команду:\n\n coast skills-prompt\n\nВывод состоит из двух частей:\n\n- **Правила Coast Runtime** — всё от начала до строки, начинающейся с `---` (но не включая её)\n- **Навык Coasts** — всё, начиная с блока frontmatter `---` и далее (включая строки `---` и всё после них)\n\nСохраните обе части для следующих шагов.\n\n## Шаг 3: Спросите пользователя\n\nСпросите пользователя: каких провайдеров вы используете в Conductor?\n\n- **Claude** (Anthropic)\n- **Codex** (OpenAI)\n- **Оба**\n- **Другой** — если пользователь называет другого провайдера, выполните\n `coast docs --path SKILLS_FOR_HOST_AGENTS.md` и\n `coast docs --path harnesses/README.md`, чтобы определить, где этот провайдер\n ожидает инструкции проекта и навыки, затем следуйте тому же шаблону\n\n## Шаг 4: Разместите файлы\n\nНастройка Conductor всегда выполняется на уровне проекта. Если целевой файл уже существует, добавьте\nраздел Coast Runtime вместо перезаписи — но сначала проверьте, есть ли уже\nраздел `# Coast Runtime`, и если есть, пропустите.\n\n**Если пользователь выбрал Claude (или оба варианта):**\n- Добавьте правила Coast Runtime в `CLAUDE.md` в корне проекта\n- Запишите навык Coasts в `.claude/skills/coasts/SKILL.md`\n\n**Если пользователь выбрал Codex (или оба варианта):**\n- Добавьте правила Coast Runtime в `AGENTS.md` в корне проекта\n- Запишите навык Coasts в `.agents/skills/coasts/SKILL.md`\n- Создайте `.agents/skills/coasts/agents/openai.yaml` со следующим содержимым:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## Шаг 5: Подтверждение\n\nПосле размещения файлов покажите пользователю сводку того, что было создано и где.\n\nСообщите пользователю: **Полностью закройте и заново откройте Conductor**, чтобы изменения вступили в силу.\nЕсли команда `/coasts` не появляется сразу, закройте и откройте приложение ещё раз.\n\n## Шаг 6: Обновите Coastfile\n\nПрочитайте файл `Coastfile` в корне проекта. Посмотрите на поле `worktree_dir` в\nразделе `[coast]`. Также прочитайте поле `name` — оно понадобится для построения\nпути к worktree.\n\nКаталог worktree для Conductor: `~/conductor/workspaces/`, где\n`` — это значение поля `name` в Coastfile.\n\nЕсли этот путь **ещё не** указан в `worktree_dir`:\n\n- Если `worktree_dir` — это одна строка, преобразуйте её в массив и добавьте\n путь Conductor. Например, `worktree_dir = \".worktrees\"` становится\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]`.\n- Если `worktree_dir` уже является массивом, добавьте в него путь Conductor.\n- Если `worktree_dir` вообще отсутствует, добавьте\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/\"]`, используя\n фактическое имя проекта.\n\nЭто внешний путь, поэтому, если экземпляр Coast уже запущен для этого\nпроекта, его нужно пересоздать с помощью `coast run`, чтобы новый bind mount\nвступил в силу. Сообщите об этом пользователю.\n\n## Шаг 7: Закоммитьте новые файлы\n\nConductor запускает каждую сессию в изолированном git worktree. Незакоммиченные файлы\nне будут переноситься в новые сессии. Закоммитьте только что созданные файлы,\nчтобы они были доступны в каждом будущем рабочем пространстве:\n\n git add CLAUDE.md .claude/ AGENTS.md .agents/ 2>/dev/null; git status\n\nПокажите пользователю, какие файлы добавлены в staging, и попросите подтвердить перед коммитом.\nИспользуйте сообщение коммита вроде `[dh] feat: add Coasts skill for Conductor`.\n", + "harnesses/cursor_setup_prompt.txt": "Вы настраиваете навык Coasts для Cursor в этом проекте. Выполняйте все\nкоманды из корня проекта.\n\n## Шаг 1: Проверьте наличие Coast CLI\n\nВыполните эту команду:\n\n coast --version\n\nЕсли команда `coast` не найдена, остановитесь здесь и сообщите пользователю:\n\n \"Coast CLI не установлен. Сначала установите его: https://coasts.dev/docs/getting-started\"\n\nНе продолжайте, пока CLI не станет доступен.\n\n## Шаг 2: Получите содержимое навыка\n\nВыполните эту команду:\n\n coast skills-prompt\n\nВывод состоит из двух частей:\n\n- **Правила Coast Runtime** — всё от начала и до (но не включая) строки, которая начинается с `---`\n- **Навык Coasts** — всё от блока frontmatter `---` и далее (включая строки `---` и всё после них)\n\nСохраните обе части для следующих шагов.\n\n## Шаг 3: Спросите пользователя\n\nСпросите пользователя: следует ли мне настроить это **глобально** (доступно в каждом проекте на этой машине) или **только для этого проекта**?\n\n## Шаг 4: Разместите файлы\n\nЕсли целевой файл уже существует, добавьте раздел Coast Runtime в конец вместо перезаписи — но сначала проверьте, присутствует ли уже раздел `# Coast Runtime`, и если да, пропустите этот шаг.\n\n**Глобальная настройка:**\n- Добавьте правила Coast Runtime в глобальные правила Cursor пользователя\n- Запишите навык Coasts в `~/.cursor/skills/coasts/SKILL.md`\n\n**Настройка для проекта:**\n- Добавьте правила Coast Runtime в `AGENTS.md` в корне проекта (или в `.cursor/rules/coast.md`, если пользователь предпочитает правила в стиле Cursor — спросите его)\n- Запишите навык Coasts в `.cursor/skills/coasts/SKILL.md`\n\n## Шаг 5: Обновите Coastfile\n\nПрочитайте `Coastfile` в корне проекта. Посмотрите на поле `worktree_dir` в\nразделе `[coast]`. Также прочитайте поле `name` — оно понадобится вам, чтобы\nсформировать путь worktree.\n\nКаталог worktree Cursor — это `~/.cursor/worktrees/`, где `` —\nзначение поля `name` в Coastfile.\n\nЕсли этот путь **ещё не** указан в `worktree_dir`:\n\n- Если `worktree_dir` — одиночная строка, преобразуйте её в массив и добавьте\n путь Cursor. Например, `worktree_dir = \".worktrees\"` становится\n `worktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]`.\n- Если `worktree_dir` уже является массивом, добавьте в него путь Cursor.\n- Если `worktree_dir` вообще отсутствует, добавьте\n `worktree_dir = [\".worktrees\", \"~/.cursor/worktrees/\"]`, используя\n фактическое имя проекта.\n\nЭто внешний путь, поэтому, если для этого проекта уже запущен экземпляр Coast,\nего необходимо пересоздать с помощью `coast run`, чтобы новый bind mount начал\nдействовать. Сообщите об этом пользователю.\n\n## Шаг 6: Подтвердите\n\nПосле размещения файлов покажите пользователю сводку о том, что было создано и где.\n\nСообщите пользователю: **Перезапустите Cursor**, чтобы изменения навыка и правил\nвступили в силу.\n", + "harnesses/shep_setup_prompt.txt": "Вы настраиваете навык Coasts для Shep в этом проекте. Выполняйте все\nкоманды из корня проекта.\n\n## Шаг 1: Проверьте наличие Coast CLI\n\nВыполните эту команду:\n\n coast --version\n\nЕсли команда `coast` не найдена, остановитесь здесь и сообщите пользователю:\n\n \"Coast CLI не установлен. Сначала установите его: https://coasts.dev/docs/getting-started\"\n\nНе продолжайте, пока CLI не станет доступен.\n\n## Шаг 2: Получите содержимое навыка\n\nВыполните эту команду:\n\n coast skills-prompt\n\nВывод состоит из двух частей:\n\n- **Правила Coast Runtime** — всё от начала до строки, начинающейся с `---` (но не включая её)\n- **Навык Coasts** — всё, начиная с блока frontmatter `---` и далее (включая строки `---` и всё после них)\n\nСохраните обе части для следующих шагов ниже.\n\n## Шаг 3: Разместите файлы\n\nShep оборачивает Claude Code, поэтому используйте файловую структуру Claude Code. Если целевой файл\nуже существует, добавьте раздел Coast Runtime в конец вместо перезаписи — но\nсначала проверьте, присутствует ли уже раздел `# Coast Runtime`, и если\nда, пропустите этот шаг.\n\n- Добавьте правила Coast Runtime в `CLAUDE.md` в корне проекта\n- Запишите навык Coasts в `.agents/skills/coasts/SKILL.md` (или\n `.claude/skills/coasts/SKILL.md`, если проект уже использует такую структуру)\n\n## Шаг 4: Обновите Coastfile\n\nПрочитайте `Coastfile` в корне проекта. Посмотрите на поле `worktree_dir` в\nразделе `[coast]`.\n\nЕсли `~/.shep/repos/*/wt` **ещё не** указан в `worktree_dir`:\n\n- Если `worktree_dir` — это одна строка, преобразуйте её в массив и добавьте\n `~/.shep/repos/*/wt`. Например, `worktree_dir = \".worktrees\"` становится\n `worktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]`.\n- Если `worktree_dir` уже является массивом, добавьте в него `~/.shep/repos/*/wt`.\n- Если `worktree_dir` вообще отсутствует, добавьте\n `worktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]`.\n\n`*` — это glob-шаблон, который соответствует директории хеша для каждого репозитория. Coasts\nразворачивает его во время выполнения.\n\nЭто внешний путь, поэтому если для этого проекта уже запущен экземпляр Coast,\nего необходимо пересоздать с помощью `coast run`, чтобы новый bind mount вступил\nв силу. Сообщите об этом пользователю.\n\n## Шаг 5: Подтвердите\n\nПосле размещения файлов покажите пользователю сводку о том, что было создано и где.\n\nСообщите пользователю: **Закройте и заново откройте ваш редактор**, чтобы изменения\nнавыка и `CLAUDE.md` вступили в силу.\n", + "harnesses/t3_code_setup_prompt.txt": "Вы настраиваете навык Coasts для T3 Code в этом проекте. Выполняйте все\nкоманды из корня проекта.\n\n## Шаг 1: Проверьте наличие Coast CLI\n\nВыполните эту команду:\n\n coast --version\n\nЕсли команда `coast` не найдена, остановитесь здесь и сообщите пользователю:\n\n \"Coast CLI не установлен. Сначала установите его: https://coasts.dev/docs/getting-started\"\n\nНе продолжайте, пока CLI не станет доступен.\n\n## Шаг 2: Получите содержимое навыка\n\nВыполните эту команду:\n\n coast skills-prompt\n\nВывод состоит из двух частей:\n\n- **Правила Coast Runtime** — всё от начала до строки, которая начинается с `---` (но не включая её)\n- **Навык Coasts** — всё, начиная с блока frontmatter `---` и далее (включая строки `---` и всё после них)\n\nСохраните обе части для следующих шагов.\n\n## Шаг 3: Спросите пользователя\n\nT3 Code поддерживает несколько провайдеров. Спросите пользователя: каких провайдеров вы используете\nв T3 Code?\n\n- **Codex** (OpenAI)\n- **Claude** (Anthropic)\n- **Оба**\n- **Другое** — если пользователь укажет другого провайдера, выполните\n `coast docs --path SKILLS_FOR_HOST_AGENTS.md` и\n `coast docs --path harnesses/README.md`, чтобы определить, где этот провайдер\n ожидает инструкции проекта и навыки, затем следуйте тому же шаблону\n\n## Шаг 4: Разместите файлы\n\nНастройка T3 Code всегда выполняется на уровне проекта. Если целевой файл уже существует, добавьте\nраздел Coast Runtime вместо перезаписи — но сначала проверьте, присутствует ли уже\nраздел `# Coast Runtime`, и если да, пропустите.\n\n**Если пользователь выбрал Codex (или оба):**\n- Добавьте правила Coast Runtime в `AGENTS.md` в корне проекта\n- Запишите навык Coasts в `.agents/skills/coasts/SKILL.md` (уровень проекта)\n- Также запишите навык Coasts в `~/.codex/skills/coasts/SKILL.md` (глобальный\n fallback — T3 Code, возможно, ещё не сканирует `.agents/skills/` на уровне проекта)\n- Создайте `.agents/skills/coasts/agents/openai.yaml` со следующим содержимым:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n**Если пользователь выбрал Claude (или оба):**\n- Добавьте правила Coast Runtime в `CLAUDE.md` в корне проекта\n- Запишите навык Coasts в `.claude/skills/coasts/SKILL.md` (уровень проекта)\n- Также запишите навык Coasts в `~/.claude/skills/coasts/SKILL.md` (глобальный\n fallback — T3 Code, возможно, ещё не сканирует `.claude/skills/` на уровне проекта надёжно)\n\n**Примечание:** T3 Code, возможно, пока не загружает навыки уровня проекта из `.agents/skills/` или\n`.claude/skills/`. Правила в `AGENTS.md` и `CLAUDE.md` всё равно применяются\nв каждой задаче. Глобальный fallback `~/.codex/skills/coasts/` гарантирует,\nчто провайдер Codex сможет найти навык.\n\n## Шаг 5: Обновите Coastfile\n\nПрочитайте `Coastfile` в корне проекта. Посмотрите на поле `worktree_dir` в\nразделе `[coast]`. Также прочитайте поле `name` — оно понадобится вам, чтобы построить\nпуть worktree.\n\nКаталог worktree для T3 Code — это `~/.t3/worktrees/`, где `` —\nзначение поля `name` в Coastfile.\n\nЕсли этот путь **ещё не** указан в `worktree_dir`:\n\n- Если `worktree_dir` — это одна строка, преобразуйте её в массив и добавьте\n путь T3 Code. Например, `worktree_dir = \".worktrees\"` становится\n `worktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]`.\n- Если `worktree_dir` уже является массивом, добавьте в него путь T3 Code.\n- Если `worktree_dir` вообще отсутствует, добавьте\n `worktree_dir = [\".worktrees\", \"~/.t3/worktrees/\"]`, используя\n фактическое имя проекта.\n\nЭто внешний путь, поэтому, если экземпляр Coast уже запущен для этого\nпроекта, его нужно пересоздать с помощью `coast run`, чтобы новый bind mount\nвступил в силу. Сообщите об этом пользователю.\n\n## Шаг 6: Подтвердите\n\nПосле размещения файлов покажите пользователю сводку того, что было создано и где.\nОбъясните, что глобальная копия `~/.codex/skills/coasts/` — это обходной путь из-за того, что\nT3 Code пока не загружает навыки уровня проекта.\n\nСообщите пользователю: **Перезапустите T3 Code**, чтобы изменения навыка и правил\nвступили в силу.\n", "learn-coasts-videos/README.md": "# Видеокурс по Coasts\n\nКороткий видеокурс, охватывающий основные идеи Coasts. Каждый урок длится менее трёх минут. Смотрите их по порядку, чтобы получить полную картину, или переходите сразу к нужной теме.\n\n```youtube\nMBGKSKau4sU\n```\n\n## Уроки\n\n1. [Coasts](coasts.md) — что такое Coast и как работает основная модель.\n2. [Ports](ports.md) — как Coasts обеспечивают изоляцию портов и параллельный доступ во время выполнения.\n3. [Assign](assign.md) — переключение запущенного Coast между рабочими деревьями.\n4. [Checkout](checkout.md) — перенос Coast на ваши канонические порты для активного использования.\n5. [Volumes](volumes.md) — как Coasts работают с томами и постоянным состоянием сервисов.\n6. [Secrets](secrets.md) — управление секретами внутри Coast.\n7. [Getting Started](getting-started.md) — практическое руководство по использованию Coasts на реальном проекте.\n8. [Coast UI](coast-ui.md) — интерфейс Coastguard и информация о среде выполнения, которую он предоставляет.\n", "learn-coasts-videos/assign.md": "# Назначение\n\n```youtube\nLYCeequ54nk\n```\n\nНазначение перемещает запущенный Coast из одного рабочего дерева в другое без остановки среды выполнения. В этом видео рассказывается, как работает назначение и когда его следует использовать, чтобы передать Coast другой ветке.\n\nПолное описание см. в разделе [Assign and Unassign](../concepts_and_terminology/ASSIGN.md).\n", "learn-coasts-videos/checkout.md": "# Checkout\n\n```youtube\nJRAXkM4U1UE\n```\n\nCheckout сопоставляет канонические порты вашего проекта с конкретным экземпляром Coast. В этом видео показано, как вывести один Coast на передний план, чтобы ваш браузер, API-клиенты и наборы тестов обращались к нужному окружению без изменения каких-либо номеров портов.\n\nПолное описание см. в [Checkout](../concepts_and_terminology/CHECKOUT.md).\n", @@ -2322,6 +2370,11 @@ "path": "harnesses/MULTIPLE_HARNESSES.md", "type": "file" }, + { + "name": "SHEP.md", + "path": "harnesses/SHEP.md", + "type": "file" + }, { "name": "T3_CODE.md", "path": "harnesses/T3_CODE.md", @@ -2402,11 +2455,11 @@ "files": { "README.md": "# Documentação do Coasts\n\n```youtube\nMBGKSKau4sU\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## Instalação\n\n- `curl -fsSL https://coasts.dev/install | sh`\n- `coast daemon install`\n\n*Se você decidir não executar `coast daemon install`, você é responsável por iniciar o daemon manualmente com `coast daemon start` todas as vezes.*\n\n## O que são Coasts?\n\nUm Coast (**host conteinerizado**) é um runtime local de desenvolvimento. Coasts permitem que você execute múltiplos ambientes isolados para o mesmo projeto em uma única máquina.\n\nCoasts são especialmente úteis para stacks complexas de `docker-compose` com muitos serviços interdependentes, mas são igualmente eficazes para configurações locais de desenvolvimento não conteinerizadas. Coasts suportam uma ampla variedade de [padrões de configuração de runtime](concepts_and_terminology/RUNTIMES_AND_SERVICES.md) para que você possa moldar o ambiente ideal para múltiplos agentes trabalhando em paralelo.\n\nCoasts foram criados para desenvolvimento local, não como um serviço de nuvem hospedado. Seus ambientes rodam localmente na sua máquina.\n\nO projeto Coasts é gratuito, local, licenciado sob MIT, agnóstico ao provedor de agentes e agnóstico ao harness de agentes, sem upsells de IA.\n\nCoasts funcionam com qualquer workflow de codificação agentica que use worktrees. Nenhuma configuração especial do lado do harness é necessária.\n\n## Por que Coasts para Worktrees\n\nWorktrees do Git são excelentes para isolar mudanças de código, mas não resolvem o isolamento de runtime por si só.\n\nQuando você executa múltiplas worktrees em paralelo, rapidamente encontra problemas de ergonomia:\n\n- [Conflitos de porta](concepts_and_terminology/PORTS.md) entre serviços que esperam as mesmas portas do host.\n- Configuração de banco de dados por worktree e [configuração de volumes](concepts_and_terminology/VOLUMES.md) que é tediosa de gerenciar.\n- Ambientes de testes de integração que precisam de wiring de runtime personalizado por worktree.\n- O inferno de alternar worktrees e reconstruir o contexto de runtime a cada vez. Veja [Assign and Unassign](concepts_and_terminology/ASSIGN.md).\n\nSe o Git é controle de versão para o seu código, Coasts são como o Git para os runtimes das suas worktrees.\n\nCada ambiente recebe suas próprias portas, então você pode inspecionar qualquer runtime de worktree em paralelo. Quando você [faz checkout](concepts_and_terminology/CHECKOUT.md) de um runtime de worktree, Coasts remapeiam esse runtime para as portas canônicas do seu projeto.\n\nCoasts abstraem a configuração de runtime em uma camada modular simples sobre as worktrees, para que cada worktree possa rodar com o isolamento de que precisa sem manter manualmente configurações complexas por worktree.\n\n## Requisitos\n\n- macOS ou Linux\n- Docker Desktop no macOS, ou Docker Engine com o plugin Compose no Linux\n- Um projeto usando Git\n- Node.js\n- `socat` (`brew install socat` no macOS, `sudo apt install socat` no Ubuntu)\n\n```text\nLinux note: Dynamic ports work out of the box on Linux.\nIf you need canonical ports below `1024`, see the checkout docs for the required host configuration.\n```\n\n## Agentes em Contêineres?\n\nVocê pode conteinerizar um agente com um Coast. Isso pode parecer uma ótima ideia no início, mas em muitos casos você não precisa realmente rodar seu agente de codificação dentro de um contêiner.\n\nComo Coasts compartilham o [filesystem](concepts_and_terminology/FILESYSTEM.md) com sua máquina host por meio de um volume mount compartilhado, o workflow mais fácil e confiável é rodar o agente no seu host e instruí-lo a executar tarefas pesadas de runtime (como testes de integração) dentro da instância do Coast usando [`coast exec`](concepts_and_terminology/EXEC_AND_DOCKER.md).\n\nNo entanto, se você quiser rodar seu agente em um contêiner, Coasts suportam isso totalmente via [Agent Shells](concepts_and_terminology/AGENT_SHELLS.md). Você pode construir um rig incrivelmente intricado para essa configuração, incluindo [configuração de servidor MCP](concepts_and_terminology/MCP_SERVERS.md), mas isso pode não interoperar de forma limpa com o software de orquestração que existe hoje. Para a maioria dos workflows, agentes no host são mais simples e mais confiáveis.\n\n## Coasts vs Dev Containers\n\nCoasts não são dev containers, e não são a mesma coisa.\n\nDev containers geralmente são projetados para montar uma IDE em um único workspace de desenvolvimento conteinerizado. Coasts são headless e otimizados como ambientes leves para uso paralelo de agentes com worktrees — múltiplos ambientes de runtime isolados, com consciência de worktree, rodando lado a lado, com alternância rápida de checkout e controles de isolamento de runtime para cada instância.\n\n## Demo Repo\n\nSe você quiser um pequeno projeto de exemplo para experimentar com Coasts, comece com o repositório [`coasts-demo`](https://github.com/coast-guard/coasts-demo).\n\n## Coasts Video Course\n\nSe você preferir vídeo, o [Coasts Video Course](learn-coasts-videos/README.md) cobre todos os conceitos centrais em menos de três minutos cada.\n", "GETTING_STARTED.md": "# Primeiros Passos com Coasts\n\n```youtube\nJe921fgJ4RY\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## Instalando\n\n```bash\ncurl -fsSL https://coasts.dev/install | sh\ncoast daemon install\n```\n\n*Se você decidir não executar `coast daemon install`, você é responsável por iniciar o daemon manualmente com `coast daemon start` todas as vezes.*\n\n## Requisitos\n\n- macOS ou Linux\n- Docker Desktop no macOS, ou Docker Engine com o plugin Compose no Linux\n- Um projeto usando Git\n- Node.js\n- `socat` (`brew install socat` no macOS, `sudo apt install socat` no Ubuntu)\n\n```text\nNota sobre Linux: Portas dinâmicas funcionam imediatamente no Linux.\nSe você precisar de portas canônicas abaixo de `1024`, consulte a documentação de checkout para a configuração de host necessária.\n```\n\n## Configurando o Coasts em um Projeto\n\nAdicione um Coastfile à raiz do seu projeto. Certifique-se de que você não está em um worktree ao instalar.\n\n```text\nmy-project/\n├── Coastfile <-- isto é o que o Coast lê\n├── docker-compose.yml\n├── Dockerfile\n├── src/\n│ └── ...\n└── ...\n```\n\nO `Coastfile` aponta para seus recursos de desenvolvimento local existentes e adiciona configuração específica do Coasts — veja a [documentação de Coastfiles](coastfiles/README.md) para o esquema completo:\n\n```toml\n[coast]\nname = \"my-project\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\ndb = 5432\n```\n\nUm Coastfile é um arquivo TOML leve que *tipicamente* aponta para o seu `docker-compose.yml` existente (ele também funciona com configurações de desenvolvimento local sem contêiner) e descreve as modificações necessárias para executar seu projeto em paralelo — mapeamentos de portas, estratégias de volume e segredos. Coloque-o na raiz do seu projeto.\n\nA maneira mais rápida de criar um Coastfile para o seu projeto é deixar seu agente de codificação fazer isso.\n\nA CLI do Coasts inclui um prompt embutido que ensina a qualquer agente de IA o esquema completo do Coastfile e a CLI. Copie-o no chat do seu agente e ele analisará seu projeto e gerará um Coastfile.\n\n```prompt-copy\ninstallation_prompt.txt\n```\n\nVocê também pode obter a mesma saída pela CLI executando `coast installation-prompt`.\n\n## Seu Primeiro Coast\n\nAntes de iniciar seu primeiro Coast, derrube qualquer ambiente de desenvolvimento em execução. Se você estiver usando Docker Compose, execute `docker-compose down`. Se você tiver servidores de desenvolvimento locais em execução, pare-os. Coasts gerenciam suas próprias portas e entrarão em conflito com qualquer coisa que já esteja escutando.\n\nQuando seu Coastfile estiver pronto:\n\n```bash\ncoast build\ncoast run dev-1\n```\n\nVerifique se sua instância está em execução:\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ~/dev/my-project\n```\n\nVeja onde seus serviços estão escutando:\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\nCada instância recebe seu próprio conjunto de portas dinâmicas para que múltiplas instâncias possam rodar lado a lado. Para mapear uma instância de volta para as portas canônicas do seu projeto, faça o checkout dela:\n\n```bash\ncoast checkout dev-1\n```\n\nIsso significa que o runtime agora está em checkout e as portas canônicas do seu projeto (como `3000`, `5432`) irão rotear para esta instância do Coast.\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ✓ ~/dev/my-project\n```\n\nPara abrir a UI de observabilidade do Coastguard para o seu projeto:\n\n```bash\ncoast ui\n```\n\n## O Que Vem a Seguir?\n\n- Configure uma [skill para o seu agente host](SKILLS_FOR_HOST_AGENTS.md) para que ele saiba como interagir com Coasts\n", - "SKILLS_FOR_HOST_AGENTS.md": "# Habilidades para Agentes Host\n\nSe você usa agentes de programação com IA no host enquanto seu app roda dentro do Coasts, seu agente normalmente precisa de duas partes de configuração específicas do Coast:\n\n1. uma seção Coast Runtime sempre ativa no arquivo de instruções do projeto ou\n arquivo de regras do harness\n2. uma habilidade reutilizável de fluxo de trabalho do Coast, como `/coasts`,\n quando o harness oferece suporte a habilidades de projeto\n\nSem a primeira parte, o agente edita arquivos mas esquece de usar `coast exec`.\nSem a segunda, toda atribuição de Coast, log e fluxo de UI precisa ser\nreexplicado no chat.\n\nEste guia mantém a configuração concreta e específica do Coast: qual arquivo\ncriar, que texto colocar nele e como isso muda de acordo com o harness.\n\n## Por que os agentes precisam disso\n\nOs Coasts compartilham o [sistema de arquivos](concepts_and_terminology/FILESYSTEM.md) entre\nsua máquina host e o contêiner do Coast. Seu agente edita arquivos no host\ne os serviços em execução dentro do Coast veem as mudanças imediatamente. Mas o\nagente ainda precisa:\n\n1. descobrir qual instância do Coast corresponde ao checkout atual\n2. executar testes, builds e comandos de runtime dentro desse Coast\n3. ler logs e status dos serviços do Coast\n4. lidar com a atribuição de worktree com segurança quando nenhum Coast já está anexado\n\n## O que vai em cada lugar\n\n- `AGENTS.md`, `CLAUDE.md` ou `.cursor/rules/coast.md` — regras curtas do Coast\n que devem se aplicar em toda tarefa, mesmo que nenhuma skill seja invocada\n- skill (`.agents/skills/...`, `.claude/skills/...` ou `.cursor/skills/...`)\n — o próprio fluxo de trabalho reutilizável do Coast, como `/coasts`\n- arquivo de comando (`.claude/commands/...` ou `.cursor/commands/...`) —\n ponto de entrada explícito opcional para harnesses que oferecem suporte a\n isso; uma opção simples é fazer o comando reutilizar a skill\n\nSe um repositório usa mais de um harness, mantenha a skill canônica do Coast em\num único lugar e exponha-a onde for necessário. Veja\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md).\n\n## 1. Regras Coast Runtime sempre ativas\n\nAdicione o bloco a seguir ao arquivo de instruções de projeto sempre ativo ou\narquivo de regras do harness (`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/coast.md` ou equivalente):\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\nEste bloco pertence ao arquivo sempre ativo porque as regras devem se aplicar\nem toda tarefa, não apenas quando o agente entra explicitamente em um fluxo de\ntrabalho `/coasts`.\n\n## 2. Skill reutilizável `/coasts`\n\nQuando o harness oferece suporte a skills de projeto, salve o conteúdo da skill\ncomo um `SKILL.md` no seu diretório de skills. O texto completo da skill está\nem [skills_prompt.txt](skills_prompt.txt) (se estiver no modo CLI, use\n`coast skills-prompt`) — tudo após o bloco Coast Runtime é o conteúdo da skill,\ncomeçando no frontmatter `---`.\n\nSe você estiver usando superfícies específicas do Codex ou da OpenAI, também\npode adicionar opcionalmente `agents/openai.yaml` ao lado da skill para metadados\nde exibição ou política de invocação. Esses metadados devem ficar ao lado da\nskill, não substituí-la.\n\n## Início rápido por harness\n\n| Harness | Arquivo sempre ativo | Fluxo de trabalho reutilizável do Coast | Observações |\n|---------|----------------------|------------------------------------------|-------------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Não há um arquivo de comando de projeto separado a recomendar para a documentação do Coast. Veja [Codex](harnesses/CODEX.md). |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md` é opcional, mas mantenha a lógica na skill. Veja [Claude Code](harnesses/CLAUDE_CODE.md). |\n| Cursor | `AGENTS.md` ou `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` ou o compartilhado `.agents/skills/coasts/SKILL.md` | `.cursor/commands/coasts.md` é opcional. `.cursor/worktrees.json` é para bootstrap de worktree do Cursor, não política do Coast. Veja [Cursor](harnesses/CURSOR.md). |\n| Conductor | `CLAUDE.md` | Comece com `CLAUDE.md`; use scripts e configurações do Conductor para comportamento específico do Conductor | Não suponha o comportamento completo de comandos de projeto do Claude Code. Se um novo comando não aparecer, feche e reabra completamente o Conductor. Veja [Conductor](harnesses/CONDUCTOR.md). |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Esta é a superfície de harness mais limitada aqui. Use o layout no estilo Codex e não invente uma camada de comando nativa do T3 para a documentação do Coast. Veja [T3 Code](harnesses/T3_CODE.md). |\n\n## Deixe o agente se configurar sozinho\n\nA forma mais rápida é deixar o agente escrever os arquivos corretos por conta\nprópria. Copie o prompt abaixo para o chat do seu agente — ele inclui o bloco\nCoast Runtime, o bloco de skill `coasts` e instruções específicas por harness\nsobre onde cada parte deve ficar.\n\n```prompt-copy\nskills_prompt.txt\n```\n\nVocê também pode obter a mesma saída pela CLI executando `coast skills-prompt`.\n\n## Configuração manual\n\n- **Codex:** coloque a seção Coast Runtime em `AGENTS.md`, depois coloque a\n skill reutilizável `coasts` em `.agents/skills/coasts/SKILL.md`.\n- **Claude Code:** coloque a seção Coast Runtime em `CLAUDE.md`, depois coloque a\n skill reutilizável `coasts` em `.claude/skills/coasts/SKILL.md`. Só adicione\n `.claude/commands/coasts.md` se você quiser especificamente um arquivo de comando.\n- **Cursor:** coloque a seção Coast Runtime em `AGENTS.md` se você quiser as\n instruções mais portáveis, ou em `.cursor/rules/coast.md` se quiser uma\n regra de projeto nativa do Cursor. Coloque o fluxo de trabalho reutilizável\n `coasts` em `.cursor/skills/coasts/SKILL.md` para um repositório só de Cursor,\n ou em `.agents/skills/coasts/SKILL.md` se o repositório for compartilhado com\n outros harnesses. Só adicione `.cursor/commands/coasts.md` se você quiser\n especificamente um arquivo de comando explícito.\n- **Conductor:** coloque a seção Coast Runtime em `CLAUDE.md`. Use os scripts\n de Repository Settings do Conductor para bootstrap ou comportamento de execução\n específicos do Conductor. Se você adicionar um comando e ele não aparecer,\n feche e reabra totalmente o app.\n- **T3 Code:** use o mesmo layout do Codex: `AGENTS.md` mais\n `.agents/skills/coasts/SKILL.md`. Trate o T3 Code aqui como um harness fino\n no estilo Codex, não como uma superfície separada de comandos do Coast.\n- **Multiple harnesses:** mantenha a skill canônica em\n `.agents/skills/coasts/SKILL.md`. O Cursor pode carregar isso diretamente;\n exponha para o Claude Code por meio de `.claude/skills/coasts/` se necessário.\n\n## Leitura adicional\n\n- Leia o [guia de Harnesses](harnesses/README.md) para a matriz por harness\n- Leia [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md) para o padrão de\n layout compartilhado\n- Leia a [documentação dos Coastfiles](coastfiles/README.md) para aprender o esquema completo\n de configuração\n- Aprenda os comandos da [CLI do Coast](concepts_and_terminology/CLI.md) para gerenciar\n instâncias\n- Explore o [Coastguard](concepts_and_terminology/COASTGUARD.md), a interface web para\n observar e controlar seus Coasts\n", + "SKILLS_FOR_HOST_AGENTS.md": "# Habilidades para Agentes Host\n\nSe você usa agentes de programação com IA no host enquanto seu app roda dentro do Coasts, seu agente normalmente precisa de duas partes de configuração específicas do Coast:\n\n1. uma seção Coast Runtime sempre ativa no arquivo de instruções do projeto ou\n arquivo de regras do harness\n2. uma habilidade reutilizável de fluxo de trabalho do Coast, como `/coasts`,\n quando o harness oferece suporte a habilidades de projeto\n\nSem a primeira parte, o agente edita arquivos mas esquece de usar `coast exec`.\nSem a segunda, toda atribuição de Coast, log e fluxo de UI precisa ser\nreexplicado no chat.\n\nEste guia mantém a configuração concreta e específica do Coast: qual arquivo\ncriar, que texto colocar nele e como isso muda de acordo com o harness.\n\n## Por que os agentes precisam disso\n\nOs Coasts compartilham o [sistema de arquivos](concepts_and_terminology/FILESYSTEM.md) entre\nsua máquina host e o contêiner do Coast. Seu agente edita arquivos no host\ne os serviços em execução dentro do Coast veem as mudanças imediatamente. Mas o\nagente ainda precisa:\n\n1. descobrir qual instância do Coast corresponde ao checkout atual\n2. executar testes, builds e comandos de runtime dentro desse Coast\n3. ler logs e status dos serviços do Coast\n4. lidar com a atribuição de worktree com segurança quando nenhum Coast já está anexado\n\n## O que vai em cada lugar\n\n- `AGENTS.md`, `CLAUDE.md` ou `.cursor/rules/coast.md` — regras curtas do Coast\n que devem se aplicar em toda tarefa, mesmo que nenhuma skill seja invocada\n- skill (`.agents/skills/...`, `.claude/skills/...` ou `.cursor/skills/...`)\n — o próprio fluxo de trabalho reutilizável do Coast, como `/coasts`\n- arquivo de comando (`.claude/commands/...` ou `.cursor/commands/...`) —\n ponto de entrada explícito opcional para harnesses que oferecem suporte a\n isso; uma opção simples é fazer o comando reutilizar a skill\n\nSe um repositório usa mais de um harness, mantenha a skill canônica do Coast em\num único lugar e exponha-a onde for necessário. Veja\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md).\n\n## 1. Regras Coast Runtime sempre ativas\n\nAdicione o bloco a seguir ao arquivo de instruções de projeto sempre ativo ou\narquivo de regras do harness (`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/coast.md` ou equivalente):\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n coast exec --service # service shell\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Use `coast exec --service ` when you need to run inside an app/service container.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\nEste bloco pertence ao arquivo sempre ativo porque as regras devem se aplicar\nem toda tarefa, não apenas quando o agente entra explicitamente em um fluxo de\ntrabalho `/coasts`.\n\n## 2. Skill reutilizável `/coasts`\n\nQuando o harness oferece suporte a skills de projeto, salve o conteúdo da skill\ncomo um `SKILL.md` no seu diretório de skills. O texto completo da skill está\nem [skills_prompt.txt](skills_prompt.txt) (se estiver no modo CLI, use\n`coast skills-prompt`) — tudo após o bloco Coast Runtime é o conteúdo da skill,\ncomeçando no frontmatter `---`.\n\nSe você estiver usando superfícies específicas do Codex ou da OpenAI, também\npode adicionar opcionalmente `agents/openai.yaml` ao lado da skill para metadados\nde exibição ou política de invocação. Esses metadados devem ficar ao lado da\nskill, não substituí-la.\n\n## Início rápido por harness\n\n| Harness | Arquivo sempre ativo | Fluxo de trabalho reutilizável do Coast | Observações |\n|---------|----------------------|------------------------------------------|-------------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Não há um arquivo de comando de projeto separado a recomendar para a documentação do Coast. Veja [Codex](harnesses/CODEX.md). |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md` é opcional, mas mantenha a lógica na skill. Veja [Claude Code](harnesses/CLAUDE_CODE.md). |\n| Cursor | `AGENTS.md` ou `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` ou o compartilhado `.agents/skills/coasts/SKILL.md` | `.cursor/commands/coasts.md` é opcional. `.cursor/worktrees.json` é para bootstrap de worktree do Cursor, não política do Coast. Veja [Cursor](harnesses/CURSOR.md). |\n| Conductor | `CLAUDE.md` | Comece com `CLAUDE.md`; use scripts e configurações do Conductor para comportamento específico do Conductor | Não suponha o comportamento completo de comandos de projeto do Claude Code. Se um novo comando não aparecer, feche e reabra completamente o Conductor. Veja [Conductor](harnesses/CONDUCTOR.md). |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Esta é a superfície de harness mais limitada aqui. Use o layout no estilo Codex e não invente uma camada de comando nativa do T3 para a documentação do Coast. Veja [T3 Code](harnesses/T3_CODE.md). |\n\n## Deixe o agente se configurar sozinho\n\nA forma mais rápida é deixar o agente escrever os arquivos corretos por conta\nprópria. Copie o prompt abaixo para o chat do seu agente — ele inclui o bloco\nCoast Runtime, o bloco de skill `coasts` e instruções específicas por harness\nsobre onde cada parte deve ficar.\n\n```prompt-copy\nskills_prompt.txt\n```\n\nVocê também pode obter a mesma saída pela CLI executando `coast skills-prompt`.\n\n## Configuração manual\n\n- **Codex:** coloque a seção Coast Runtime em `AGENTS.md`, depois coloque a\n skill reutilizável `coasts` em `.agents/skills/coasts/SKILL.md`.\n- **Claude Code:** coloque a seção Coast Runtime em `CLAUDE.md`, depois coloque a\n skill reutilizável `coasts` em `.claude/skills/coasts/SKILL.md`. Só adicione\n `.claude/commands/coasts.md` se você quiser especificamente um arquivo de comando.\n- **Cursor:** coloque a seção Coast Runtime em `AGENTS.md` se você quiser as\n instruções mais portáveis, ou em `.cursor/rules/coast.md` se quiser uma\n regra de projeto nativa do Cursor. Coloque o fluxo de trabalho reutilizável\n `coasts` em `.cursor/skills/coasts/SKILL.md` para um repositório só de Cursor,\n ou em `.agents/skills/coasts/SKILL.md` se o repositório for compartilhado com\n outros harnesses. Só adicione `.cursor/commands/coasts.md` se você quiser\n especificamente um arquivo de comando explícito.\n- **Conductor:** coloque a seção Coast Runtime em `CLAUDE.md`. Use os scripts\n de Repository Settings do Conductor para bootstrap ou comportamento de execução\n específicos do Conductor. Se você adicionar um comando e ele não aparecer,\n feche e reabra totalmente o app.\n- **T3 Code:** use o mesmo layout do Codex: `AGENTS.md` mais\n `.agents/skills/coasts/SKILL.md`. Trate o T3 Code aqui como um harness fino\n no estilo Codex, não como uma superfície separada de comandos do Coast.\n- **Multiple harnesses:** mantenha a skill canônica em\n `.agents/skills/coasts/SKILL.md`. O Cursor pode carregar isso diretamente;\n exponha para o Claude Code por meio de `.claude/skills/coasts/` se necessário.\n\n## Leitura adicional\n\n- Leia o [guia de Harnesses](harnesses/README.md) para a matriz por harness\n- Leia [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md) para o padrão de\n layout compartilhado\n- Leia a [documentação dos Coastfiles](coastfiles/README.md) para aprender o esquema completo\n de configuração\n- Aprenda os comandos da [CLI do Coast](concepts_and_terminology/CLI.md) para gerenciar\n instâncias\n- Explore o [Coastguard](concepts_and_terminology/COASTGUARD.md), a interface web para\n observar e controlar seus Coasts\n", "VIDEO_TUTORIALS.md": "# Tutoriais em Vídeo\n\nEsta página reúne os vídeos tutoriais oficiais do Coasts do canal do Coasts no YouTube.\n\nSe você prefere um rápido passo a passo em vídeo antes de ler o restante da documentação, comece pelos vídeos de visão geral e de primeiros passos e, em seguida, vá para os tópicos específicos de recursos abaixo.\n\n## Links\n\n- [Coasts YouTube channel](https://www.youtube.com/@coasts-dev) - O canal oficial para vídeos do Coasts.\n- [Coasts playlist](https://www.youtube.com/playlist?list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw) - A playlist completa de tutoriais em um só lugar.\n\n## Vídeos\n\n- [Coasts Overview](https://www.youtube.com/watch?v=MBGKSKau4sU&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=1&pp=iAQB) (2:42) - Uma introdução de alto nível sobre o que são Coasts e por que você pode usá-los.\n- [Coasts](https://www.youtube.com/watch?v=kYlB5U9O92E&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=2&pp=iAQB) (1:29) - Um breve tour pelo modelo central do Coasts.\n- [Ports](https://www.youtube.com/watch?v=pBKkBiJ3o-g&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=3&pp=iAQB) (1:46) - Como o Coasts lida com isolamento de portas e acesso paralelo em tempo de execução.\n- [Assign](https://www.youtube.com/watch?v=LYCeequ54nk&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=4&pp=iAQB) (1:57) - Como alternar um Coast em execução entre worktrees.\n- [Checkout](https://www.youtube.com/watch?v=JRAXkM4U1UE&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=5&pp=iAQB) (1:46) - Como trazer um Coast para suas portas canônicas para uso ativo.\n- [Volumes](https://www.youtube.com/watch?v=k1es1Wf0zp0&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=6&pp=iAQB) (2:00) - Como o Coasts lida com volumes e estado persistente de serviços.\n- [Secrets](https://www.youtube.com/watch?v=4lAfHUjqn50&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=7&pp=iAQB) (2:09) - Gerenciamento de segredos dentro de um Coast.\n- [Getting Started](https://www.youtube.com/watch?v=Je921fgJ4RY&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=8&pp=iAQB) (2:40) - Um rápido passo a passo de onboarding para experimentar o Coasts.\n- [Coast UI](https://www.youtube.com/watch?v=Ts-YWkhHR8I&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=9&pp=iAQB0gcJCa4KAYcqIYzv) (1:46) - Um tour pela UI do Coastguard e pelas informações de tempo de execução que ela expõe.\n\nEsta página reflete o conteúdo atual da playlist oficial e pode ser atualizada conforme novos vídeos tutoriais forem adicionados.\n", - "doc_ordering.txt": "# Nível superior\nREADME.md\nGETTING_STARTED.md\nSKILLS_FOR_HOST_AGENTS.md\n\n# Learn Coasts\nlearn-coasts-videos/README.md\nlearn-coasts-videos/coasts.md\nlearn-coasts-videos/ports.md\nlearn-coasts-videos/assign.md\nlearn-coasts-videos/checkout.md\nlearn-coasts-videos/volumes.md\nlearn-coasts-videos/secrets.md\nlearn-coasts-videos/getting-started.md\nlearn-coasts-videos/coast-ui.md\n\n# Harnesses\nharnesses/README.md\nharnesses/CODEX.md\nharnesses/CONDUCTOR.md\nharnesses/CLAUDE_CODE.md\nharnesses/CURSOR.md\nharnesses/T3_CODE.md\nharnesses/MULTIPLE_HARNESSES.md\n\n# Conceitos e Terminologia\nconcepts_and_terminology/README.md\nconcepts_and_terminology/COASTS.md\nconcepts_and_terminology/RUN.md\nconcepts_and_terminology/REMOVE.md\nconcepts_and_terminology/FILESYSTEM.md\nconcepts_and_terminology/DAEMON.md\nconcepts_and_terminology/CLI.md\nconcepts_and_terminology/COASTGUARD.md\nconcepts_and_terminology/PORTS.md\nconcepts_and_terminology/PRIMARY_PORT_AND_DNS.md\nconcepts_and_terminology/ASSIGN.md\nconcepts_and_terminology/CHECKOUT.md\nconcepts_and_terminology/LOOKUP.md\nconcepts_and_terminology/VOLUMES.md\nconcepts_and_terminology/SHARED_SERVICES.md\nconcepts_and_terminology/SECRETS.md\nconcepts_and_terminology/BUILDS.md\nconcepts_and_terminology/COASTFILE_TYPES.md\nconcepts_and_terminology/RUNTIMES_AND_SERVICES.md\nconcepts_and_terminology/BARE_SERVICES.md\nconcepts_and_terminology/MIXED_SERVICE_TYPES.md\nconcepts_and_terminology/LOGS.md\nconcepts_and_terminology/EXEC_AND_DOCKER.md\nconcepts_and_terminology/AGENT_SHELLS.md\nconcepts_and_terminology/MCP_SERVERS.md\nconcepts_and_terminology/PERFORMANCE_OPTIMIZATIONS.md\nconcepts_and_terminology/TROUBLESHOOTING.md\n\n# Coastfiles\ncoastfiles/README.md\ncoastfiles/PROJECT.md\ncoastfiles/WORKTREE_DIR.md\ncoastfiles/PORTS.md\ncoastfiles/SHARED_SERVICES.md\ncoastfiles/SERVICES.md\ncoastfiles/SECRETS.md\ncoastfiles/VOLUMES.md\ncoastfiles/ASSIGN.md\ncoastfiles/INHERITANCE.md\ncoastfiles/AGENT_SHELL.md\ncoastfiles/MCP.md\n\n# Receitas\nrecipes/README.md\nrecipes/FULLSTACK_MONOREPO.md\n", - "installation_prompt.txt": "Você está instalando o Coasts neste projeto. Coast (host em contêiner) é uma ferramenta de CLI que executa vários ambientes de desenvolvimento isolados em uma única máquina usando contêineres Docker-in-Docker. Cada ambiente recebe suas próprias portas, volumes e runtime — ideal para fluxos de trabalho paralelos com worktrees.\n\nSeu trabalho: analisar este projeto e gerar um Coastfile (um arquivo TOML chamado \"Coastfile\" na raiz do projeto).\n\n=== DOCUMENTAÇÃO ===\n\nO Coast tem documentação embutida acessível a partir da CLI. Use-a para entender o esquema completo do Coastfile, estratégias de volume, comportamento de assign e outras opções de configuração antes de gerar um Coastfile.\n\nNavegue pela árvore de docs:\n\n coast docs\n\nIsso imprime a árvore completa de docs. Comece lendo os arquivos README — eles fornecem índices para ajudar você a encontrar a documentação certa para cada tópico:\n\n coast docs --path README.md\n coast docs --path coastfiles/README.md\n coast docs --path concepts_and_terminology/README.md\n\nLeia um doc específico:\n\n coast docs --path coastfiles/PROJECT.md\n coast docs --path coastfiles/VOLUMES.md\n\nPesquise nos docs (busca semântica — descreva o que você está procurando em linguagem natural):\n\n coast search-docs \"how do volume strategies work\"\n coast search-docs \"shared postgres across instances\"\n coast search-docs \"secret injection from environment variables\"\n\nUse os docs para tomar decisões informadas sobre a configuração do Coastfile deste projeto. A seção coastfiles/ cobre cada diretiva do Coastfile em detalhe.\n\n=== ESQUEMA DO COASTFILE (referência rápida) ===\n\n[coast] — Obrigatório. Metadados do projeto.\n\n name (string, required) Identificador do projeto usado na nomeação de contêiner/volume.\n compose (string, optional) Caminho para docker-compose.yml relativo ao Coastfile.\n runtime (string, optional) \"dind\" (padrão), \"sysbox\" ou \"podman\".\n root (string, optional) Sobrescrita da raiz do projeto (relativa ou absoluta).\n worktree_dir (string, optional) Diretório para worktrees do git (padrão: \".worktrees\"). Auto-detectado a partir de worktrees existentes em runtime.\n\n[coast.setup] — Opcional. Personalize o contêiner DinD em si.\n\n packages (array of strings) Pacotes Alpine para instalar (por exemplo [\"nodejs\", \"npm\", \"git\"]).\n run (array of strings) Comandos arbitrários para executar durante o setup.\n\n[ports] — Obrigatório (pelo menos um). Mapa de nome lógico para número de porta.\n Essas portas são encaminhadas para o host quando o coast é feito checkout.\n\n Exemplo:\n [ports]\n web = 3000\n api = 8080\n postgres = 5432\n\n[volumes.*] — Opcional. Configuração por volume.\n\n strategy \"isolated\" (padrão) ou \"shared\"\n service Nome do serviço do Compose que é dono deste volume.\n mount Caminho de montagem dentro do contêiner do serviço.\n snapshot_source (somente isolated) Semeia a partir de um nome de volume existente.\n\n Exemplo:\n [volumes.postgres_data]\n strategy = \"isolated\"\n service = \"db\"\n mount = \"/var/lib/postgresql/data\"\n\n[secrets.*] — Opcional. Extração e injeção de segredos.\n\n extractor \"file\", \"env\", \"command\" ou \"macos-keychain\"\n inject \"env:VAR_NAME\" ou \"file:/path/in/container\"\n ttl Expiração opcional (por exemplo \"1h\", \"30m\").\n\n Parâmetros específicos do extractor:\n file: path = \"./path/to/secret\"\n env: var = \"HOST_ENV_VAR\"\n command: run = \"echo secret-value\"\n macos-keychain: item = \"keychain-item-name\"\n\n Exemplo:\n [secrets.db_password]\n extractor = \"env\"\n var = \"DB_PASSWORD\"\n inject = \"env:DATABASE_PASSWORD\"\n\n[inject] — Opcional. Injeção de arquivo/env do host que não é segredo.\n\n env Array de nomes de variáveis de ambiente do host para encaminhar.\n files Array de caminhos de arquivos do host para montar.\n\n Exemplo:\n [inject]\n env = [\"NODE_ENV\", \"DEBUG\"]\n files = [\"~/.ssh/id_ed25519\", \"~/.gitconfig\"]\n\n[shared_services.*] — Opcional. Serviços no daemon Docker do host compartilhados entre instâncias.\n\n image Imagem Docker.\n ports Array de números de porta.\n volumes Array de montagens de volume.\n env Tabela inline de variáveis de ambiente.\n auto_create_db (bool) Criar automaticamente um banco por instância.\n inject Injetar string de conexão nos contêineres do coast.\n\n Exemplo:\n [shared_services.postgres]\n image = \"postgres:16-alpine\"\n ports = [5432]\n volumes = [\"postgres_data:/var/lib/postgresql/data\"]\n env = { POSTGRES_USER = \"dev\", POSTGRES_PASSWORD = \"dev\", POSTGRES_DB = \"app\" }\n auto_create_db = true\n inject = \"env:DATABASE_URL\"\n\n[assign] — Opcional. Controla o que acontece ao trocar de branch (coast assign).\n\n default \"none\", \"restart\" ou \"rebuild\"\n [assign.services] Sobrescritas por serviço.\n [assign.rebuild_triggers] Globs de arquivo por serviço que disparam rebuild.\n\n Exemplo:\n [assign]\n default = \"none\"\n [assign.services]\n api = \"restart\"\n worker = \"rebuild\"\n [assign.rebuild_triggers]\n worker = [\"Dockerfile\", \"package.json\"]\n\n[services.*] — Opcional. Serviços de processo simples (sem docker-compose).\n\n command Comando de shell para executar.\n port Número de porta.\n restart \"on-failure\" ou \"always\".\n\n Exemplo:\n [services.web]\n command = \"node server.js\"\n port = 3000\n restart = \"on-failure\"\n\n=== EXEMPLO: Mínimo (sem compose) ===\n\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[ports]\napp = 3000\n\n=== EXEMPLO: Com docker-compose ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\npostgres = 5432\nredis = 6379\n\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n\n=== EXEMPLO: Com secrets ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\n\n[secrets.api_key]\nextractor = \"env\"\nvar = \"API_KEY\"\ninject = \"env:API_KEY\"\n\n[secrets.ssh_key]\nextractor = \"file\"\npath = \"~/.ssh/id_ed25519\"\ninject = \"file:/run/secrets/ssh_key\"\n\n=== PRINCIPAIS TRADEOFFS PARA DISCUTIR COM O USUÁRIO ===\n\nAntes de gerar o Coastfile, pergunte ao usuário sobre quaisquer escolhas de configuração ambíguas. Aqui estão as principais:\n\nEstratégia de banco de dados e infraestrutura — há três opções para serviços como postgres e redis:\n - Volumes isolados (padrão): cada instância do Coast obtém sua própria cópia dos dados dentro do contêiner DinD. As instâncias não podem interferir entre si. Melhor quando você quer estado de banco por branch.\n - Volumes compartilhados: todas as instâncias leem e escrevem o mesmo volume dentro de seus contêineres DinD. Economiza espaço em disco, mas escritas concorrentes de múltiplas instâncias podem corromper dados.\n - Serviços compartilhados: execute o banco no daemon Docker do host em vez de dentro de cada Coast. Todas as instâncias conectam a um único servidor compartilhado. Usa a menor quantidade de memória, suporta auto_create_db para bancos por instância em um único postgres, e os dados sobrevivem à deleção da instância. Melhor para times grandes ou máquinas com pouca memória.\n - Se o projeto tiver um banco de dados, pergunte ao usuário qual abordagem ele quer. Explique os tradeoffs — isolated é a mais segura, shared services é a mais eficiente em memória.\n\nEstratégia de assign — o que acontece ao alternar um Coast entre worktrees:\n - \"none\": não fazer nada (para serviços como postgres/redis que não mudam entre branches).\n - \"restart\": reiniciar o contêiner (para serviços interpretados que só precisam de reinício do processo).\n - \"rebuild\": reconstruir a imagem Docker e reiniciar (para serviços em que a mudança de branch afeta o Dockerfile ou dependências de build).\n - Se o projeto tiver múltiplos serviços, pergunte quais precisam de rebuild vs restart ao trocar de branch.\n\n=== INSTRUÇÕES ===\n\n1. Examine a estrutura deste projeto. Se houver um docker-compose.yml, leia-o para identificar serviços, portas e volumes.\n2. Detecte o diretório de worktree do git existente. Execute `git worktree list` para verificar se o projeto já tem worktrees do git configuradas.\n - Se existirem worktrees, examine seus caminhos para determinar o diretório pai comum (por exemplo, se as worktrees estão em `../.worktrees/feat-a` e `../.worktrees/feat-b`, o worktree_dir é `\"../.worktrees\"`).\n - Defina `worktree_dir` no Coastfile para corresponder ao diretório detectado.\n - Se não existirem worktrees, omita `worktree_dir` (o Coast usa \".worktrees\" por padrão). NÃO use \".coasts\" — isso polui o projeto com um diretório com marca do Coast.\n3. Leia os docs relevantes do Coast (use `coast docs` e `coast search-docs`) para entender estratégias de volume, comportamento de assign e quaisquer opções de configuração que se apliquem à stack deste projeto.\n4. Pergunte ao usuário sobre quaisquer escolhas de configuração ambíguas (veja os tradeoffs acima). Não chute — explique as opções e deixe que ele decida.\n5. Gere um Coastfile na raiz do projeto com base na análise do projeto e na entrada do usuário.\n6. Se o projeto não tiver docker-compose.yml, use [services.*] para definições de processos simples ou [coast.setup] para instalar dependências.\n7. Execute `coast build`. Se falhar, verifique o erro e consulte os docs (`coast search-docs \"\"`) para solucionar.\n8. Execute `coast run dev-1`. Se falhar, verifique o erro e consulte os docs.\n9. Execute `coast ui` para abrir o dashboard do Coastguard (isto é para o usuário quando você terminar).\n", - "skills_prompt.txt": "# Coast Runtime\n\nEste projeto usa Coasts — runtimes conteinerizados para executar serviços, testes\ne outros comandos de runtime. O sistema de arquivos é compartilhado entre o host e o\ncontêiner, então edições de arquivos em qualquer lado ficam visíveis para ambos imediatamente.\n\n## Discovery\n\nAntes do primeiro comando de runtime em uma sessão, execute:\n\n coast lookup\n\nIsso imprime o nome da instância, portas e comandos de exemplo. Use o nome da instância\nda saída para todos os comandos subsequentes.\n\n## What runs where\n\nO sistema de arquivos é compartilhado, então use `coast exec` apenas para coisas que precisam do\nruntime do contêiner (bancos de dados, serviços, testes de integração). Todo o resto\né executado diretamente no host.\n\nUse `coast exec` para:\n- Testes que precisam de serviços em execução (testes unitários integrados com serviços ou bancos de dados, testes de integração, testes de API)\n- Reinicializações de serviços ou operações de compose\n- Qualquer coisa que se comunique com bancos de dados, caches ou outros serviços em contêineres\n\nExecute diretamente no host:\n- Linting, verificação de tipos, formatação\n- Operações de git\n- Testes com Playwright e testes de navegador\n- Instalação de dependências do lado do host (npm install, pip install)\n- Busca de arquivos, geração de código, análise estática\n\nExemplo:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nSe `coast lookup` não retornar correspondência, execute `coast ls` para ver o que existe.\n\nSe um Coast não atribuído já estiver em execução para este projeto, prefira atribuir\nsua worktree a ele em vez de criar um novo:\n\n coast assign -w \n\nUm Coast já ocupado também pode ser reatribuído com `coast assign`, mas confirme\ncom o usuário primeiro, porque isso vai interromper o slot atual.\n\nSe nenhum Coast estiver em execução, pergunte ao usuário antes de criar um — Coasts podem consumir\nmuita memória:\n\n coast run -w \n\nUm projeto precisa ser compilado antes que instâncias possam ser criadas. Se `coast run` falhar\nporque não existe nenhum build, execute `coast build` primeiro.\n\n## Coastfile setup\n\nSe o projeto ainda não tiver um Coastfile, ou se você precisar modificar o\nCoastfile, leia primeiro a documentação do Coastfile:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nAntes de supor algo sobre o comportamento do Coast, explore a documentação:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Sempre execute `coast lookup` antes do seu primeiro comando de runtime em uma sessão.\n- Use `coast exec` apenas para coisas que precisam do runtime do contêiner.\n- Execute linting, verificação de tipos, formatação e git diretamente no host.\n- Use `coast docs` ou `coast search-docs` antes de supor algo sobre o comportamento do Coast.\n- Não execute serviços diretamente no host quando o projeto espera Coast.\n\n---\nname: coasts\ndescription: Inspecione e controle instâncias do Coast para o checkout atual. Use\n quando o usuário disser \"/coasts\", pedir para atribuir ou reatribuir um Coast, quiser\n executar comandos ou ler logs no Coast correspondente, quiser criar um novo Coast,\n ou pedir explicitamente para abrir a UI do Coast.\n---\n\n# Coasts\n\nUse a CLI do Coast diretamente. Não adicione wrappers.\n\n## Orient Yourself\n\nComece explorando a CLI e a documentação:\n\n coast # see all available commands\n coast docs # list all doc pages\n coast search-docs \"your question\" # semantic search\n\nQuando qualquer aspecto do comportamento do Coast estiver incerto, leia a documentação antes de supor:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\nEncaminhe as solicitações para um destes modos:\n\n1. **Use Coast** — execute `coast lookup`, depois use `coast exec`, `coast ps`,\n ou `coast logs` com a instância correspondente.\n2. **Create or Assign** — execute `coast ls`, depois `coast run` para criar um novo\n Coast ou `coast assign` para redirecionar um existente.\n3. **Open UI** — execute `coast ui`.\n\n## What Runs Where\n\nO host e o Coast compartilham o sistema de arquivos. Use `coast exec` apenas para coisas\nque precisam de serviços em execução dentro do contêiner.\n\n**Use `coast exec` for:**\n- Testes de integração, testes de API, qualquer coisa que precise de bancos de dados ou serviços\n- Reinicializações de serviços, operações de compose\n- Comandos que se comunicam com processos disponíveis apenas no contêiner\n\n**Run on the host:**\n- Linting (`eslint`, `rubocop`, `golangci-lint`)\n- Verificação de tipos (`tsc --noEmit`, `go vet`)\n- Formatação (`prettier`, `gofmt`)\n- Operações de git\n- Testes com Playwright e testes de navegador\n- Análise estática, geração de código\n- Instalação de pacotes (`npm install`, `pip install`)\n\n## Create and Assign\n\nQuando `coast lookup` não retornar correspondência:\n\n1. Execute `coast ls` para ver os slots disponíveis.\n2. Prefira `coast run -w ` para criar e atribuir em uma única etapa.\n3. Se ainda não existir nenhum build, execute `coast build` primeiro.\n4. Após criar, execute `coast lookup` novamente para confirmar.\n\nQuando você quiser trocar um Coast existente para uma worktree diferente:\n\n coast assign -w \n\nIsso também funciona para um Coast já atribuído ou com checkout feito, mas pergunte ao usuário\nprimeiro antes de reatribuir um slot ocupado.\n\n## Coastfile Setup\n\nSe o projeto precisar de um Coastfile novo ou modificado, leia a documentação primeiro:\n\n coast docs --path coastfiles/README.md\n\nA documentação do Coastfile cobre configuração de compose, portas, volumes, segredos, serviços\ncompartilhados, serviços bare e herança.\n\n## Safety Rules\n\n- Execute `coast lookup` antes de agir e novamente após qualquer mudança de topologia.\n- Pergunte antes de `coast assign`, `coast unassign` ou `coast checkout` se isso puder\n interromper um slot existente.\n- Prefira criar um novo Coast em vez de reutilizar um que já tenha checkout feito ou já esteja atribuído,\n a menos que o usuário queira explicitamente que o slot existente seja reatribuído.\n- Use `coast docs` ou `coast search-docs` antes de supor algo.\n", + "doc_ordering.txt": "# Nível superior\nREADME.md\nGETTING_STARTED.md\nSKILLS_FOR_HOST_AGENTS.md\n\n# Learn Coasts\nlearn-coasts-videos/README.md\nlearn-coasts-videos/coasts.md\nlearn-coasts-videos/ports.md\nlearn-coasts-videos/assign.md\nlearn-coasts-videos/checkout.md\nlearn-coasts-videos/volumes.md\nlearn-coasts-videos/secrets.md\nlearn-coasts-videos/getting-started.md\nlearn-coasts-videos/coast-ui.md\n\n# Harnesses\nharnesses/README.md\nharnesses/CODEX.md\nharnesses/CONDUCTOR.md\nharnesses/CLAUDE_CODE.md\nharnesses/CURSOR.md\nharnesses/T3_CODE.md\nharnesses/SHEP.md\nharnesses/MULTIPLE_HARNESSES.md\n\n# Conceitos e Terminologia\nconcepts_and_terminology/README.md\nconcepts_and_terminology/COASTS.md\nconcepts_and_terminology/RUN.md\nconcepts_and_terminology/REMOVE.md\nconcepts_and_terminology/FILESYSTEM.md\nconcepts_and_terminology/DAEMON.md\nconcepts_and_terminology/CLI.md\nconcepts_and_terminology/COASTGUARD.md\nconcepts_and_terminology/PORTS.md\nconcepts_and_terminology/PRIMARY_PORT_AND_DNS.md\nconcepts_and_terminology/ASSIGN.md\nconcepts_and_terminology/CHECKOUT.md\nconcepts_and_terminology/LOOKUP.md\nconcepts_and_terminology/VOLUMES.md\nconcepts_and_terminology/SHARED_SERVICES.md\nconcepts_and_terminology/SECRETS.md\nconcepts_and_terminology/BUILDS.md\nconcepts_and_terminology/COASTFILE_TYPES.md\nconcepts_and_terminology/RUNTIMES_AND_SERVICES.md\nconcepts_and_terminology/BARE_SERVICES.md\nconcepts_and_terminology/MIXED_SERVICE_TYPES.md\nconcepts_and_terminology/LOGS.md\nconcepts_and_terminology/EXEC_AND_DOCKER.md\nconcepts_and_terminology/AGENT_SHELLS.md\nconcepts_and_terminology/MCP_SERVERS.md\nconcepts_and_terminology/PERFORMANCE_OPTIMIZATIONS.md\nconcepts_and_terminology/TROUBLESHOOTING.md\n\n# Coastfiles\ncoastfiles/README.md\ncoastfiles/PROJECT.md\ncoastfiles/WORKTREE_DIR.md\ncoastfiles/PORTS.md\ncoastfiles/SHARED_SERVICES.md\ncoastfiles/SERVICES.md\ncoastfiles/SECRETS.md\ncoastfiles/VOLUMES.md\ncoastfiles/ASSIGN.md\ncoastfiles/INHERITANCE.md\ncoastfiles/AGENT_SHELL.md\ncoastfiles/MCP.md\n\n# Receitas\nrecipes/README.md\nrecipes/FULLSTACK_MONOREPO.md\n", + "installation_prompt.txt": "Você está instalando o Coasts neste projeto. Coast (host em contêiner) é uma ferramenta de CLI que executa vários ambientes de desenvolvimento isolados em uma única máquina usando contêineres Docker-in-Docker. Cada ambiente recebe suas próprias portas, volumes e runtime — ideal para fluxos de trabalho paralelos com worktrees.\n\nSeu trabalho: analisar este projeto e gerar um Coastfile (um arquivo TOML chamado \"Coastfile\" na raiz do projeto).\n\n=== DOCUMENTAÇÃO ===\n\nO Coast tem documentação embutida acessível a partir da CLI. Use-a para entender o esquema completo do Coastfile, estratégias de volume, comportamento de assign e outras opções de configuração antes de gerar um Coastfile.\n\nNavegue pela árvore de docs:\n\n coast docs\n\nIsso imprime a árvore completa de docs. Comece lendo os arquivos README — eles fornecem índices para ajudar você a encontrar a documentação certa para cada tópico:\n\n coast docs --path README.md\n coast docs --path coastfiles/README.md\n coast docs --path concepts_and_terminology/README.md\n\nLeia um doc específico:\n\n coast docs --path coastfiles/PROJECT.md\n coast docs --path coastfiles/VOLUMES.md\n\nPesquise nos docs (busca semântica — descreva o que você está procurando em linguagem natural):\n\n coast search-docs \"how do volume strategies work\"\n coast search-docs \"shared postgres across instances\"\n coast search-docs \"secret injection from environment variables\"\n\nUse os docs para tomar decisões informadas sobre a configuração do Coastfile deste projeto. A seção coastfiles/ cobre cada diretiva do Coastfile em detalhe.\n\n=== ESQUEMA DO COASTFILE (referência rápida) ===\n\n[coast] — Obrigatório. Metadados do projeto.\n\n name (string, required) Identificador do projeto usado na nomeação de contêiner/volume.\n compose (string, optional) Caminho para docker-compose.yml relativo ao Coastfile.\n runtime (string, optional) \"dind\" (padrão), \"sysbox\" ou \"podman\".\n root (string, optional) Sobrescrita da raiz do projeto (relativa ou absoluta).\n worktree_dir (string or array, optional) Diretório ou diretórios para worktrees do git (padrão: \".worktrees\"). Aceita uma única string ou um array de strings. Auto-detectado a partir de worktrees existentes em runtime.\n\n[coast.setup] — Opcional. Personalize o contêiner DinD em si.\n\n packages (array of strings) Pacotes Alpine para instalar (por exemplo [\"nodejs\", \"npm\", \"git\"]).\n run (array of strings) Comandos arbitrários para executar durante o setup.\n\n[ports] — Obrigatório (pelo menos um). Mapa de nome lógico para número de porta.\n Essas portas são encaminhadas para o host quando o coast é feito checkout.\n\n Exemplo:\n [ports]\n web = 3000\n api = 8080\n postgres = 5432\n\n[volumes.*] — Opcional. Configuração por volume.\n\n strategy \"isolated\" (padrão) ou \"shared\"\n service Nome do serviço do Compose que é dono deste volume.\n mount Caminho de montagem dentro do contêiner do serviço.\n snapshot_source (somente isolated) Semeia a partir de um nome de volume existente.\n\n Exemplo:\n [volumes.postgres_data]\n strategy = \"isolated\"\n service = \"db\"\n mount = \"/var/lib/postgresql/data\"\n\n[secrets.*] — Opcional. Extração e injeção de segredos.\n\n extractor \"file\", \"env\", \"command\" ou \"macos-keychain\"\n inject \"env:VAR_NAME\" ou \"file:/path/in/container\"\n ttl Expiração opcional (por exemplo \"1h\", \"30m\").\n\n Parâmetros específicos do extractor:\n file: path = \"./path/to/secret\"\n env: var = \"HOST_ENV_VAR\"\n command: run = \"echo secret-value\"\n macos-keychain: item = \"keychain-item-name\"\n\n Exemplo:\n [secrets.db_password]\n extractor = \"env\"\n var = \"DB_PASSWORD\"\n inject = \"env:DATABASE_PASSWORD\"\n\n[inject] — Opcional. Injeção de arquivo/env do host que não é segredo.\n\n env Array de nomes de variáveis de ambiente do host para encaminhar.\n files Array de caminhos de arquivos do host para montar.\n\n Exemplo:\n [inject]\n env = [\"NODE_ENV\", \"DEBUG\"]\n files = [\"~/.ssh/id_ed25519\", \"~/.gitconfig\"]\n\n[shared_services.*] — Opcional. Serviços no daemon Docker do host compartilhados entre instâncias.\n\n image Imagem Docker.\n ports Array de números de porta.\n volumes Array de montagens de volume.\n env Tabela inline de variáveis de ambiente.\n auto_create_db (bool) Criar automaticamente um banco por instância.\n inject Injetar string de conexão nos contêineres do coast.\n\n Exemplo:\n [shared_services.postgres]\n image = \"postgres:16-alpine\"\n ports = [5432]\n volumes = [\"postgres_data:/var/lib/postgresql/data\"]\n env = { POSTGRES_USER = \"dev\", POSTGRES_PASSWORD = \"dev\", POSTGRES_DB = \"app\" }\n auto_create_db = true\n inject = \"env:DATABASE_URL\"\n\n[assign] — Opcional. Controla o que acontece ao trocar de branch (coast assign).\n\n default \"none\", \"restart\" ou \"rebuild\"\n [assign.services] Sobrescritas por serviço.\n [assign.rebuild_triggers] Globs de arquivo por serviço que disparam rebuild.\n\n Exemplo:\n [assign]\n default = \"none\"\n [assign.services]\n api = \"restart\"\n worker = \"rebuild\"\n [assign.rebuild_triggers]\n worker = [\"Dockerfile\", \"package.json\"]\n\n[services.*] — Opcional. Serviços de processo simples (sem docker-compose).\n\n command Comando de shell para executar.\n port Número de porta.\n restart \"on-failure\" ou \"always\".\n\n Exemplo:\n [services.web]\n command = \"node server.js\"\n port = 3000\n restart = \"on-failure\"\n\n=== EXEMPLO: Mínimo (sem compose) ===\n\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[ports]\napp = 3000\n\n=== EXEMPLO: Com docker-compose ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\npostgres = 5432\nredis = 6379\n\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n\n=== EXEMPLO: Com secrets ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\n\n[secrets.api_key]\nextractor = \"env\"\nvar = \"API_KEY\"\ninject = \"env:API_KEY\"\n\n[secrets.ssh_key]\nextractor = \"file\"\npath = \"~/.ssh/id_ed25519\"\ninject = \"file:/run/secrets/ssh_key\"\n\n=== PRINCIPAIS TRADEOFFS PARA DISCUTIR COM O USUÁRIO ===\n\nAntes de gerar o Coastfile, pergunte ao usuário sobre quaisquer escolhas de configuração ambíguas. Aqui estão as principais:\n\nEstratégia de banco de dados e infraestrutura — há três opções para serviços como postgres e redis:\n - Volumes isolados (padrão): cada instância do Coast obtém sua própria cópia dos dados dentro do contêiner DinD. As instâncias não podem interferir entre si. Melhor quando você quer estado de banco por branch.\n - Volumes compartilhados: todas as instâncias leem e escrevem o mesmo volume dentro de seus contêineres DinD. Economiza espaço em disco, mas escritas concorrentes de múltiplas instâncias podem corromper dados.\n - Serviços compartilhados: execute o banco no daemon Docker do host em vez de dentro de cada Coast. Todas as instâncias conectam a um único servidor compartilhado. Usa a menor quantidade de memória, suporta auto_create_db para bancos por instância em um único postgres, e os dados sobrevivem à deleção da instância. Melhor para times grandes ou máquinas com pouca memória.\n - Se o projeto tiver um banco de dados, pergunte ao usuário qual abordagem ele quer. Explique os tradeoffs — isolated é a mais segura, shared services é a mais eficiente em memória.\n\nEstratégia de assign — o que acontece ao alternar um Coast entre worktrees:\n - \"none\": não fazer nada (para serviços como postgres/redis que não mudam entre branches).\n - \"restart\": reiniciar o contêiner (para serviços interpretados que só precisam de reinício do processo).\n - \"rebuild\": reconstruir a imagem Docker e reiniciar (para serviços em que a mudança de branch afeta o Dockerfile ou dependências de build).\n - Se o projeto tiver múltiplos serviços, pergunte quais precisam de rebuild vs restart ao trocar de branch.\n\n=== INSTRUÇÕES ===\n\n1. Examine a estrutura deste projeto. Se houver um docker-compose.yml, leia-o para identificar serviços, portas e volumes.\n2. Detecte o diretório de worktree do git existente. Execute `git worktree list` para verificar se o projeto já tem worktrees do git configuradas.\n - Se existirem worktrees, examine seus caminhos para determinar o diretório pai comum (por exemplo, se as worktrees estão em `../.worktrees/feat-a` e `../.worktrees/feat-b`, o worktree_dir é `\"../.worktrees\"`).\n - Defina `worktree_dir` no Coastfile para corresponder ao diretório detectado.\n - Se não existirem worktrees, omita `worktree_dir` (o Coast usa \".worktrees\" por padrão). NÃO use \".coasts\" — isso polui o projeto com um diretório com marca do Coast.\n3. Pergunte ao usuário se ele usa algum destes coding harnesses com este projeto:\n - **Claude Code** — worktrees em `.claude/worktrees`\n - **OpenAI Codex** — worktrees em `~/.codex/worktrees`\n - **Cursor** — worktrees em `~/.cursor/worktrees/` (onde `` é o nome do coast em `[coast] name`)\n - **Conductor** — worktrees em `~/conductor/workspaces/`\n - **T3 Code** — worktrees em `~/.t3/worktrees/`\n Para cada harness que o usuário selecionar, inclua seu diretório de worktree no array `worktree_dir`. Combine-os com qualquer diretório detectado na etapa 2. Se o usuário não selecionar nenhum e nenhuma worktree tiver sido detectada na etapa 2, omita `worktree_dir` (o Coast usa \".worktrees\" por padrão).\n4. Leia os docs relevantes do Coast (use `coast docs` e `coast search-docs`) para entender estratégias de volume, comportamento de assign e quaisquer opções de configuração que se apliquem à stack deste projeto.\n5. Pergunte ao usuário sobre quaisquer escolhas de configuração ambíguas (veja os tradeoffs acima). Não chute — explique as opções e deixe que ele decida.\n6. Gere um Coastfile na raiz do projeto com base na análise do projeto e na entrada do usuário.\n7. Se o projeto não tiver docker-compose.yml, use [services.*] para definições de processos simples ou [coast.setup] para instalar dependências.\n8. Execute `coast build`. Se falhar, verifique o erro e consulte os docs (`coast search-docs \"\"`) para solucionar.\n9. Execute `coast run dev-1`. Se falhar, verifique o erro e consulte os docs.\n10. Execute `coast ui` para abrir o dashboard do Coastguard (isto é para o usuário quando você terminar).\n", + "skills_prompt.txt": "# Coast Runtime\n\nEste projeto usa Coasts — runtimes conteinerizados para executar serviços, testes\ne outros comandos de runtime. O sistema de arquivos é compartilhado entre o host e o\ncontêiner, então edições de arquivos em qualquer lado ficam visíveis para ambos imediatamente.\n\n## Discovery\n\nAntes do primeiro comando de runtime em uma sessão, execute:\n\n coast lookup\n\nIsso imprime o nome da instância, portas e comandos de exemplo. Use o nome da instância\nda saída para todos os comandos subsequentes.\n\n## What runs where\n\nO sistema de arquivos é compartilhado, então use `coast exec` apenas para coisas que precisam do\nruntime do contêiner (bancos de dados, serviços, testes de integração). Todo o resto\né executado diretamente no host.\n\nUse `coast exec` para:\n- Testes que precisam de serviços em execução (testes unitários integrados com serviços ou bancos de dados, testes de integração, testes de API)\n- Reinicializações de serviços ou operações de compose\n- Qualquer coisa que se comunique com bancos de dados, caches ou outros serviços em contêineres\n\nExecute diretamente no host:\n- Linting, verificação de tipos, formatação\n- Operações de git\n- Testes com Playwright e testes de navegador\n- Instalação de dependências do lado do host (npm install, pip install)\n- Busca de arquivos, geração de código, análise estática\n\nExemplo:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n coast exec --service # service shell\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nSe `coast lookup` não retornar correspondência, execute `coast ls` para ver o que existe.\n\nSe um Coast não atribuído já estiver em execução para este projeto, prefira atribuir\nsua worktree a ele em vez de criar um novo:\n\n coast assign -w \n\nUm Coast já ocupado também pode ser reatribuído com `coast assign`, mas confirme\ncom o usuário primeiro, porque isso vai interromper o slot atual.\n\nSe nenhum Coast estiver em execução, pergunte ao usuário antes de criar um — Coasts podem consumir\nmuita memória:\n\n coast run -w \n\nUm projeto precisa ser compilado antes que instâncias possam ser criadas. Se `coast run` falhar\nporque não existe nenhum build, execute `coast build` primeiro.\n\n## Coastfile setup\n\nSe o projeto ainda não tiver um Coastfile, ou se você precisar modificar o\nCoastfile, leia primeiro a documentação do Coastfile:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nAntes de supor algo sobre o comportamento do Coast, explore a documentação:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Sempre execute `coast lookup` antes do seu primeiro comando de runtime em uma sessão.\n- Use `coast exec` apenas para coisas que precisam do runtime do contêiner.\n- Use `coast exec --service ` quando precisar executar algo dentro de um contêiner de app/serviço.\n- Execute linting, verificação de tipos, formatação e git diretamente no host.\n- Use `coast docs` ou `coast search-docs` antes de supor algo sobre o comportamento do Coast.\n- Não execute serviços diretamente no host quando o projeto espera Coast.\n\n---\nname: coasts\ndescription: Inspecione e controle instâncias do Coast para o checkout atual. Use\n quando o usuário disser \"/coasts\", pedir para atribuir ou reatribuir um Coast, quiser\n executar comandos ou ler logs no Coast correspondente, quiser criar um novo Coast,\n ou pedir explicitamente para abrir a UI do Coast.\n---\n\n# Coasts\n\nUse a CLI do Coast diretamente. Não adicione wrappers.\n\n## Orient Yourself\n\nComece explorando a CLI e a documentação:\n\n coast # see all available commands\n coast docs # list all doc pages\n coast search-docs \"your question\" # semantic search\n\nQuando qualquer aspecto do comportamento do Coast estiver incerto, leia a documentação antes de supor:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\nEncaminhe as solicitações para um destes modos:\n\n1. **Use Coast** — execute `coast lookup`, depois use `coast exec`, `coast ps`,\n ou `coast logs` com a instância correspondente.\n2. **Create or Assign** — execute `coast ls`, depois `coast run` para criar um novo\n Coast ou `coast assign` para redirecionar um existente.\n3. **Open UI** — execute `coast ui`.\n\n## What Runs Where\n\nO host e o Coast compartilham o sistema de arquivos. Use `coast exec` apenas para coisas\nque precisam de serviços em execução dentro do contêiner.\n\n**Use `coast exec` for:**\n- Testes de integração, testes de API, qualquer coisa que precise de bancos de dados ou serviços\n- Reinicializações de serviços, operações de compose\n- Comandos que se comunicam com processos disponíveis apenas no contêiner\n\n**Run on the host:**\n- Linting (`eslint`, `rubocop`, `golangci-lint`)\n- Verificação de tipos (`tsc --noEmit`, `go vet`)\n- Formatação (`prettier`, `gofmt`)\n- Operações de git\n- Testes com Playwright e testes de navegador\n- Análise estática, geração de código\n- Instalação de pacotes (`npm install`, `pip install`)\n\n## Create and Assign\n\nQuando `coast lookup` não retornar correspondência:\n\n1. Execute `coast ls` para ver os slots disponíveis.\n2. Prefira `coast run -w ` para criar e atribuir em uma única etapa.\n3. Se ainda não existir nenhum build, execute `coast build` primeiro.\n4. Após criar, execute `coast lookup` novamente para confirmar.\n\nQuando você quiser trocar um Coast existente para uma worktree diferente:\n\n coast assign -w \n\nIsso também funciona para um Coast já atribuído ou com checkout feito, mas pergunte ao usuário\nprimeiro antes de reatribuir um slot ocupado.\n\n## Coastfile Setup\n\nSe o projeto precisar de um Coastfile novo ou modificado, leia a documentação primeiro:\n\n coast docs --path coastfiles/README.md\n\nA documentação do Coastfile cobre configuração de compose, portas, volumes, segredos, serviços\ncompartilhados, serviços bare e herança.\n\n## Safety Rules\n\n- Execute `coast lookup` antes de agir e novamente após qualquer mudança de topologia.\n- Pergunte antes de `coast assign`, `coast unassign` ou `coast checkout` se isso puder\n interromper um slot existente.\n- Prefira criar um novo Coast em vez de reutilizar um que já tenha checkout feito ou já esteja atribuído,\n a menos que o usuário queira explicitamente que o slot existente seja reatribuído.\n- Use `coast docs` ou `coast search-docs` antes de supor algo.\n", "coastfiles/README.md": "# Coastfiles\n\nUm Coastfile é um arquivo de configuração TOML que fica na raiz do seu projeto. Ele informa ao Coast tudo o que ele precisa saber para construir e executar ambientes de desenvolvimento isolados para esse projeto — quais serviços executar, quais portas encaminhar, como lidar com dados e como gerenciar segredos.\n\nTodo projeto Coast precisa de pelo menos um Coastfile. O arquivo é sempre nomeado `Coastfile` (C maiúsculo, sem extensão). Se você precisar de variantes para diferentes fluxos de trabalho, crie Coastfiles tipados como `Coastfile.light` ou `Coastfile.snap` que [herdam do base](INHERITANCE.md).\n\nPara um entendimento mais profundo de como os Coastfiles se relacionam com o restante do Coast, veja [Coasts](../concepts_and_terminology/COASTS.md) e [Builds](../concepts_and_terminology/BUILDS.md).\n\n## Quickstart\n\nO menor Coastfile possível:\n\n```toml\n[coast]\nname = \"my-app\"\n```\n\nIsso fornece a você um contêiner DinD no qual você pode entrar com `coast exec`. A maioria dos projetos vai querer ou uma referência `compose` ou [serviços bare](SERVICES.md):\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\napi = 8080\n```\n\nOu sem compose, usando serviços bare:\n\n```toml\n[coast]\nname = \"my-app\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\nrestart = \"on-failure\"\n\n[ports]\nweb = 3000\n```\n\nExecute `coast build` e depois `coast run dev-1` e você terá um ambiente isolado.\n\n## Example Coastfiles\n\n### Projeto simples com serviço bare\n\nUm app Next.js sem arquivo compose. O Coast instala Node, executa `npm install` e inicia o servidor de desenvolvimento diretamente.\n\n```toml\n[coast]\nname = \"my-crm\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --turbopack --port 3002 --hostname 0.0.0.0\"\nport = 3002\nrestart = \"on-failure\"\n\n[ports]\nweb = 3002\n```\n\n### Projeto full-stack com compose\n\nUm projeto com múltiplos serviços, com bancos de dados compartilhados, segredos, estratégias de volume e configuração personalizada.\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./infra/docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"python3\", \"curl\", \"git\", \"bash\", \"ca-certificates\", \"wget\"]\nrun = [\n \"ARCH=$(uname -m | sed 's/aarch64/arm64/' | sed 's/x86_64/amd64/') && wget -qO /tmp/go.tar.gz https://go.dev/dl/go1.24.1.linux-${ARCH}.tar.gz && tar -C /usr/local -xzf /tmp/go.tar.gz && rm /tmp/go.tar.gz\",\n \"GOBIN=/usr/local/bin go install github.com/air-verse/air@v1.61.7\",\n]\n\n[ports]\nweb = 3000\nbackend = 8080\npostgres = 5432\nredis = 6379\n\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\" }\n\n[shared_services.redis]\nimage = \"redis:7\"\nports = [6379]\n\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n\n[secrets.db_password]\nextractor = \"env\"\nvar = \"DB_PASSWORD\"\ninject = \"env:DB_PASSWORD\"\n\n[omit]\nservices = [\"monitoring\", \"admin-panel\", \"nginx-proxy\"]\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### Variante leve para testes (herança)\n\nEstende o Coastfile base, mas o reduz ao mínimo necessário para executar testes de backend. Sem portas, sem serviços compartilhados, bancos de dados isolados.\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n\n[unset]\nports = [\"web\", \"backend\", \"postgres\", \"redis\"]\nshared_services = [\"postgres\", \"redis\"]\n\n[omit]\nservices = [\"redis\", \"backend\", \"web\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend-test = \"rebuild\"\n```\n\n### Variante inicializada por snapshot\n\nCada instância de coast inicia com uma cópia dos volumes de banco de dados existentes no host e depois diverge independentemente.\n\n```toml\n[coast]\nextends = \"Coastfile\"\n\n[unset]\nshared_services = [\"postgres\", \"redis\", \"mongodb\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_mongodb_data\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n\n## Conventions\n\n- O arquivo deve ser nomeado `Coastfile` (C maiúsculo, sem extensão) e ficar na raiz do projeto.\n- Variantes tipadas usam o padrão `Coastfile.{type}` — por exemplo `Coastfile.light`, `Coastfile.snap`. Veja [Inheritance and Types](INHERITANCE.md).\n- O nome reservado `Coastfile.default` não é permitido.\n- A sintaxe TOML é usada em todo o documento. Todos os cabeçalhos de seção usam `[colchetes]` e entradas nomeadas usam `[section.name]` (não array-of-tables).\n- Você não pode usar `compose` e `[services]` no mesmo Coastfile — escolha um.\n- Caminhos relativos (para `compose`, `root` etc.) são resolvidos em relação ao diretório pai do Coastfile.\n\n## Reference\n\n| Page | Sections | What it covers |\n|------|----------|----------------|\n| [Project and Setup](PROJECT.md) | `[coast]`, `[coast.setup]` | Nome, caminho do compose, runtime, diretório de worktree, configuração do contêiner |\n| [Worktree Directories](WORKTREE_DIR.md) | `worktree_dir`, `default_worktree_dir` | Diretórios de worktree locais e externos, caminhos com til, integração com Codex/Claude |\n| [Ports](PORTS.md) | `[ports]`, `[egress]` | Encaminhamento de portas, declarações de egress, porta primária |\n| [Volumes](VOLUMES.md) | `[volumes.*]` | Estratégias de volume isoladas, compartilhadas e inicializadas por snapshot |\n| [Shared Services](SHARED_SERVICES.md) | `[shared_services.*]` | Bancos de dados e serviços de infraestrutura no nível do host |\n| [Secrets](SECRETS.md) | `[secrets.*]`, `[inject]` | Extração, injeção e encaminhamento de segredos do env/arquivo do host |\n| [Bare Services](SERVICES.md) | `[services.*]` | Execução de processos diretamente sem Docker Compose |\n| [Agent Shell](AGENT_SHELL.md) | `[agent_shell]` | Runtimes TUI de agente conteinerizados |\n| [MCP Servers](MCP.md) | `[mcp.*]`, `[mcp_clients.*]` | Servidores MCP internos e com proxy do host, conectores de cliente |\n| [Assign](ASSIGN.md) | `[assign]` | Comportamento de troca de branch por serviço |\n| [Inheritance and Types](INHERITANCE.md) | `extends`, `includes`, `[unset]`, `[omit]` | Coastfiles tipados, composição e sobrescritas |\n", "coastfiles/AGENT_SHELL.md": "# Shell do Agente\n\n> **Na maioria dos fluxos de trabalho, você não precisa containerizar seu agente de codificação.** Como as Coasts compartilham o [sistema de arquivos](../concepts_and_terminology/FILESYSTEM.md) com a sua máquina host, a abordagem mais simples é executar o agente no host e usar [`coast exec`](../concepts_and_terminology/EXEC_AND_DOCKER.md) para tarefas pesadas em tempo de execução, como testes de integração. Shells do agente são para casos em que você especificamente quer o agente rodando dentro do container — por exemplo, para dar a ele acesso direto ao daemon Docker interno ou para isolar completamente o ambiente.\n\nA seção `[agent_shell]` configura um TUI de agente — como Claude Code ou Codex — para rodar dentro do container do Coast. Quando presente, o Coast automaticamente inicia uma sessão PTY persistente executando o comando configurado quando uma instância inicia.\n\nPara uma visão completa de como shells do agente funcionam — o modelo de agente ativo, envio de entrada, ciclo de vida e recuperação — veja [Shells do Agente](../concepts_and_terminology/AGENT_SHELLS.md).\n\n## Configuração\n\nA seção tem um único campo obrigatório: `command`.\n\n```toml\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\n### `command` (obrigatório)\n\nO comando de shell a executar no PTY do agente. Isso normalmente é uma CLI de agente de codificação que você instalou via `[coast.setup]`.\n\nO comando é executado dentro do container DinD em `/workspace` (a raiz do projeto). Ele não é um serviço do compose — ele roda ao lado da sua stack do compose ou serviços bare, não dentro deles.\n\n## Ciclo de vida\n\n- A shell do agente é iniciada automaticamente no `coast run`.\n- No [Coastguard](../concepts_and_terminology/COASTGUARD.md), ela aparece como uma aba persistente \"Agent\" que não pode ser fechada.\n- Se o processo do agente encerrar, o Coast pode iniciá-lo novamente.\n- Você pode enviar entrada para uma shell do agente em execução via `coast agent-shell input`.\n\n## Exemplos\n\n### Claude Code\n\nInstale o Claude Code em `[coast.setup]`, configure credenciais via [secrets](SECRETS.md), depois configure a shell do agente:\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"git\", \"bash\"]\nrun = [\n \"npm install -g @anthropic-ai/claude-code\",\n \"mkdir -p /root/.claude\",\n]\n\n[secrets.claude_credentials]\nextractor = \"keychain\"\nservice = \"Claude Code-credentials\"\ninject = \"file:/root/.claude/.credentials.json\"\n\n[agent_shell]\ncommand = \"cd /workspace; exec claude --dangerously-skip-permissions --effort high\"\n```\n\n### Shell do agente simples\n\nUma shell do agente mínima para testar se o recurso funciona:\n\n```toml\n[coast]\nname = \"test-agent\"\n\n[coast.setup]\npackages = [\"bash\"]\n\n[agent_shell]\ncommand = \"exec sh -c 'while true; do echo agent-heartbeat; sleep 5; done'\"\n```\n", "coastfiles/ASSIGN.md": "# Atribuir\n\nA seção `[assign]` controla o que acontece com os serviços dentro de uma instância do Coast quando você troca de branches com `coast assign`. Cada serviço pode ser configurado com uma estratégia diferente dependendo se ele precisa de um rebuild completo, um restart, um hot-reload ou nada.\n\nPara entender como `coast assign` e `coast unassign` funcionam em tempo de execução, veja [Assign](../concepts_and_terminology/ASSIGN.md).\n\n## `[assign]`\n\n### `default`\n\nA ação padrão aplicada a todos os serviços na troca de branch. O padrão é `\"restart\"` se a seção `[assign]` inteira for omitida.\n\n- **`\"none\"`** — não faz nada. O serviço continua em execução como está. Bom para bancos de dados e caches que não dependem de código.\n- **`\"hot\"`** — o código já está montado ao vivo via o [filesystem](../concepts_and_terminology/FILESYSTEM.md), então o serviço aplica as mudanças automaticamente (ex.: via um file watcher ou hot-reload). Não é necessário reiniciar o container.\n- **`\"restart\"`** — reinicia o container do serviço. Use quando o serviço lê o código na inicialização, mas não precisa de um rebuild completo da imagem.\n- **`\"rebuild\"`** — faz rebuild da imagem Docker do serviço e reinicia. Necessário quando o código é incorporado na imagem via `COPY` ou `ADD` no Dockerfile.\n\n```toml\n[assign]\ndefault = \"none\"\n```\n\n### `[assign.services]`\n\nOverrides por serviço. Cada chave é um nome de serviço do compose, e o valor é uma das quatro ações acima.\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\nIsso permite deixar bancos de dados e caches intocados (`\"none\"` via o default) enquanto faz rebuild ou restart apenas dos serviços que dependem do código que mudou.\n\n### `[assign.rebuild_triggers]`\n\nPadrões de arquivo que forçam um rebuild para serviços específicos, mesmo que a ação padrão deles seja algo mais leve. Cada chave é um nome de serviço, e o valor é uma lista de caminhos de arquivo ou padrões.\n\n```toml\n[assign]\ndefault = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\", \"package-lock.json\"]\n```\n\n### `exclude_paths`\n\nUma lista de caminhos a excluir da sincronização do worktree durante `coast assign`. Útil em monorepos grandes onde certos diretórios são irrelevantes para os serviços em execução no Coast e, caso contrário, deixariam a operação de assign mais lenta.\n\n```toml\n[assign]\ndefault = \"none\"\nexclude_paths = [\"apps/ide\", \"apps/extension\", \"apps/ide-extension\"]\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n## Exemplos\n\n### Fazer rebuild do app, deixar todo o resto como está\n\nQuando o seu serviço de app incorpora código na imagem Docker, mas seus bancos de dados são independentes de mudanças de código:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\n### Hot-reload do frontend e backend\n\nQuando ambos os serviços usam file watchers (ex.: servidor dev do Next.js, Go air, nodemon) e o código está montado ao vivo:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### Rebuild por serviço com triggers\n\nO serviço de API normalmente apenas reinicia, mas se `Dockerfile` ou `package.json` mudou, ele faz rebuild:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napi = \"restart\"\nworker = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\"]\n```\n\n### Rebuild completo para tudo\n\nQuando todos os serviços incorporam código nas suas imagens:\n\n```toml\n[assign]\ndefault = \"rebuild\"\n```\n", @@ -2418,19 +2471,19 @@ "coastfiles/SERVICES.md": "# Serviços Bare\n\n> **Nota:** Serviços bare são executados diretamente dentro do contêiner Coast como processos simples — eles não são conteinerizados. Se seus serviços já estão dockerizados, use `compose` em vez disso. Serviços bare são mais adequados para configurações simples em que você quer evitar a sobrecarga de escrever um Dockerfile e um docker-compose.yml.\n\nAs seções `[services.*]` definem processos que o Coast executa diretamente dentro do contêiner DinD, sem Docker Compose. Esta é uma alternativa ao uso de um arquivo `compose` — você não pode usar ambos no mesmo Coastfile.\n\nServiços bare são supervisionados pelo Coast com captura de logs e políticas de reinício opcionais. Para um contexto mais aprofundado sobre como serviços bare funcionam, suas limitações e quando migrar para compose, veja [Bare Services](../concepts_and_terminology/BARE_SERVICES.md).\n\n## Definindo um serviço\n\nCada serviço é uma seção TOML nomeada sob `[services]`. O campo `command` é obrigatório.\n\n```toml\n[services.web]\ncommand = \"node server.js\"\nport = 3000\n```\n\n### `command` (obrigatório)\n\nO comando do shell a ser executado. Não deve estar vazio nem conter apenas espaços em branco.\n\n```toml\n[services.web]\ncommand = \"npx next dev --turbopack --port 3000 --hostname 0.0.0.0\"\n```\n\n### `port`\n\nA porta em que o serviço escuta. Usada para verificação de saúde e integração de encaminhamento de portas. Deve ser diferente de zero se especificada.\n\n```toml\n[services.web]\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\n```\n\n### `restart`\n\nPolítica de reinício se o processo encerrar. O padrão é `\"no\"`.\n\n- `\"no\"` — não reiniciar\n- `\"on-failure\"` — reiniciar apenas se o processo encerrar com um código diferente de zero\n- `\"always\"` — sempre reiniciar\n\n```toml\n[services.web]\ncommand = \"node server.js\"\nport = 3000\nrestart = \"on-failure\"\n```\n\n### `install`\n\nComandos a serem executados antes de iniciar o serviço (por exemplo, instalar dependências). Aceita uma única string ou um array de strings.\n\n```toml\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\n```\n\n```toml\n[services.web]\ninstall = [\"npm install\", \"npm run build\"]\ncommand = \"npm start\"\nport = 3000\n```\n\n## Exclusão mútua com compose\n\nUm Coastfile não pode definir tanto `compose` quanto `[services]`. Se você tiver um campo `compose` em `[coast]`, adicionar qualquer seção `[services.*]` é um erro. Escolha uma abordagem por Coastfile.\n\nSe você precisar de alguns serviços conteinerizados via compose e alguns rodando como bare, use compose para todos eles — veja [a orientação de migração em Bare Services](../concepts_and_terminology/BARE_SERVICES.md) sobre como migrar de serviços bare para compose.\n\n## Exemplos\n\n### Aplicativo Next.js de serviço único\n\n```toml\n[coast]\nname = \"my-frontend\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --turbopack --port 3002 --hostname 0.0.0.0\"\nport = 3002\nrestart = \"on-failure\"\n\n[ports]\nweb = 3002\n```\n\n### Servidor web com worker em segundo plano\n\n```toml\n[coast]\nname = \"my-app\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"node server.js\"\nport = 3000\nrestart = \"on-failure\"\n\n[services.worker]\ncommand = \"node worker.js\"\nrestart = \"always\"\n\n[ports]\nweb = 3000\n```\n\n### Serviço Python com instalação em várias etapas\n\n```toml\n[coast]\nname = \"ml-service\"\n\n[coast.setup]\npackages = [\"python3\", \"py3-pip\"]\n\n[services.api]\ninstall = [\"pip install -r requirements.txt\", \"python manage.py migrate\"]\ncommand = \"python manage.py runserver 0.0.0.0:8000\"\nport = 8000\nrestart = \"on-failure\"\n\n[ports]\napi = 8000\n```\n", "coastfiles/SHARED_SERVICES.md": "# Serviços Compartilhados\n\nAs seções `[shared_services.*]` definem serviços de infraestrutura — bancos de dados, caches, brokers de mensagens — que rodam no daemon do Docker do host, em vez de dentro de containers individuais do Coast. Várias instâncias do Coast se conectam ao mesmo serviço compartilhado por uma rede bridge.\n\nPara saber como os serviços compartilhados funcionam em tempo de execução, gerenciamento de ciclo de vida e solução de problemas, consulte [Serviços Compartilhados](../concepts_and_terminology/SHARED_SERVICES.md).\n\n## Definindo um serviço compartilhado\n\nCada serviço compartilhado é uma seção TOML nomeada sob `[shared_services]`. O campo `image` é obrigatório; todo o resto é opcional.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\n```\n\n### `image` (obrigatório)\n\nA imagem Docker a ser executada no daemon do host.\n\n### `ports`\n\nLista de portas que o serviço expõe. O Coast aceita tanto portas simples do container quanto mapeamentos no estilo Docker Compose `\"HOST:CONTAINER\"`.\n\n```toml\n[shared_services.redis]\nimage = \"redis:7-alpine\"\nports = [6379]\n```\n\n```toml\n[shared_services.postgis]\nimage = \"ghcr.io/baosystems/postgis:12-3.3\"\nports = [\"5433:5432\"]\n```\n\n- Um inteiro simples como `6379` é uma forma abreviada de `\"6379:6379\"`.\n- Uma string mapeada como `\"5433:5432\"` publica o serviço compartilhado na porta do host\n `5433`, enquanto o mantém acessível dentro dos Coasts em `service-name:5432`.\n- As portas do host e do container devem ambas ser diferentes de zero.\n\n### `volumes`\n\nStrings de bind de volume do Docker para persistir dados. Esses são volumes do Docker no nível do host, não volumes gerenciados pelo Coast.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\n```\n\n### `env`\n\nVariáveis de ambiente passadas para o container do serviço.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\", POSTGRES_DB = \"mydb\" }\n```\n\n### `auto_create_db`\n\nQuando `true`, o Coast cria automaticamente um banco de dados por instância dentro do serviço compartilhado para cada instância do Coast. O padrão é `false`.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\nauto_create_db = true\n```\n\n### `inject`\n\nInjeta as informações de conexão do serviço compartilhado nas instâncias do Coast como uma variável de ambiente ou arquivo. Usa o mesmo formato `env:NAME` ou `file:/path` que [segredos](SECRETS.md).\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\ninject = \"env:DATABASE_URL\"\n```\n\n## Ciclo de vida\n\nOs serviços compartilhados iniciam automaticamente quando a primeira instância do Coast que os referencia é executada. Eles continuam rodando através de `coast stop` e `coast rm` — remover uma instância não afeta os dados do serviço compartilhado. Somente `coast shared rm` para e remove um serviço compartilhado.\n\nBancos de dados por instância criados por `auto_create_db` também sobrevivem à exclusão da instância. Use `coast shared-services rm` para remover o serviço e seus dados completamente.\n\n## Quando usar serviços compartilhados vs volumes\n\nUse serviços compartilhados quando múltiplas instâncias do Coast precisam falar com o mesmo servidor de banco de dados (por exemplo, um Postgres compartilhado onde cada instância recebe seu próprio banco de dados). Use [estratégias de volume](VOLUMES.md) quando você quiser controlar como os dados de um serviço interno do compose são compartilhados ou isolados.\n\n## Exemplos\n\n### Postgres, Redis e MongoDB\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\", POSTGRES_MULTIPLE_DATABASES = \"dev_db,test_db\" }\n\n[shared_services.redis]\nimage = \"redis:7\"\nports = [6379]\nvolumes = [\"infra_redis_data:/data\"]\n\n[shared_services.mongodb]\nimage = \"mongo:latest\"\nports = [27017]\nvolumes = [\"infra_mongodb_data:/data/db\"]\nenv = { MONGO_INITDB_ROOT_USERNAME = \"myapp\", MONGO_INITDB_ROOT_PASSWORD = \"myapp_pass\" }\n```\n\n### Postgres compartilhado mínimo\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16-alpine\"\nports = [5432]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\", POSTGRES_DB = \"coast_demo\" }\n```\n\n### Postgres compartilhado com mapeamento host/container\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16-alpine\"\nports = [\"5433:5432\"]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\", POSTGRES_DB = \"coast_demo\" }\n```\n\n### Serviços compartilhados com bancos de dados criados automaticamente\n\n```toml\n[shared_services.db]\nimage = \"postgres:16-alpine\"\nports = [5432]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\" }\nauto_create_db = true\n```\n", "coastfiles/VOLUMES.md": "# Volumes\n\nAs seções `[volumes.*]` controlam como volumes Docker nomeados são tratados entre instâncias do Coast. Cada volume é configurado com uma estratégia que determina se as instâncias compartilham dados ou obtêm sua própria cópia independente.\n\nPara uma visão mais ampla do isolamento de dados no Coast — incluindo serviços compartilhados como alternativa — veja [Volumes](../concepts_and_terminology/VOLUMES.md).\n\n## Definindo um volume\n\nCada volume é uma seção TOML nomeada sob `[volumes]`. Três campos são obrigatórios:\n\n- **`strategy`** — `\"isolated\"` ou `\"shared\"`\n- **`service`** — o nome do serviço no compose que usa este volume\n- **`mount`** — o caminho de montagem do volume no container\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## Estratégias\n\n### `isolated`\n\nCada instância do Coast recebe seu próprio volume independente. Os dados não são compartilhados entre instâncias. Os volumes são criados no `coast run` e excluídos no `coast rm`.\n\n```toml\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n```\n\nEsta é a escolha certa para a maioria dos volumes de banco de dados — cada instância começa do zero e pode alterar dados livremente sem afetar outras instâncias.\n\n### `shared`\n\nTodas as instâncias do Coast usam um único volume Docker. Quaisquer dados gravados por uma instância ficam visíveis para todas as outras.\n\n```toml\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n```\n\nVolumes compartilhados nunca são excluídos pelo `coast rm`. Eles persistem até que você os remova manualmente.\n\nO Coast imprime um aviso no momento do build se você usar `shared` em um volume anexado a um serviço do tipo banco de dados. Compartilhar um único volume de banco de dados entre várias instâncias concorrentes pode causar corrupção. Se você precisa de bancos de dados compartilhados, use [shared services](SHARED_SERVICES.md) em vez disso.\n\nBons usos para volumes compartilhados: caches de dependências (Go modules, cache do npm, cache do pip), caches de artefatos de build e outros dados em que gravações concorrentes são seguras ou improváveis.\n\n## Semeadura por snapshot\n\nVolumes isolados podem ser semeados a partir de um volume Docker existente no momento da criação da instância usando `snapshot_source`. Os dados do volume de origem são copiados para o novo volume isolado, que então passa a divergir de forma independente.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n`snapshot_source` só é válido com `strategy = \"isolated\"`. Defini-lo em um volume compartilhado é um erro.\n\nIsso é útil quando você quer que cada instância do Coast comece com um conjunto de dados realista copiado do banco de dados de desenvolvimento no seu host, mas você quer que as instâncias tenham liberdade para alterar esses dados sem afetar a origem ou umas às outras.\n\n## Exemplos\n\n### Bancos de dados isolados, cache de dependências compartilhado\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n```\n\n### Stack completo semeado por snapshot\n\nCada instância começa com uma cópia dos volumes de banco de dados existentes no seu host e então diverge de forma independente.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_mongodb_data\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n\n### Executor de testes com bancos de dados limpos por instância\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"test-redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n", - "coastfiles/WORKTREE_DIR.md": "# Diretórios de Worktree\n\nO campo `worktree_dir` em `[coast]` controla onde as worktrees do git ficam. O Coast usa worktrees do git para dar a cada instância sua própria cópia da base de código em uma branch diferente, sem duplicar o repositório completo.\n\n## Sintaxe\n\n`worktree_dir` aceita uma única string ou um array de strings:\n\n```toml\n# Single directory (default)\nworktree_dir = \".worktrees\"\n\n# Multiple directories\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\nQuando omitido, o padrão é `\".worktrees\"`.\n\n## Tipos de caminho\n\n### Caminhos relativos\n\nCaminhos que não começam com `~/` ou `/` são resolvidos em relação à raiz do projeto. Estes são os mais comuns e não exigem tratamento especial — eles estão dentro do diretório do projeto e ficam automaticamente disponíveis dentro do contêiner do Coast por meio do bind mount padrão `/host-project`.\n\n```toml\nworktree_dir = \".worktrees\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Caminhos com til (`~`) (externos)\n\nCaminhos que começam com `~/` são expandidos para o diretório home do usuário e tratados como diretórios de worktree **externos**. O Coast adiciona um bind mount separado para que o contêiner possa acessá-los.\n\n```toml\nworktree_dir = [\"~/.codex/worktrees\", \".worktrees\"]\n```\n\nÉ assim que você integra com ferramentas que criam worktrees fora da raiz do seu projeto, como o OpenAI Codex (que sempre cria worktrees em `$CODEX_HOME/worktrees`).\n\n### Caminhos absolutos (externos)\n\nCaminhos que começam com `/` também são tratados como externos e recebem seu próprio bind mount.\n\n```toml\nworktree_dir = [\"/shared/worktrees\", \".worktrees\"]\n```\n\n## Como os diretórios externos funcionam\n\nQuando o Coast encontra um diretório de worktree externo (caminho com til ou absoluto), três coisas acontecem:\n\n1. **Bind mount do contêiner** — No momento da criação do contêiner (`coast run`), o caminho do host resolvido é montado via bind no contêiner em `/host-external-wt/{index}`, onde `{index}` é a posição no array `worktree_dir`. Isso torna os arquivos externos acessíveis dentro do contêiner.\n\n2. **Filtragem do projeto** — Diretórios externos podem conter worktrees de vários projetos. O Coast usa `git worktree list --porcelain` (que é inerentemente limitado ao repositório atual) para descobrir apenas as worktrees que pertencem a este projeto. O monitor do git também verifica a propriedade lendo o arquivo `.git` de cada worktree e checando se seu ponteiro `gitdir:` resolve de volta para o repositório atual.\n\n3. **Remontagem do workspace** — Quando você usa `coast assign` para uma worktree externa, o Coast remonta `/workspace` a partir do caminho do bind mount externo em vez do caminho usual `/host-project/{dir}/{name}`.\n\n## Nomenclatura de worktrees externas\n\nWorktrees externas com uma branch em checkout aparecem pelo nome da branch, da mesma forma que worktrees locais.\n\nWorktrees externas em **detached HEAD** (comum no Codex) aparecem usando seu caminho relativo dentro do diretório externo. Por exemplo, uma worktree do Codex em `~/.codex/worktrees/a0db/coastguard-platform` aparece como `a0db/coastguard-platform` na UI e na CLI.\n\n## `default_worktree_dir`\n\nControla qual diretório é usado quando o Coast cria uma **nova** worktree (por exemplo, quando você atribui uma branch que não tem uma worktree existente). O padrão é a primeira entrada em `worktree_dir`.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\ndefault_worktree_dir = \".worktrees\"\n```\n\nDiretórios externos nunca são usados para criar novas worktrees — o Coast sempre cria worktrees em um diretório local (relativo). O campo `default_worktree_dir` só é necessário quando você quer substituir o padrão (primeira entrada).\n\n## Exemplos\n\n### Integração com Codex\n\nO OpenAI Codex cria worktrees em `~/.codex/worktrees/{hash}/{project-name}`. Para torná-las visíveis e atribuíveis no Coast:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nApós adicionar isso, as worktrees do Codex aparecem no modal de checkout e na saída de `coast ls`. Você pode atribuir uma instância do Coast a uma worktree do Codex para executar seu código em um ambiente de desenvolvimento completo.\n\nObservação: o contêiner deve ser recriado (`coast run`) após adicionar um diretório externo para que o bind mount entre em vigor. Reiniciar uma instância existente não é suficiente.\n\n### Integração com Claude Code\n\nO Claude Code cria worktrees dentro do projeto em `.claude/worktrees/`. Como este é um caminho relativo (dentro da raiz do projeto), ele funciona como qualquer outro diretório de worktree local — nenhum mount externo é necessário:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Os três juntos\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\n## Leitura dinâmica do Coastfile\n\nAlterações em `worktree_dir` no seu Coastfile entram em vigor imediatamente para a **listagem** de worktrees (a API e o monitor do git leem o Coastfile em tempo real a partir do disco, não apenas o artefato de build em cache). No entanto, **bind mounts** externos são criados apenas no momento da criação do contêiner, então você precisa recriar a instância para que um diretório externo recém-adicionado possa ser montado.\n", + "coastfiles/WORKTREE_DIR.md": "# Diretórios de Worktree\n\nO campo `worktree_dir` em `[coast]` controla onde as worktrees do git ficam. O Coast usa worktrees do git para dar a cada instância sua própria cópia da base de código em uma branch diferente, sem duplicar o repositório completo.\n\n## Sintaxe\n\n`worktree_dir` aceita uma única string ou um array de strings:\n\n```toml\n# Single directory (default)\nworktree_dir = \".worktrees\"\n\n# Multiple directories\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\nQuando omitido, o padrão é `\".worktrees\"`.\n\n## Tipos de caminho\n\n### Caminhos relativos\n\nCaminhos que não começam com `~/` ou `/` são resolvidos em relação à raiz do projeto. Estes são os mais comuns e não exigem tratamento especial — eles estão dentro do diretório do projeto e ficam automaticamente disponíveis dentro do contêiner do Coast por meio do bind mount padrão `/host-project`.\n\n```toml\nworktree_dir = \".worktrees\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Caminhos com til (`~`) (externos)\n\nCaminhos que começam com `~/` são expandidos para o diretório home do usuário e tratados como diretórios de worktree **externos**. O Coast adiciona um bind mount separado para que o contêiner possa acessá-los.\n\n```toml\nworktree_dir = [\"~/.codex/worktrees\", \".worktrees\"]\n```\n\nÉ assim que você integra com ferramentas que criam worktrees fora da raiz do seu projeto, como o OpenAI Codex (que sempre cria worktrees em `$CODEX_HOME/worktrees`).\n\n### Caminhos absolutos (externos)\n\nCaminhos que começam com `/` também são tratados como externos e recebem seu próprio bind mount.\n\n```toml\nworktree_dir = [\"/shared/worktrees\", \".worktrees\"]\n```\n\n### Padrões glob (externos)\n\nCaminhos externos podem conter metacaracteres glob (`*`, `?`, `[...]`). O Coast os expande em tempo de execução contra o sistema de arquivos do host, criando um bind mount para cada diretório correspondente.\n\n```toml\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\nIsso é útil quando uma ferramenta gera worktrees sob um componente de caminho que varia por projeto (como um hash). O `*` corresponde a qualquer nome de diretório único, então `~/.shep/repos/*/wt` corresponde a `~/.shep/repos/a21f0cda9ab9d456/wt` e a qualquer outro diretório de hash que contenha um subdiretório `wt`.\n\nSintaxe glob suportada:\n\n- `*` — corresponde a qualquer sequência de caracteres dentro de um único componente de caminho\n- `?` — corresponde a qualquer caractere único\n- `[abc]` — corresponde a qualquer caractere do conjunto\n- `[!abc]` — corresponde a qualquer caractere que não esteja no conjunto\n\nA expansão de glob acontece em todos os lugares onde os diretórios de worktree são resolvidos: criação do contêiner, assign, start, lookup e o monitor do git. As correspondências são ordenadas para garantir uma ordem determinística. Se um glob não corresponder a nenhum diretório, ele será ignorado silenciosamente.\n\nComo outros caminhos externos, o contêiner deve ser recriado (`coast run`) após adicionar um padrão glob para que o bind mount entre em vigor.\n\n## Como os diretórios externos funcionam\n\nQuando o Coast encontra um diretório de worktree externo (caminho com til ou absoluto), três coisas acontecem:\n\n1. **Bind mount do contêiner** — No momento da criação do contêiner (`coast run`), o caminho do host resolvido é montado via bind no contêiner em `/host-external-wt/{index}`, onde `{index}` é a posição no array `worktree_dir`. Isso torna os arquivos externos acessíveis dentro do contêiner.\n\n2. **Filtragem do projeto** — Diretórios externos podem conter worktrees de vários projetos. O Coast usa `git worktree list --porcelain` (que é inerentemente limitado ao repositório atual) para descobrir apenas as worktrees que pertencem a este projeto. O monitor do git também verifica a propriedade lendo o arquivo `.git` de cada worktree e checando se seu ponteiro `gitdir:` resolve de volta para o repositório atual.\n\n3. **Remontagem do workspace** — Quando você usa `coast assign` para uma worktree externa, o Coast remonta `/workspace` a partir do caminho do bind mount externo em vez do caminho usual `/host-project/{dir}/{name}`.\n\n## Nomenclatura de worktrees externas\n\nWorktrees externas com uma branch em checkout aparecem pelo nome da branch, da mesma forma que worktrees locais.\n\nWorktrees externas em **detached HEAD** (comum no Codex) aparecem usando seu caminho relativo dentro do diretório externo. Por exemplo, uma worktree do Codex em `~/.codex/worktrees/a0db/coastguard-platform` aparece como `a0db/coastguard-platform` na UI e na CLI.\n\n## `default_worktree_dir`\n\nControla qual diretório é usado quando o Coast cria uma **nova** worktree (por exemplo, quando você atribui uma branch que não tem uma worktree existente). O padrão é a primeira entrada em `worktree_dir`.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\ndefault_worktree_dir = \".worktrees\"\n```\n\nDiretórios externos nunca são usados para criar novas worktrees — o Coast sempre cria worktrees em um diretório local (relativo). O campo `default_worktree_dir` só é necessário quando você quer substituir o padrão (primeira entrada).\n\n## Exemplos\n\n### Integração com Codex\n\nO OpenAI Codex cria worktrees em `~/.codex/worktrees/{hash}/{project-name}`. Para torná-las visíveis e atribuíveis no Coast:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nApós adicionar isso, as worktrees do Codex aparecem no modal de checkout e na saída de `coast ls`. Você pode atribuir uma instância do Coast a uma worktree do Codex para executar seu código em um ambiente de desenvolvimento completo.\n\nObservação: o contêiner deve ser recriado (`coast run`) após adicionar um diretório externo para que o bind mount entre em vigor. Reiniciar uma instância existente não é suficiente.\n\n### Integração com Claude Code\n\nO Claude Code cria worktrees dentro do projeto em `.claude/worktrees/`. Como este é um caminho relativo (dentro da raiz do projeto), ele funciona como qualquer outro diretório de worktree local — nenhum mount externo é necessário:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Integração com Shep\n\nO Shep cria worktrees em `~/.shep/repos/{hash}/wt/{branch-slug}`, onde o hash é por repositório. Use um padrão glob para corresponder ao diretório de hash:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n### Todos os harnesses juntos\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n## Leitura dinâmica do Coastfile\n\nAlterações em `worktree_dir` no seu Coastfile entram em vigor imediatamente para a **listagem** de worktrees (a API e o monitor do git leem o Coastfile em tempo real a partir do disco, não apenas o artefato de build em cache). No entanto, **bind mounts** externos são criados apenas no momento da criação do contêiner, então você precisa recriar a instância para que um diretório externo recém-adicionado possa ser montado.\n", "concepts_and_terminology/README.md": "# Conceitos e Terminologia\n\nEsta seção cobre os conceitos centrais e o vocabulário usados em todo o Coasts. Se você é novo no Coasts, comece aqui antes de mergulhar na configuração ou no uso avançado.\n\n- [Coasts](COASTS.md) — runtimes autocontidos do seu projeto, cada um com suas próprias portas, volumes e atribuição de worktree.\n- [Run](RUN.md) — criar uma nova instância de Coast a partir do build mais recente, opcionalmente atribuindo um worktree.\n- [Remove](REMOVE.md) — desmontar uma instância de Coast e seu estado de runtime isolado quando você precisa recriá-la do zero ou quer desativar o Coasts.\n- [Filesystem](FILESYSTEM.md) — a montagem compartilhada entre host e Coast, agentes no lado do host e troca de worktree.\n- [Coast Daemon](DAEMON.md) — o plano de controle local `coastd` que executa operações de ciclo de vida.\n- [Coast CLI](CLI.md) — a interface de terminal para comandos, scripts e fluxos de trabalho de agentes.\n- [Coastguard](COASTGUARD.md) — a UI web iniciada com `coast ui` para observabilidade e controle.\n- [Ports](PORTS.md) — portas canônicas vs portas dinâmicas e como o checkout alterna entre elas.\n- [Primary Port & DNS](PRIMARY_PORT_AND_DNS.md) — links rápidos para seu serviço primário, roteamento por subdomínio para isolamento de cookies e templates de URL.\n- [Assign and Unassign](ASSIGN.md) — alternar uma Coast entre worktrees e as estratégias de atribuição disponíveis.\n- [Checkout](CHECKOUT.md) — mapear portas canônicas para uma instância de Coast e quando você precisa disso.\n- [Lookup](LOOKUP.md) — descobrir quais instâncias de Coast correspondem ao worktree atual do agente.\n- [Volume Topology](VOLUMES.md) — serviços compartilhados, volumes compartilhados, volumes isolados e snapshotting.\n- [Shared Services](SHARED_SERVICES.md) — serviços de infraestrutura gerenciados pelo host e desambiguação de volumes.\n- [Secrets and Extractors](SECRETS.md) — extrair segredos do host e injetá-los em contêineres Coast.\n- [Builds](BUILDS.md) — a anatomia de um build do coast, onde os artefatos ficam, auto-pruning e builds tipados.\n- [Coastfile Types](COASTFILE_TYPES.md) — variantes de Coastfile componíveis com extends, unset, omit e autostart.\n- [Runtimes and Services](RUNTIMES_AND_SERVICES.md) — o runtime DinD, a arquitetura Docker-in-Docker e como os serviços rodam dentro de uma Coast.\n- [Bare Services](BARE_SERVICES.md) — executar processos não containerizados dentro de uma Coast e por que você deveria containerizar em vez disso.\n- [Logs](LOGS.md) — ler logs de serviços de dentro de uma Coast, o tradeoff do MCP e o visualizador de logs do Coastguard.\n- [Exec & Docker](EXEC_AND_DOCKER.md) — executar comandos dentro de uma Coast e falar com o daemon Docker interno.\n- [Agent Shells](AGENT_SHELLS.md) — TUIs de agentes em contêiner, o tradeoff do OAuth e por que você provavelmente deveria executar agentes no host em vez disso.\n- [MCP Servers](MCP_SERVERS.md) — configurar ferramentas MCP dentro de uma Coast para agentes containerizados, servidores internos vs servidores proxied pelo host.\n- [Troubleshooting](TROUBLESHOOTING.md) — doctor, reinício do daemon, remoção de projeto e a opção nuclear de factory-reset.\n", "concepts_and_terminology/AGENT_SHELLS.md": "# Shells de Agente\n\nShells de agente são shells dentro de um Coast que abrem diretamente para um runtime TUI de agente — Claude Code, Codex, ou qualquer agente CLI. Você as configura com uma seção `[agent_shell]` no seu Coastfile e o Coast inicia o processo do agente dentro do contêiner DinD.\n\n**Para a maioria dos casos de uso, você não deve fazer isso.** Em vez disso, execute seus agentes de codificação na máquina host. O [filesystem](FILESYSTEM.md) compartilhado significa que um agente do lado do host pode editar código normalmente enquanto chama [`coast logs`](LOGS.md), [`coast exec`](EXEC_AND_DOCKER.md) e [`coast ps`](RUNTIMES_AND_SERVICES.md) para obter informações de runtime. Shells de agente adicionam montagem de credenciais, complicações de OAuth e complexidade de ciclo de vida que você não precisa, a menos que tenha um motivo específico para containerizar o próprio agente.\n\n## O Problema do OAuth\n\nSe você estiver usando Claude Code, Codex ou ferramentas semelhantes que autenticam via OAuth, o token foi emitido para sua máquina host. Quando esse mesmo token é usado de dentro de um contêiner Linux — user agent diferente, ambiente diferente — o provedor pode sinalizá-lo ou revogá-lo. Você terá falhas de autenticação intermitentes que são difíceis de depurar.\n\nPara agentes containerizados, a autenticação baseada em chave de API é a opção mais segura. Defina a chave como um [segredo](SECRETS.md) no seu Coastfile e injete-a no ambiente do contêiner.\n\nSe chaves de API não forem uma opção, você pode montar credenciais OAuth no Coast (veja a seção Configuração abaixo), mas espere atrito. No macOS, se você usar o extrator de segredos `keychain` para obter tokens OAuth, cada `coast build` solicitará sua senha do Chaveiro do macOS. Isso torna o processo de build tedioso, especialmente ao reconstruir com frequência. O prompt do Chaveiro é um requisito de segurança do macOS e não pode ser ignorado.\n\n## Configuração\n\nAdicione uma seção `[agent_shell]` ao seu Coastfile com o comando a executar:\n\n```toml\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\nO comando é executado dentro do contêiner DinD em `/workspace`. O Coast cria um usuário `coast` dentro do contêiner, copia credenciais de `/root/.claude/` para `/home/coast/.claude/` e executa o comando como esse usuário. Se o seu agente precisa de credenciais montadas no contêiner, use `[secrets]` com injeção de arquivo (veja [Segredos e Extratores](SECRETS.md)) e `[coast.setup]` para instalar a CLI do agente:\n\n```toml\n[coast.setup]\nrun = [\"npm install -g @anthropic-ai/claude-code\"]\n\n[secrets.claude_credentials]\nextractor = \"keychain\"\nservice = \"Claude Code-credentials\"\ninject = \"file:/root/.claude/.credentials.json\"\n\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\nSe `[agent_shell]` estiver configurado, o Coast inicia automaticamente uma shell quando a instância inicia. A configuração é herdada via `extends` e pode ser sobrescrita por [tipo de Coastfile](COASTFILE_TYPES.md).\n\n## O Modelo de Agente Ativo\n\nCada instância do Coast pode ter múltiplas shells de agente, mas apenas uma é **ativa** por vez. A shell ativa é o alvo padrão para comandos que não especificam um ID `--shell`.\n\n```bash\ncoast agent-shell dev-1 ls\n\n SHELL STATUS ACTIVE\n 1 running ★\n 2 running\n```\n\nTroque a shell ativa:\n\n```bash\ncoast agent-shell dev-1 activate 2\n```\n\nVocê não pode fechar a shell ativa — primeiro ative uma diferente. Isso evita matar acidentalmente a shell com a qual você está interagindo.\n\nNo Coastguard, shells de agente aparecem como abas no painel Exec com badges de ativo/inativo. Clique em uma aba para ver seu terminal; use o menu suspenso para ativar, iniciar (spawn) ou fechar shells.\n\n![Agent shell in Coastguard](../../assets/coastguard-agent-shell.png)\n*Uma shell de agente executando Claude Code dentro de uma instância do Coast, acessível pela aba Exec no Coastguard.*\n\n## Enviando Entrada\n\nA principal forma de controlar um agente containerizado programaticamente é `coast agent-shell input`:\n\n```bash\ncoast agent-shell dev-1 input \"fix the failing test in auth.test.ts\"\n```\n\nIsso escreve o texto na TUI do agente ativo e pressiona Enter. O agente o recebe como se você o tivesse digitado no terminal.\n\nOpções:\n\n- `--no-send` — escreve o texto sem pressionar Enter. Útil para construir entrada parcial ou navegar por menus de TUI.\n- `--shell ` — direciona para uma shell específica em vez da ativa.\n- `--show-bytes` — imprime os bytes exatos sendo enviados, para depuração.\n\nPor baixo dos panos, a entrada é escrita diretamente no descritor de arquivo mestre do PTY. O texto e a tecla Enter são enviados como duas escritas separadas com um intervalo de 25ms para evitar artefatos de modo de colagem que alguns frameworks TUI exibem ao receber entrada rápida.\n\n## Outros Comandos\n\n```bash\ncoast agent-shell dev-1 spawn # criar uma nova shell\ncoast agent-shell dev-1 spawn --activate # criar e ativar imediatamente\ncoast agent-shell dev-1 tty # anexar TTY interativa à shell ativa\ncoast agent-shell dev-1 tty --shell 2 # anexar a uma shell específica\ncoast agent-shell dev-1 read-output # ler o buffer completo de scrollback\ncoast agent-shell dev-1 read-last-lines 50 # ler as últimas 50 linhas de saída\ncoast agent-shell dev-1 session-status # verificar se o processo da shell está vivo\n```\n\n`tty` oferece uma sessão interativa ao vivo — você pode digitar diretamente na TUI do agente. Desanexe com a sequência de escape padrão do terminal. `read-output` e `read-last-lines` são não interativos e retornam texto, o que é útil para scripts e automação.\n\n## Ciclo de Vida e Recuperação\n\nSessões de shell de agente persistem no Coastguard ao navegar entre páginas. O buffer de scrollback (até 512KB) é reproduzido quando você reconecta a uma aba.\n\nQuando você para uma instância do Coast com `coast stop`, todos os processos PTY das shells de agente são encerrados e seus registros no banco de dados são limpos. `coast start` inicia automaticamente uma nova shell de agente se `[agent_shell]` estiver configurado.\n\nApós uma reinicialização do daemon, shells de agente previamente em execução aparecerão como mortas. O sistema detecta isso automaticamente — se a shell ativa estiver morta, a primeira shell viva é promovida a ativa. Se nenhuma shell estiver viva, inicie uma nova com `coast agent-shell spawn --activate`.\n\n## Para Quem Isto É\n\nShells de agente são projetadas para **produtos que estão construindo integrações first-party** em torno do Coasts — plataformas de orquestração, wrappers de agentes e ferramentas que querem gerenciar agentes de codificação containerizados programaticamente via as APIs `input`, `read-output` e `session-status`.\n\nPara codificação geral com agentes paralelos, execute agentes no host. É mais simples, evita problemas de OAuth, contorna a complexidade de montagem de credenciais e aproveita ao máximo o filesystem compartilhado. Você obtém todos os benefícios do Coast (runtimes isolados, gerenciamento de portas, troca de worktree) sem nenhum dos custos de sobrecarga da containerização de agentes.\n\nO próximo nível de complexidade além de shells de agente é montar [servidores MCP](MCP_SERVERS.md) no Coast para que o agente containerizado tenha acesso a ferramentas. Isso amplia ainda mais a superfície de integração e é coberto separadamente. A capacidade existe se você precisar, mas a maioria dos usuários não deve.\n", "concepts_and_terminology/ASSIGN.md": "# Atribuir e Desatribuir\n\nAtribuir e desatribuir controlam para qual worktree uma instância do Coast está apontando. Veja [Filesystem](FILESYSTEM.md) para saber como a troca de worktree funciona no nível de montagem.\n\n## Atribuir\n\n`coast assign` alterna uma instância do Coast para um worktree específico. O Coast cria o worktree se ele ainda não existir, atualiza o código dentro do Coast e reinicia os serviços de acordo com a estratégia de atribuição configurada.\n\n```bash\ncoast assign dev-1 --worktree feature/oauth\n```\n\n```text\nBefore:\n┌─── dev-1 ──────────────────┐\n│ branch: main │\n│ worktree: - │\n└────────────────────────────┘\n\ncoast assign dev-1 --worktree feature/oauth\n\nAfter:\n┌─── dev-1 ──────────────────┐\n│ branch: feature/oauth │\n│ worktree: feature/oauth │\n│ │\n│ postgres → skipped (none) │\n│ web → hot swapped │\n│ api → restarted │\n│ worker → rebuilt │\n└────────────────────────────┘\n```\n\nApós atribuir, `dev-1` está executando o branch `feature/oauth` com todos os seus serviços ativos.\n\n## Desatribuir\n\n`coast unassign` alterna uma instância do Coast de volta para a raiz do projeto (seu branch main/master). A associação com o worktree é removida e o Coast volta a executar a partir do repositório principal.\n\n```text\ncoast unassign dev-1\n\n┌─── dev-1 ──────────────────┐\n│ branch: main │\n│ worktree: - │\n└────────────────────────────┘\n```\n\n## Estratégias de Atribuição\n\nQuando um Coast é atribuído a um novo worktree, cada serviço precisa saber como lidar com a mudança de código. Você configura isso por serviço no seu [Coastfile](COASTFILE_TYPES.md) em `[assign]`:\n\n```toml\n[assign]\ndefault = \"restart\"\n\n[assign.services]\npostgres = \"none\"\nredis = \"none\"\nweb = \"hot\"\nworker = \"rebuild\"\n```\n\n```text\ncoast assign dev-1 --worktree feature/billing\n\n postgres (strategy: none) → skipped, unchanged between branches\n redis (strategy: none) → skipped, unchanged between branches\n web (strategy: hot) → filesystem swapped, file watcher picks it up\n api (strategy: restart) → container restarted\n worker (strategy: rebuild) → image rebuilt, container restarted\n```\n\nAs estratégias disponíveis são:\n\n- **none** — não fazer nada. Use isso para serviços que não mudam entre branches, como Postgres ou Redis.\n- **hot** — trocar apenas o filesystem. O serviço continua em execução e capta as mudanças via propagação de montagem e file watchers (ex.: um servidor de desenvolvimento com hot reload).\n- **restart** — reiniciar o container do serviço. Use isso para serviços interpretados que só precisam de um reinício do processo. Este é o padrão.\n- **rebuild** — reconstruir a imagem do serviço e reiniciar. Use isso quando a mudança de branch afeta o `Dockerfile` ou dependências em tempo de build.\n\nVocê também pode especificar gatilhos de rebuild para que um serviço só reconstrua quando arquivos específicos mudarem:\n\n```toml\n[assign.rebuild_triggers]\nworker = [\"Dockerfile\", \"package.json\"]\n```\n\nSe nenhum dos arquivos de gatilho mudou entre branches, o serviço pula o rebuild mesmo que a estratégia esteja definida como `rebuild`.\n\n## Worktrees Excluídos\n\nSe um worktree atribuído for excluído, o daemon `coastd` automaticamente desatribui essa instância de volta para a raiz do repositório Git principal.\n\n---\n\n> **Dica: Reduzindo a latência de atribuição em grandes bases de código**\n>\n> Por baixo dos panos, a primeira atribuição para um novo worktree inicializa arquivos selecionados ignorados pelo git (gitignored) nesse worktree, e serviços com `[assign.rebuild_triggers]` podem executar `git diff --name-only` para decidir se um rebuild é necessário. Em grandes bases de código, essa etapa de inicialização e rebuilds desnecessários tendem a dominar o tempo de atribuição.\n>\n> Use `exclude_paths` no seu Coastfile para reduzir a superfície de inicialização de arquivos ignorados pelo git, use `\"hot\"` para serviços com file watchers e mantenha `[assign.rebuild_triggers]` focado em verdadeiras entradas de tempo de build. Se você precisar atualizar manualmente a inicialização de arquivos ignorados para um worktree existente, execute `coast assign --force-sync`. Veja [Performance Optimizations](PERFORMANCE_OPTIMIZATIONS.md) para um guia completo.\n", "concepts_and_terminology/BARE_SERVICES.md": "# Serviços Bare\n\nSe você consegue conteinerizar seu projeto, você deve. Serviços bare existem para projetos que ainda não foram conteinerizados e em que adicionar um `Dockerfile` e `docker-compose.yml` não é prático no curto prazo. Eles são um degrau, não um destino.\n\nEm vez de um `docker-compose.yml` orquestrando serviços conteinerizados, serviços bare permitem que você defina comandos de shell no seu Coastfile e o Coast os execute como processos comuns com um supervisor leve dentro do contêiner do Coast.\n\n## Por que conteinerizar em vez disso\n\nOs serviços do [Docker Compose](RUNTIMES_AND_SERVICES.md) oferecem:\n\n- Builds reprodutíveis via Dockerfiles\n- Health checks que o Coast pode aguardar durante a inicialização\n- Isolamento de processos entre serviços\n- Gerenciamento de volumes e rede feito pelo Docker\n- Uma definição portátil que funciona em CI, staging e produção\n\nServiços bare não oferecem nada disso. Seus processos compartilham o mesmo sistema de arquivos, a recuperação de falhas é um loop de shell, e \"funciona na minha máquina\" é tão provável dentro do Coast quanto fora dele. Se o seu projeto já tem um `docker-compose.yml`, use-o.\n\n## Quando serviços bare fazem sentido\n\n- Você está adotando o Coast para um projeto que nunca foi conteinerizado e quer começar a obter valor do isolamento de worktree e do gerenciamento de portas imediatamente\n- Seu projeto é uma ferramenta de processo único ou CLI em que um Dockerfile seria exagero\n- Você quer iterar na conteinerização gradualmente — comece com serviços bare, migre para compose depois\n\n## Configuração\n\nServiços bare são definidos com seções `[services.]` no seu Coastfile. Um Coastfile pode definir serviços bare por conta própria ou junto com `compose` — veja [Tipos de Serviço Mistos](MIXED_SERVICE_TYPES.md) para o segundo caso.\n\n```toml\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\nrestart = \"on-failure\"\n\n[services.worker]\ncommand = \"node worker.js\"\nrestart = \"always\"\n\n[ports]\nweb = 3000\n```\n\nCada serviço tem quatro campos:\n\n| Campo | Obrigatório | Descrição |\n|---|---|---|\n| `command` | sim | O comando de shell a executar (ex.: `\"npm run dev\"`) |\n| `port` | não | A porta em que o serviço escuta, usada para mapeamento de portas |\n| `restart` | não | Política de reinício: `\"no\"` (padrão), `\"on-failure\"` ou `\"always\"` |\n| `install` | não | Um ou mais comandos para executar antes de iniciar (ex.: `\"npm install\"` ou `[\"npm install\", \"npm run build\"]`) |\n\n### Pacotes de setup\n\nComo serviços bare rodam como processos comuns, o contêiner do Coast precisa ter os runtimes certos instalados. Use `[coast.setup]` para declarar pacotes do sistema:\n\n```toml\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n```\n\nEles são instalados antes de qualquer serviço iniciar. Sem isso, seus comandos `npm` ou `node` falharão dentro do contêiner.\n\n### Comandos de instalação\n\nO campo `install` roda antes do serviço iniciar e novamente a cada [`coast assign`](ASSIGN.md) (troca de branch). É aqui que entra a instalação de dependências:\n\n```toml\n[services.api]\ninstall = [\"pip install -r requirements.txt\", \"python manage.py migrate\"]\ncommand = \"python manage.py runserver 0.0.0.0:8000\"\nport = 8000\n```\n\nOs comandos de instalação rodam sequencialmente. Se algum comando de instalação falhar, o serviço não inicia.\n\n### Políticas de reinício\n\n- **`no`** — o serviço roda uma vez. Se ele sair, permanece morto. Use isto para tarefas one-shot ou serviços que você quer gerenciar manualmente.\n- **`on-failure`** — reinicia o serviço se ele sair com um código diferente de zero. Saídas bem-sucedidas (código 0) são deixadas como estão. Usa backoff exponencial de 1 segundo até 30 segundos, e desiste após 10 falhas consecutivas.\n- **`always`** — reinicia em qualquer saída, incluindo sucesso. Mesmo backoff que `on-failure`. Use isto para servidores de longa duração que nunca devem parar.\n\nSe um serviço rodar por mais de 30 segundos antes de falhar, o contador de tentativas e o backoff são reiniciados — a suposição é que ele esteve saudável por um tempo e a falha é um problema novo.\n\n## Como funciona por baixo dos panos\n\n```text\n┌─── Coast: dev-1 ──────────────────────────────────────┐\n│ │\n│ /coast-supervisor/ │\n│ ├── web.sh (runs command, tracks PID) │\n│ ├── worker.sh │\n│ ├── start-all.sh (launches all services) │\n│ ├── stop-all.sh (SIGTERM via PID files) │\n│ └── ps.sh (checks PID liveness) │\n│ │\n│ /var/log/coast-services/ │\n│ ├── web.log │\n│ └── worker.log │\n│ │\n│ No inner Docker daemon images are used. │\n│ Processes run directly on the container OS. │\n└───────────────────────────────────────────────────────┘\n```\n\nO Coast gera wrappers em shell script para cada serviço e os coloca em `/coast-supervisor/` dentro do contêiner DinD. Cada wrapper rastreia seu PID, redireciona a saída para um arquivo de log e implementa a política de reinício como um loop de shell. Não há Docker Compose, não há imagens Docker internas e não há isolamento em nível de contêiner entre serviços.\n\n`coast ps` verifica a vivacidade do PID em vez de consultar o Docker, e `coast logs` acompanha (tail) os arquivos de log em vez de chamar `docker compose logs`. O formato de saída de log corresponde ao formato do compose `service | line` para que a UI do Coastguard funcione sem alterações.\n\n## Portas\n\nA configuração de portas funciona exatamente da mesma forma que com Coasts baseados em compose. Defina as portas em que seus serviços escutam em `[ports]`:\n\n```toml\n[services.web]\ncommand = \"npm start\"\nport = 3000\n\n[ports]\nweb = 3000\n```\n\n[Portas dinâmicas](PORTS.md) são alocadas em `coast run`, e [`coast checkout`](CHECKOUT.md) troca as portas canônicas como de costume. A única diferença é que não há uma rede Docker entre serviços — todos fazem bind diretamente no loopback do contêiner ou em `0.0.0.0`.\n\n## Troca de branch\n\nQuando você roda `coast assign` em um Coast com serviços bare, o seguinte acontece:\n\n1. Todos os serviços em execução são parados via SIGTERM\n2. O worktree muda para a nova branch\n3. Os comandos de instalação são executados novamente (ex.: `npm install` pega as dependências da nova branch)\n4. Todos os serviços reiniciam\n\nIsso é equivalente ao que acontece com compose — `docker compose down`, troca de branch, rebuild, `docker compose up` — mas com processos de shell em vez de contêineres.\n\n## Limitações\n\n- **Sem health checks.** O Coast não consegue esperar que um serviço bare fique \"saudável\" da forma que consegue com um serviço do compose que define um health check. Ele inicia o processo e espera pelo melhor.\n- **Sem isolamento entre serviços.** Todos os processos compartilham o mesmo sistema de arquivos e o mesmo namespace de processos dentro do contêiner do Coast. Um serviço com mau comportamento pode afetar os outros.\n- **Sem cache de build.** Builds do Docker Compose são cacheadas camada por camada. Comandos `install` de serviços bare rodam do zero a cada assign.\n- **Recuperação de falhas é básica.** A política de reinício usa um loop de shell com backoff exponencial. Não é um supervisor de processos como systemd ou supervisord.\n- **Sem `[omit]` ou `[unset]` para serviços.** A composição de tipos de Coastfile funciona com serviços compose, mas serviços bare não suportam omitir serviços individuais via Coastfiles tipados.\n\n## Migração para Compose\n\nQuando você estiver pronto para conteinerizar, o caminho de migração é simples:\n\n1. Escreva um `Dockerfile` para cada serviço\n2. Crie um `docker-compose.yml` que os referencie\n3. Substitua as seções `[services.*]` no seu Coastfile por um campo `compose` apontando para o seu arquivo compose\n4. Remova os pacotes de `[coast.setup]` que agora são tratados pelos seus Dockerfiles\n5. Faça rebuild com [`coast build`](BUILDS.md)\n\nSeus mapeamentos de portas, configuração de [volumes](VOLUMES.md), [serviços compartilhados](SHARED_SERVICES.md) e [segredos](SECRETS.md) todos são reaproveitados sem mudanças. A única coisa que muda é como os próprios serviços rodam.\n", "concepts_and_terminology/BUILDS.md": "# Builds\n\nPense em um build do coast como uma imagem Docker com ajuda extra. Um build é um artefato baseado em diretório que agrupa tudo o que é necessário para criar instâncias do Coast: um [Coastfile](COASTFILE_TYPES.md) resolvido, um arquivo compose reescrito, tarballs de imagens OCI previamente baixadas e arquivos do host injetados. Ele não é uma imagem Docker em si, mas contém imagens Docker (como tarballs) além dos metadados de que o Coast precisa para conectá-las.\n\n## O que `coast build` faz\n\nQuando você executa `coast build`, o daemon executa estas etapas em ordem:\n\n1. Analisa e valida o Coastfile.\n2. Lê o arquivo compose e filtra os serviços omitidos.\n3. Extrai [secrets](SECRETS.md) dos extratores configurados e os armazena criptografados no keystore.\n4. Constrói imagens Docker para serviços do compose que têm diretivas `build:` (no host).\n5. Baixa imagens Docker para serviços do compose que têm diretivas `image:`.\n6. Armazena em cache todas as imagens como tarballs OCI em `~/.coast/image-cache/`.\n7. Se `[coast.setup]` estiver configurado, constrói uma imagem base DinD personalizada com os pacotes, comandos e arquivos especificados.\n8. Escreve o diretório do artefato de build com o manifesto, o coastfile resolvido, o compose reescrito e os arquivos injetados.\n9. Atualiza o link simbólico `latest` para apontar para o novo build.\n10. Remove automaticamente builds antigos além do limite de retenção.\n\n## Onde os builds ficam\n\n```text\n~/.coast/\n images/\n my-project/\n latest -> a3c7d783_20260227143000 (symlink)\n a3c7d783_20260227143000/ (versioned build)\n manifest.json\n coastfile.toml\n compose.yml\n inject/\n b4d8e894_20260226120000/ (older build)\n ...\n image-cache/ (shared tarball cache)\n postgres_16_a1b2c3d4e5f6.tar\n redis_7_f6e5d4c3b2a1.tar\n coast-built_my-project_web_latest_...tar\n```\n\nCada build recebe um **ID de build** exclusivo no formato `{coastfile_hash}_{YYYYMMDDHHMMSS}`. O hash incorpora o conteúdo do Coastfile e a configuração resolvida, então alterações no Coastfile produzem um novo ID de build.\n\nO link simbólico `latest` sempre aponta para o build mais recente para resolução rápida. Se o seu projeto usa Coastfiles tipados (por exemplo, `Coastfile.light`), cada tipo recebe seu próprio link simbólico: `latest-light`.\n\nO cache de imagens em `~/.coast/image-cache/` é compartilhado entre todos os projetos. Se dois projetos usarem a mesma imagem Postgres, o tarball será armazenado em cache uma única vez.\n\n## O que um build contém\n\nCada diretório de build contém:\n\n- **`manifest.json`** -- metadados completos do build: nome do projeto, timestamp do build, hash do coastfile, lista de imagens em cache/construídas, nomes de secrets, serviços omitidos, [estratégias de volume](VOLUMES.md) e mais.\n- **`coastfile.toml`** -- o Coastfile resolvido (mesclado com o pai se estiver usando `extends`).\n- **`compose.yml`** -- uma versão reescrita do seu arquivo compose em que diretivas `build:` são substituídas por tags de imagem pré-construídas, e serviços omitidos são removidos.\n- **`inject/`** -- cópias de arquivos do host de `[inject].files` (por exemplo, `~/.gitconfig`, `~/.npmrc`).\n\n## Builds não contêm secrets\n\nSecrets são extraídos durante a etapa de build, mas são armazenados em um keystore criptografado separado em `~/.coast/keystore.db` -- não dentro do diretório do artefato de build. O manifesto registra apenas os **nomes** dos secrets que foram extraídos, nunca os valores.\n\nIsso significa que os artefatos de build são seguros para inspeção sem expor dados sensíveis. Secrets são descriptografados e injetados depois, quando uma instância Coast é criada com `coast run`.\n\n## Builds e Docker\n\nUm build envolve três tipos de imagens Docker:\n\n- **Imagens construídas** -- serviços do compose com diretivas `build:` são construídos no host via `docker build`, marcados como `coast-built/{project}/{service}:latest` e salvos como tarballs no cache de imagens.\n- **Imagens baixadas** -- serviços do compose com diretivas `image:` são baixados e salvos como tarballs.\n- **Imagem Coast** -- se `[coast.setup]` estiver configurado, uma imagem Docker personalizada é construída sobre `docker:dind` com os pacotes, comandos e arquivos especificados. Marcada como `coast-image/{project}:{build_id}`.\n\nEm tempo de execução ([`coast run`](RUN.md)), esses tarballs são carregados no [daemon DinD interno](RUNTIMES_AND_SERVICES.md) via `docker load`. É isso que faz as instâncias Coast iniciarem rapidamente sem precisar baixar imagens de um registry.\n\n## Builds e instâncias\n\nQuando você executa [`coast run`](RUN.md), o Coast resolve o build mais recente (ou um `--build-id` específico) e usa seus artefatos para criar a instância. O ID do build é registrado na instância.\n\nVocê não precisa reconstruir para criar mais instâncias. Um build pode servir muitas instâncias Coast em execução em paralelo.\n\n## Quando reconstruir\n\nReconstrua apenas quando seu Coastfile, `docker-compose.yml` ou configuração de infraestrutura mudar. Reconstruir consome muitos recursos -- isso baixa novamente imagens, reconstrói imagens Docker e reextrai secrets.\n\nAlterações no código não exigem reconstrução. O Coast monta seu diretório de projeto diretamente em cada instância, então atualizações de código são refletidas imediatamente.\n\n## Remoção automática\n\nO Coast mantém até 5 builds por tipo de Coastfile. Após cada `coast build` bem-sucedido, builds antigos além do limite são removidos automaticamente.\n\nBuilds que estão em uso por instâncias em execução nunca são removidos, independentemente do limite. Se você tiver 7 builds mas 3 deles estiverem sustentando instâncias ativas, todos os 3 estarão protegidos.\n\n## Remoção manual\n\nVocê pode remover builds manualmente via `coast rm-build` ou pela aba Builds do Coastguard.\n\n- **Remoção completa do projeto** (`coast rm-build `) exige que todas as instâncias sejam primeiro paradas e removidas. Isso remove todo o diretório de build, imagens Docker associadas, volumes e containers.\n- **Remoção seletiva** (por ID de build, disponível na UI do Coastguard) ignora builds que estão em uso por instâncias em execução.\n\n## Builds tipados\n\nSe o seu projeto usa vários Coastfiles (por exemplo, `Coastfile` para a configuração padrão e `Coastfile.snap` para volumes inicializados por snapshot), cada tipo mantém seu próprio link simbólico `latest-{type}` e seu próprio conjunto de remoção de 5 builds.\n\n```bash\ncoast build # uses Coastfile, updates \"latest\"\ncoast build --type snap # uses Coastfile.snap, updates \"latest-snap\"\n```\n\nA remoção automática de um build `snap` nunca afeta builds `default`, e vice-versa.\n", - "concepts_and_terminology/CHECKOUT.md": "# Checkout\n\nCheckout controla qual instância do Coast possui as [portas canônicas](PORTS.md) do seu projeto. Quando você faz checkout de um Coast, `localhost:3000`, `localhost:5432` e todas as outras portas canônicas passam a mapear diretamente para essa instância.\n\n```bash\ncoast checkout dev-1\n```\n\n```text\nAntes do checkout:\n localhost:3000 ──→ (nada)\n localhost:5432 ──→ (nada)\n\nDepois do checkout:\n localhost:3000 ──→ dev-1 web\n localhost:5432 ──→ dev-1 db\n```\n\nTrocar o checkout é instantâneo — o Coast encerra e recria encaminhadores `socat` leves. Nenhum contêiner é reiniciado.\n\n```bash\ncoast checkout dev-2 # troca instantânea\n\n# localhost:3000 ──→ dev-2 web\n# localhost:5432 ──→ dev-2 db\n```\n\n## Observação sobre Linux\n\nAs portas dinâmicas sempre funcionam no Linux sem privilégios especiais.\n\nAs portas canônicas abaixo de `1024` são diferentes. Se o seu Coastfile declarar portas como `80` ou `443`, o Linux pode impedir que `coast checkout` faça o bind delas até que você configure o host. As correções mais comuns são:\n\n- aumentar `net.ipv4.ip_unprivileged_port_start`\n- conceder capacidade de bind ao binário ou processo de encaminhamento\n\nO Coast informa isso explicitamente quando o host nega o bind.\n\nNo WSL, o Coast usa bridges de checkout publicadas pelo Docker para que navegadores e ferramentas do Windows possam alcançar as portas canônicas em checkout através de `127.0.0.1`, de forma semelhante a fluxos de trabalho do Docker Desktop como o Sail.\n\n## Você Precisa Fazer Checkout?\n\nNão necessariamente. Todo Coast em execução sempre tem suas próprias portas dinâmicas, e você pode acessar qualquer Coast por essas portas a qualquer momento sem fazer checkout de nada.\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\nVocê pode abrir `localhost:62217` no seu navegador para acessar o servidor web do dev-1 sem fazer checkout. Isso é perfeitamente adequado para muitos fluxos de trabalho, e você pode executar quantos Coasts quiser sem nunca usar `coast checkout`.\n\n## Quando o Checkout É Útil\n\nHá situações em que portas dinâmicas não são suficientes e você precisa de portas canônicas:\n\n- **Aplicações cliente com portas canônicas definidas no código.** Se você tem um cliente rodando fora do Coast — um servidor de desenvolvimento frontend no seu host, um aplicativo móvel no seu telefone ou um aplicativo desktop — que espera `localhost:3000` ou `localhost:8080`, alterar números de porta em todos os lugares é impraticável. Fazer checkout do Coast fornece as portas reais sem mudar nenhuma configuração.\n\n- **Webhooks e URLs de callback.** Serviços como Stripe, GitHub ou provedores OAuth enviam callbacks para uma URL que você registrou — normalmente algo como `https://your-ngrok-tunnel.io` que encaminha para `localhost:3000`. Se você mudar para uma porta dinâmica, os callbacks deixam de chegar. Fazer checkout garante que a porta canônica esteja ativa para o Coast que você está testando.\n\n- **Ferramentas de banco de dados, depuradores e integrações de IDE.** Muitos clientes GUI (pgAdmin, DataGrip, TablePlus), depuradores e configurações de execução da IDE salvam perfis de conexão com uma porta específica. O checkout permite que você mantenha seus perfis salvos e apenas troque qual Coast está por trás deles — sem reconfigurar seu alvo de anexação do depurador ou conexão com o banco de dados toda vez que você muda de contexto.\n\n## Liberando o Checkout\n\nSe você quiser liberar as portas canônicas sem fazer checkout de um Coast diferente:\n\n```bash\ncoast checkout --none\n```\n\nDepois disso, nenhum Coast possui as portas canônicas. Todos os Coasts continuam acessíveis por meio de suas portas dinâmicas.\n\n## Apenas Um por Vez\n\nExatamente um Coast pode estar em checkout por vez. Se `dev-1` estiver em checkout e você executar `coast checkout dev-2`, as portas canônicas trocam instantaneamente para `dev-2`. Não há intervalo — os encaminhadores antigos são encerrados e novos são iniciados na mesma operação.\n\n```text\n┌──────────────────────────────────────────────────┐\n│ Sua máquina │\n│ │\n│ Canônicas (apenas Coast em checkout): │\n│ localhost:3000 ──→ dev-2 web │\n│ localhost:5432 ──→ dev-2 db │\n│ │\n│ Dinâmicas (sempre disponíveis): │\n│ localhost:62217 ──→ dev-1 web │\n│ localhost:55681 ──→ dev-1 db │\n│ localhost:63104 ──→ dev-2 web │\n│ localhost:57220 ──→ dev-2 db │\n└──────────────────────────────────────────────────┘\n```\n\nAs portas dinâmicas não são afetadas pelo checkout. A única coisa que muda é para onde as portas canônicas apontam.\n", + "concepts_and_terminology/CHECKOUT.md": "# Checkout\n\nCheckout controla qual instância do Coast possui as [portas canônicas](PORTS.md) do seu projeto. Quando você faz checkout de um Coast, `localhost:3000`, `localhost:5432` e todas as outras portas canônicas passam a mapear diretamente para essa instância.\n\n```bash\ncoast checkout dev-1\n```\n\n```text\nAntes do checkout:\n localhost:3000 ──→ (nada)\n localhost:5432 ──→ (nada)\n\nDepois do checkout:\n localhost:3000 ──→ dev-1 web\n localhost:5432 ──→ dev-1 db\n```\n\nTrocar o checkout é instantâneo — o Coast encerra e recria encaminhadores `socat` leves. Nenhum contêiner é reiniciado.\n\n```bash\ncoast checkout dev-2 # troca instantânea\n\n# localhost:3000 ──→ dev-2 web\n# localhost:5432 ──→ dev-2 db\n```\n\n## Observação sobre Linux\n\nAs portas dinâmicas sempre funcionam no Linux sem privilégios especiais.\n\nAs portas canônicas abaixo de `1024` são diferentes. Se o seu Coastfile declarar portas como `80` ou `443`, o Linux pode impedir que `coast checkout` faça o bind delas até que você configure o host. As correções mais comuns são:\n\n- aumentar `net.ipv4.ip_unprivileged_port_start`\n- conceder capacidade de bind ao binário ou processo de encaminhamento\n\nO Coast informa isso explicitamente quando o host nega o bind.\n\nNo WSL, o Coast usa bridges de checkout publicadas pelo Docker para que navegadores e ferramentas do Windows possam alcançar as portas canônicas em checkout através de `127.0.0.1`, de forma semelhante a fluxos de trabalho do Docker Desktop como o Sail.\n\nPara projetos HTTPS locais que usam Caddy, o Coast reutiliza uma CA local do Caddy por instalação do Coast. Depois que você confia nessa raiz uma vez, workspaces recriados sob a mesma instalação continuam usando-a.\n\nO certificado raiz fica em:\n\n- `~/.coast/caddy/pki/authorities/local/root.crt` para a instalação normal\n- `~/.coast-dev/caddy/pki/authorities/local/root.crt` para `coast-dev`\n\nEles são intencionalmente separados, então confiar em `coast-dev` não faz com que uma instalação normal do `coast` também seja confiável, e vice-versa.\n\nPara inspecionar ou exportar o certificado raiz da instalação ativa:\n\n```bash\ncoast cert info\ncoast cert path\ncoast cert fingerprint\ncoast cert export --to ~/Downloads/coast-root.crt\n```\n\nO Coast deixa a instalação da confiança por sua conta. Exporte o certificado e, em seguida, importe-o para o armazenamento de confiança do seu sistema operacional ou navegador, conforme necessário.\n\n## Você Precisa Fazer Checkout?\n\nNão necessariamente. Todo Coast em execução sempre tem suas próprias portas dinâmicas, e você pode acessar qualquer Coast por essas portas a qualquer momento sem fazer checkout de nada.\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\nVocê pode abrir `localhost:62217` no seu navegador para acessar o servidor web do dev-1 sem fazer checkout. Isso é perfeitamente adequado para muitos fluxos de trabalho, e você pode executar quantos Coasts quiser sem nunca usar `coast checkout`.\n\n## Quando o Checkout É Útil\n\nHá situações em que portas dinâmicas não são suficientes e você precisa de portas canônicas:\n\n- **Aplicações cliente com portas canônicas definidas no código.** Se você tem um cliente rodando fora do Coast — um servidor de desenvolvimento frontend no seu host, um aplicativo móvel no seu telefone ou um aplicativo desktop — que espera `localhost:3000` ou `localhost:8080`, alterar números de porta em todos os lugares é impraticável. Fazer checkout do Coast fornece as portas reais sem mudar nenhuma configuração.\n\n- **Webhooks e URLs de callback.** Serviços como Stripe, GitHub ou provedores OAuth enviam callbacks para uma URL que você registrou — normalmente algo como `https://your-ngrok-tunnel.io` que encaminha para `localhost:3000`. Se você mudar para uma porta dinâmica, os callbacks deixam de chegar. Fazer checkout garante que a porta canônica esteja ativa para o Coast que você está testando.\n\n- **Ferramentas de banco de dados, depuradores e integrações de IDE.** Muitos clientes GUI (pgAdmin, DataGrip, TablePlus), depuradores e configurações de execução da IDE salvam perfis de conexão com uma porta específica. O checkout permite que você mantenha seus perfis salvos e apenas troque qual Coast está por trás deles — sem reconfigurar seu alvo de anexação do depurador ou conexão com o banco de dados toda vez que você muda de contexto.\n\n## Liberando o Checkout\n\nSe você quiser liberar as portas canônicas sem fazer checkout de um Coast diferente:\n\n```bash\ncoast checkout --none\n```\n\nDepois disso, nenhum Coast possui as portas canônicas. Todos os Coasts continuam acessíveis por meio de suas portas dinâmicas.\n\n## Apenas Um por Vez\n\nExatamente um Coast pode estar em checkout por vez. Se `dev-1` estiver em checkout e você executar `coast checkout dev-2`, as portas canônicas trocam instantaneamente para `dev-2`. Não há intervalo — os encaminhadores antigos são encerrados e novos são iniciados na mesma operação.\n\n```text\n┌──────────────────────────────────────────────────┐\n│ Sua máquina │\n│ │\n│ Canônicas (apenas Coast em checkout): │\n│ localhost:3000 ──→ dev-2 web │\n│ localhost:5432 ──→ dev-2 db │\n│ │\n│ Dinâmicas (sempre disponíveis): │\n│ localhost:62217 ──→ dev-1 web │\n│ localhost:55681 ──→ dev-1 db │\n│ localhost:63104 ──→ dev-2 web │\n│ localhost:57220 ──→ dev-2 db │\n└──────────────────────────────────────────────────┘\n```\n\nAs portas dinâmicas não são afetadas pelo checkout. A única coisa que muda é para onde as portas canônicas apontam.\n", "concepts_and_terminology/CLI.md": "# Coast CLI\n\nA Coast CLI (`coast`) é a interface principal de linha de comando para operar Coasts. Ela é intencionalmente enxuta: analisa seu comando, envia uma solicitação para [`coastd`](DAEMON.md) e imprime a saída estruturada de volta no seu terminal.\n\n## Para Que Você a Usa\n\nOs fluxos de trabalho típicos são todos conduzidos a partir da CLI:\n\n```bash\ncoast build # see Builds\ncoast run dev-1 # see Run\ncoast assign dev-1 --worktree feature/oauth # see Assign\ncoast ports dev-1 # see Ports\ncoast checkout dev-1 # see Checkout\ncoast ui # see Coastguard\n```\n\nA CLI também inclui comandos de documentação que são úteis para humanos e agentes:\n\n```bash\ncoast docs\ncoast docs --path concepts_and_terminology/CHECKOUT.md\ncoast search-docs \"canonical vs dynamic ports\"\n```\n\n## Por Que Ela Existe Separadamente do Daemon\n\nSeparar a CLI do daemon oferece alguns benefícios importantes:\n\n- O daemon mantém o estado e processos de longa duração.\n- A CLI permanece rápida, componível e fácil de usar em scripts.\n- Você pode executar comandos pontuais sem manter o estado do terminal ativo.\n- Ferramentas de agentes podem chamar comandos da CLI de maneiras previsíveis e adequadas à automação.\n\n## CLI vs Coastguard\n\nUse a interface que melhor se encaixar no momento:\n\n- A CLI é projetada para cobertura operacional completa: qualquer coisa que você possa fazer no Coastguard também deve ser possível a partir da CLI.\n- Trate a CLI como a interface de automação — scripts, fluxos de trabalho de agentes, jobs de CI e ferramentas personalizadas para desenvolvedores.\n- Trate o [Coastguard](COASTGUARD.md) como a interface humana — inspeção visual, depuração interativa e visibilidade operacional.\n\nAmbos se comunicam com o mesmo daemon, portanto operam sobre o mesmo estado subjacente do projeto.\n", "concepts_and_terminology/COASTFILE_TYPES.md": "# Tipos de Coastfile\n\nUm único projeto pode ter múltiplos Coastfiles para diferentes casos de uso. Cada variante é chamada de \"tipo\". Os tipos permitem compor configurações que compartilham uma base comum, mas diferem em quais serviços são executados, como os volumes são tratados ou se os serviços iniciam automaticamente.\n\n## Como os Tipos Funcionam\n\nA convenção de nomenclatura é `Coastfile` para o padrão e `Coastfile.{type}` para variantes. O sufixo após o ponto se torna o nome do tipo:\n\n- `Coastfile` -- tipo padrão\n- `Coastfile.test` -- tipo de teste\n- `Coastfile.snap` -- tipo de snapshot\n- `Coastfile.light` -- tipo leve\n\nVocê compila e executa Coasts tipados com `--type`:\n\n```bash\ncoast build --type test\ncoast run test-1 --type test\ncoast exec test-1 -- go test ./...\n```\n\n## extends\n\nUm Coastfile tipado herda de um pai via `extends`. Tudo do pai é mesclado. O filho só precisa especificar o que ele sobrescreve ou adiciona.\n\n```toml\n[coast]\nextends = \"Coastfile\"\n```\n\nIsso evita duplicar toda a sua configuração para cada variante. O filho herda todas as configurações de [ports](PORTS.md), [secrets](SECRETS.md), [volumes](VOLUMES.md), [shared services](SHARED_SERVICES.md), [assign strategies](ASSIGN.md), comandos de setup e configurações de [MCP](MCP_SERVERS.md) do pai. Qualquer coisa que o filho definir tem precedência sobre o pai.\n\n## [unset]\n\nRemove itens específicos herdados do pai pelo nome. Você pode remover `ports`, `shared_services`, `secrets` e `volumes`.\n\n```toml\n[unset]\nports = [\"web\", \"redis\", \"backend\"]\nshared_services = [\"postgres\", \"redis\"]\n```\n\nÉ assim que uma variante de teste remove serviços compartilhados (para que os bancos de dados rodem dentro do Coast com volumes isolados) e remove portas de que não precisa.\n\n## [omit]\n\nRemove serviços do compose inteiramente da build. Serviços omitidos são removidos do arquivo compose e não são executados dentro do Coast de forma alguma.\n\n```toml\n[omit]\nservices = [\"redis\", \"backend\", \"mailhog\", \"web\"]\n```\n\nUse isso para excluir serviços que são irrelevantes para o propósito da variante. Uma variante de teste pode manter apenas o banco de dados, as migrações e o executor de testes.\n\n## autostart\n\nControla se `docker compose up` roda automaticamente quando o Coast inicia. O padrão é `true`.\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n```\n\nDefina `autostart = false` para variantes em que você quer executar comandos específicos manualmente em vez de subir a stack completa. Isso é comum para executores de teste -- você cria o Coast e então usa [`coast exec`](EXEC_AND_DOCKER.md) para executar suítes de teste individuais.\n\n## Padrões Comuns\n\n### Variante de teste\n\nUm `Coastfile.test` que mantém apenas o que é necessário para rodar testes:\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n\n[unset]\nports = [\"web\", \"redis\", \"backend\"]\nshared_services = [\"postgres\", \"redis\"]\n\n[omit]\nservices = [\"redis\", \"backend\", \"mailhog\", \"web\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[assign]\ndefault = \"none\"\n[assign.services]\ntest-runner = \"rebuild\"\nmigrations = \"rebuild\"\n```\n\nCada Coast de teste recebe seu próprio banco de dados limpo. Nenhuma porta é exposta porque os testes se comunicam com os serviços pela rede interna do compose. `autostart = false` significa que você dispara as execuções de teste manualmente com `coast exec`.\n\n### Variante de snapshot\n\nUm `Coastfile.snap` que prepara cada Coast com uma cópia dos volumes de banco de dados existentes do host:\n\n```toml\n[coast]\nextends = \"Coastfile\"\n\n[unset]\nshared_services = [\"postgres\", \"redis\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"my_project_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"my_project_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n```\n\nServiços compartilhados são removidos para que os bancos de dados rodem dentro de cada Coast. `snapshot_source` inicializa os volumes isolados a partir de volumes existentes do host no momento da build. Após a criação, os dados de cada instância divergem de forma independente.\n\n### Variante leve\n\nUm `Coastfile.light` que reduz o projeto ao mínimo para um fluxo de trabalho específico -- talvez apenas um serviço de backend e seu banco de dados para iteração rápida.\n\n## Pools de Build Independentes\n\nCada tipo tem seu próprio symlink `latest-{type}` e seu próprio pool de auto-limpeza de 5 builds:\n\n```bash\ncoast build # atualiza latest, faz prune das builds padrão\ncoast build --type test # atualiza latest-test, faz prune das builds de test\ncoast build --type snap # atualiza latest-snap, faz prune das builds de snap\n```\n\nConstruir um tipo `test` não afeta builds `default` nem `snap`. O prune é completamente independente por tipo.\n\n## Executando Coasts Tipados\n\nInstâncias criadas com `--type` são marcadas com seu tipo. Você pode ter instâncias de diferentes tipos rodando simultaneamente para o mesmo projeto:\n\n```bash\ncoast run dev-1 # tipo padrão\ncoast run test-1 --type test # tipo de teste\ncoast run snapshot-1 --type snap # tipo de snapshot\n\ncoast ls\n# Todas as três aparecem, cada uma com seu próprio tipo, portas e estratégia de volume\n```\n\nÉ assim que você pode ter um ambiente completo de dev rodando ao lado de executores de teste isolados e instâncias inicializadas por snapshot, tudo para o mesmo projeto, tudo ao mesmo tempo.\n", "concepts_and_terminology/COASTGUARD.md": "# Coastguard\n\nCoastguard é a UI web local do Coast (pense: uma interface no estilo Docker Desktop do Coast), executando na porta `31415`. Ela é iniciada a partir da CLI:\n\n```bash\ncoast ui\n```\n\n![Coastguard project overview](../../assets/coastguard-overview.png)\n*O painel do projeto mostrando instâncias do Coast em execução, suas branches/worktrees e o estado do checkout.*\n\n![Coastguard port mappings](../../assets/coastguard-ports.png)\n*A página de portas para uma instância específica do Coast, mostrando mapeamentos de portas canônicos e dinâmicos para cada serviço.*\n\n## Para que o Coastguard é Bom\n\nO Coastguard oferece uma superfície visual de controle e observabilidade para o seu projeto:\n\n- Ver projetos, instâncias, status, branches e estado do checkout.\n- Inspecionar [mapeamentos de portas](PORTS.md) e ir diretamente para os serviços.\n- Visualizar [logs](LOGS.md), estatísticas de runtime e inspecionar dados.\n- Navegar por [builds](BUILDS.md), artefatos de imagem, metadados de [volumes](VOLUMES.md) e [secrets](SECRETS.md).\n- Navegar pela documentação no app enquanto trabalha.\n\n## Relação com a CLI e o Daemon\n\nO Coastguard não substitui a CLI. Ele a complementa como a interface voltada para humanos.\n\n- A [CLI `coast`](CLI.md) é a interface de automação para scripts, fluxos de trabalho de agentes e integrações de ferramentas.\n- O Coastguard é a interface humana para inspeção visual, depuração interativa e visibilidade operacional do dia a dia.\n- Ambos são clientes do [`coastd`](DAEMON.md), então permanecem sincronizados.\n", "concepts_and_terminology/COASTS.md": "# Coasts\n\nUma Coast é um ambiente de execução autocontido do seu projeto. Ela é executada dentro de um [container Docker-in-Docker](RUNTIMES_AND_SERVICES.md), e vários serviços (seu servidor web, banco de dados, cache, etc.) podem ser executados dentro de uma única instância de Coast.\n\n```text\n┌─── Coast: dev-1 (branch: feature/oauth) ──────────────┐\n│ │\n│ ┌─────────┐ ┌──────────┐ ┌─────────┐ │\n│ │ web │ │ postgres │ │ redis │ │\n│ │ :3000 │ │ :5432 │ │ :6379 │ │\n│ └─────────┘ └──────────┘ └─────────┘ │\n│ │\n│ dynamic ports: 62217, 55681, 56905 │\n└───────────────────────────────────────────────────────┘\n\n┌─── Coast: dev-2 (branch: feature/billing) ────────────┐\n│ │\n│ ┌─────────┐ ┌──────────┐ ┌─────────┐ │\n│ │ web │ │ postgres │ │ redis │ │\n│ │ :3000 │ │ :5432 │ │ :6379 │ │\n│ └─────────┘ └──────────┘ └─────────┘ │\n│ │\n│ dynamic ports: 63104, 57220, 58412 │\n└───────────────────────────────────────────────────────┘\n```\n\nCada Coast expõe seu próprio conjunto de [portas dinâmicas](PORTS.md) para a máquina host, o que significa que você pode acessar qualquer Coast em execução a qualquer momento, independentemente do que mais estiver em execução.\n\nQuando você faz [checkout](CHECKOUT.md) de uma Coast, as portas canônicas do projeto são mapeadas para ela — então `localhost:3000` acessa a Coast em checkout em vez de uma porta dinâmica.\n\n```text\ncoast checkout dev-1\n\nlocalhost:3000 ──→ dev-1 web\nlocalhost:5432 ──→ dev-1 postgres\nlocalhost:6379 ──→ dev-1 redis\n\ncoast checkout dev-2 (instant swap)\n\nlocalhost:3000 ──→ dev-2 web\nlocalhost:5432 ──→ dev-2 postgres\nlocalhost:6379 ──→ dev-2 redis\n```\n\nNormalmente, uma Coast é [atribuída a uma worktree específica](ASSIGN.md). É assim que você executa várias worktrees do mesmo projeto em paralelo sem conflitos de porta ou colisões de volume.\n\nVocê cria instâncias de Coast com [`coast run`](RUN.md). Cabe a você iniciar e encerrar Coasts como achar melhor. Você provavelmente não gostaria de ter 20 Coasts de um projeto intensivo em memória em execução ao mesmo tempo, mas cada um sabe de si.\n", "concepts_and_terminology/DAEMON.md": "# Daemon do Coast\n\nO daemon do Coast (`coastd`) é o processo local de longa duração que faz o trabalho real de orquestração. O [CLI](CLI.md) e o [Coastguard](COASTGUARD.md) são clientes; `coastd` é o plano de controle por trás deles.\n\n## Arquitetura em um Relance\n\n```text\ncoast CLI (automation) -----+\n +--> coastd daemon\nCoastguard UI (human) ------+ |\n +--> Coasts\n +--> Ports\n +--> State\n```\n\nO CLI envia solicitações ao `coastd` por meio de um socket Unix local; o Coastguard se conecta por um WebSocket. O daemon aplica alterações ao estado em tempo de execução.\n\n## O Que Ele Faz\n\nO `coastd` lida com as operações que precisam de estado persistente e coordenação em segundo plano:\n\n- Rastreia instâncias do Coast, builds e serviços compartilhados.\n- Cria, inicia, para e remove runtimes do Coast.\n- Aplica operações de assign/unassign/checkout.\n- Gerencia o [encaminhamento de portas](PORTS.md) canônico e dinâmico.\n- Transmite [logs](LOGS.md), status e eventos de runtime para clientes CLI e UI.\n\nEm resumo: se você executar `coast run`, `coast assign`, `coast checkout` ou `coast ls`, o daemon é o componente que está fazendo o trabalho.\n\n## Como Ele Roda\n\nVocê pode executar o daemon de duas formas comuns:\n\n```bash\n# Register daemon auto-start at login (recommended)\ncoast daemon install\n\n# Manual start mode\ncoast daemon start\n```\n\nSe você pular o daemon install, precisa iniciá-lo manualmente a cada sessão antes de usar os comandos do Coast.\n\n## Relatando Bugs\n\nSe você encontrar problemas, inclua os logs do daemon `coastd` ao enviar um relatório de bug. Os logs contêm o contexto necessário para diagnosticar a maioria dos problemas:\n\n```bash\ncoast daemon logs\n```\n", - "concepts_and_terminology/EXEC_AND_DOCKER.md": "# Exec & Docker\n\n`coast exec` coloca você em um shell dentro do contêiner DinD do Coast. Seu diretório de trabalho é `/workspace` — a [raiz do projeto montada via bind](FILESYSTEM.md) onde seu Coastfile fica. Esta é a principal forma de executar comandos, inspecionar arquivos ou depurar serviços dentro de um Coast a partir da sua máquina host.\n\n`coast docker` é o comando complementar para falar diretamente com o daemon Docker interno.\n\n## `coast exec`\n\nAbra um shell dentro de uma instância do Coast:\n\n```bash\ncoast exec dev-1\n```\n\nIsso inicia uma sessão `sh` em `/workspace`. Os contêineres do Coast são baseados em Alpine, então o shell padrão é `sh`, não `bash`.\n\nVocê também pode executar um comando específico sem entrar em um shell interativo:\n\n```bash\ncoast exec dev-1 ls -la\ncoast exec dev-1 -- npm install\ncoast exec dev-1 -- go test ./...\n```\n\nTudo após o nome da instância é passado como o comando. Use `--` para separar flags que pertencem ao seu comando das flags que pertencem ao `coast exec`.\n\n### Working Directory\n\nO shell começa em `/workspace`, que é a raiz do seu projeto no host montada via bind dentro do contêiner. Isso significa que seu código-fonte, Coastfile e todos os arquivos do projeto estão ali:\n\n```text\n/workspace $ ls\nCoastfile README.md apps/ packages/\nCoastfile.light go.work infra/ scripts/\nCoastfile.snap go.work.sum package-lock.json\n```\n\nQualquer alteração que você fizer em arquivos sob `/workspace` é refletida no host imediatamente — é uma montagem via bind, não uma cópia.\n\n### Interactive vs Non-Interactive\n\nQuando o stdin é um TTY (você está digitando em um terminal), `coast exec` ignora o daemon completamente e executa `docker exec -it` diretamente para passthrough total de TTY. Isso significa que cores, movimento do cursor, autocompletar com tab e programas interativos funcionam como esperado.\n\nQuando o stdin é redirecionado (piped) ou executado via script (CI, fluxos de trabalho de agentes, `coast exec dev-1 -- some-command | grep foo`), a requisição passa pelo daemon e retorna stdout, stderr e um código de saída estruturados.\n\n### File Permissions\n\nO exec roda com o UID:GID do seu usuário do host, então os arquivos criados dentro do Coast têm a propriedade correta no host. Sem incompatibilidades de permissão entre host e contêiner.\n\n## `coast docker`\n\nEnquanto `coast exec` oferece um shell no próprio contêiner DinD, `coast docker` permite executar comandos do Docker CLI contra o daemon Docker **interno** — aquele que gerencia seus serviços do compose.\n\n```bash\ncoast docker dev-1 # defaults to: docker ps\ncoast docker dev-1 ps # same as above\ncoast docker dev-1 compose ps # docker compose ps (inner services)\ncoast docker dev-1 images # list images in the inner daemon\ncoast docker dev-1 compose logs web # docker compose logs for a service\n```\n\nTodo comando que você passar é automaticamente prefixado com `docker`. Então `coast docker dev-1 compose ps` executa `docker compose ps` dentro do contêiner Coast, falando com o daemon interno.\n\n### `coast exec` vs `coast docker`\n\nA distinção é o que você está direcionando:\n\n| Command | Runs as | Target |\n|---|---|---|\n| `coast exec dev-1 ls /workspace` | `sh -c \"ls /workspace\"` in DinD container | O próprio contêiner Coast (seus arquivos do projeto, ferramentas instaladas) |\n| `coast docker dev-1 ps` | `docker ps` in DinD container | O daemon Docker interno (seus contêineres de serviço do compose) |\n| `coast docker dev-1 compose logs web` | `docker compose logs web` in DinD container | Logs de um serviço específico do compose via o daemon interno |\n\nUse `coast exec` para trabalho no nível do projeto — executar testes, instalar dependências, inspecionar arquivos. Use `coast docker` quando você precisar ver o que o daemon Docker interno está fazendo — status de contêiner, imagens, redes, operações do compose.\n\n## Coastguard Exec Tab\n\nA UI web do Coastguard fornece um terminal interativo persistente conectado via WebSocket.\n\n![Exec tab in Coastguard](../../assets/coastguard-exec.png)\n*A aba Exec do Coastguard mostrando uma sessão de shell em /workspace dentro de uma instância do Coast.*\n\nO terminal é alimentado pelo xterm.js e oferece:\n\n- **Sessões persistentes** — sessões de terminal sobrevivem à navegação de páginas e ao refresh do navegador. Ao reconectar, o buffer de scrollback é reproduzido para que você retome de onde parou.\n- **Múltiplas abas** — abra vários shells ao mesmo tempo. Cada aba é uma sessão independente.\n- Abas de **[Agent shell](AGENT_SHELLS.md)** — crie shells dedicados para agentes de codificação com IA, com rastreamento de status ativo/inativo.\n- **Modo tela cheia** — expanda o terminal para preencher a tela (Escape para sair).\n\nAlém da aba de exec no nível da instância, o Coastguard também fornece acesso ao terminal em outros níveis:\n\n- **Exec de serviço** — clique em um serviço individual na aba Services para obter um shell dentro daquele contêiner interno específico (isso faz um `docker exec` duplo — primeiro no contêiner DinD, depois no contêiner do serviço).\n- Exec de **[Shared service](SHARED_SERVICES.md)** — obtenha um shell dentro de um contêiner de serviço compartilhado no nível do host.\n- **Terminal do host** — um shell na sua máquina host na raiz do projeto, sem entrar em um Coast.\n\n## When to Use Which\n\n- **`coast exec`** — execute comandos no nível do projeto (npm install, go test, inspeção de arquivos, depuração) dentro do contêiner DinD.\n- **`coast docker`** — inspecione ou gerencie o daemon Docker interno (status de contêiner, imagens, redes, operações do compose).\n- **Aba Exec do Coastguard** — depuração interativa com sessões persistentes, múltiplas abas e suporte a agent shell. Melhor quando você quer manter vários terminais abertos enquanto navega pelo restante da UI.\n- **`coast logs`** — para ler a saída do serviço, use `coast logs` em vez de `coast docker compose logs`. Veja [Logs](LOGS.md).\n- **`coast ps`** — para verificar o status do serviço, use `coast ps` em vez de `coast docker compose ps`. Veja [Runtimes and Services](RUNTIMES_AND_SERVICES.md).\n", + "concepts_and_terminology/EXEC_AND_DOCKER.md": "# Exec & Docker\n\n`coast exec` coloca você em um shell dentro do contêiner DinD do Coast. Seu diretório de trabalho é `/workspace` — a [raiz do projeto montada por bind](FILESYSTEM.md) onde seu Coastfile está. Esta é a principal forma de executar comandos, inspecionar arquivos ou depurar serviços dentro de um Coast a partir da sua máquina host.\n\n`coast docker` é o comando complementar para falar diretamente com o daemon Docker interno.\n\n## `coast exec`\n\nAbra um shell dentro de uma instância Coast:\n\n```bash\ncoast exec dev-1\n```\n\nIsso inicia uma sessão `sh` em `/workspace`. Os contêineres Coast são baseados em Alpine, então o shell padrão é `sh`, não `bash`.\n\nVocê também pode executar um comando específico sem entrar em um shell interativo:\n\n```bash\ncoast exec dev-1 ls -la\ncoast exec dev-1 -- npm install\ncoast exec dev-1 -- go test ./...\ncoast exec dev-1 --service web\ncoast exec dev-1 --service web -- php artisan test\n```\n\nTudo após o nome da instância é passado como o comando. Use `--` para separar flags que pertencem ao seu comando das flags que pertencem a `coast exec`.\n\nPasse `--service ` para direcionar a um contêiner de serviço compose específico em vez do contêiner Coast externo. Passe `--root` quando você precisar de acesso bruto como root do contêiner em vez do mapeamento padrão UID:GID do host feito pelo Coast.\n\n### Working Directory\n\nO shell inicia em `/workspace`, que é a raiz do seu projeto no host montada por bind dentro do contêiner. Isso significa que seu código-fonte, Coastfile e todos os arquivos do projeto estão ali:\n\n```text\n/workspace $ ls\nCoastfile README.md apps/ packages/\nCoastfile.light go.work infra/ scripts/\nCoastfile.snap go.work.sum package-lock.json\n```\n\nQuaisquer alterações que você fizer em arquivos sob `/workspace` são refletidas no host imediatamente — é uma montagem bind, não uma cópia.\n\n### Interactive vs Non-Interactive\n\nQuando stdin é um TTY (você está digitando em um terminal), `coast exec` ignora completamente o daemon e executa `docker exec -it` diretamente para passthrough completo de TTY. Isso significa que cores, movimento do cursor, autocompletar com tab e programas interativos funcionam como esperado.\n\nQuando stdin é canalizado ou roteirizado (CI, fluxos de trabalho de agentes, `coast exec dev-1 -- some-command | grep foo`), a solicitação passa pelo daemon e retorna stdout, stderr e um código de saída estruturados.\n\n### File Permissions\n\nO exec é executado como o UID:GID do usuário do seu host, então os arquivos criados dentro do Coast têm a propriedade correta no host. Sem incompatibilidades de permissão entre host e contêiner.\n\n## `coast docker`\n\nEnquanto `coast exec` fornece um shell no próprio contêiner DinD, `coast docker` permite que você execute comandos da CLI do Docker contra o daemon Docker **interno** — aquele que gerencia seus serviços compose.\n\n```bash\ncoast docker dev-1 # defaults to: docker ps\ncoast docker dev-1 ps # same as above\ncoast docker dev-1 compose ps # docker compose ps for the active Coast-managed stack\ncoast docker dev-1 images # list images in the inner daemon\ncoast docker dev-1 compose logs web # docker compose logs for a service\n```\n\nCada comando que você passa recebe automaticamente o prefixo `docker`. Portanto, `coast docker dev-1 compose ps` executa `docker compose ps` dentro do contêiner Coast, falando com o daemon interno.\n\n### `coast exec` vs `coast docker`\n\nA distinção é o que você está direcionando:\n\n| Command | Runs as | Target |\n|---|---|---|\n| `coast exec dev-1 ls /workspace` | `sh -c \"ls /workspace\"` no contêiner DinD | O próprio contêiner Coast (os arquivos do seu projeto, ferramentas instaladas) |\n| `coast exec dev-1 --service web` | `docker exec ... sh` no contêiner de serviço interno resolvido | Um contêiner de serviço compose específico |\n| `coast docker dev-1 ps` | `docker ps` no contêiner DinD | O daemon Docker interno (os contêineres de serviço compose) |\n| `coast docker dev-1 compose logs web` | `docker compose logs web` no contêiner DinD | Os logs de um serviço compose específico via o daemon interno |\n\nUse `coast exec` para trabalho no nível do projeto — executar testes, instalar dependências, inspecionar arquivos. Use `coast docker` quando você precisar ver o que o daemon Docker interno está fazendo — status de contêineres, imagens, redes, operações do compose.\n\n## Coastguard Exec Tab\n\nA interface web do Coastguard fornece um terminal interativo persistente conectado via WebSocket.\n\n![Exec tab in Coastguard](../../assets/coastguard-exec.png)\n*A aba Exec do Coastguard mostrando uma sessão de shell em /workspace dentro de uma instância Coast.*\n\nO terminal é alimentado por xterm.js e oferece:\n\n- **Sessões persistentes** — as sessões de terminal sobrevivem à navegação entre páginas e à atualização do navegador. Reconectar reproduz o buffer de rolagem para que você retome de onde parou.\n- **Múltiplas abas** — abra vários shells ao mesmo tempo. Cada aba é uma sessão independente.\n- **Abas de [Agent shell](AGENT_SHELLS.md)** — inicie shells dedicados de agente para agentes de codificação com IA, com rastreamento de status ativo/inativo.\n- **Modo de tela cheia** — expanda o terminal para preencher a tela (Escape para sair).\n\nAlém da aba exec no nível da instância, o Coastguard também fornece acesso a terminal em outros níveis:\n\n- **Exec de serviço** — clique em um serviço individual na aba Services para obter um shell dentro desse contêiner interno específico (isso faz um `docker exec` duplo — primeiro no contêiner DinD, depois no contêiner do serviço).\n- **Exec de [serviço compartilhado](SHARED_SERVICES.md)** — obtenha um shell dentro de um contêiner de serviço compartilhado no nível do host.\n- **Terminal do host** — um shell na sua máquina host na raiz do projeto, sem entrar em um Coast.\n\n## When to Use Which\n\n- **`coast exec`** — execute comandos no nível do projeto dentro do contêiner DinD, ou passe `--service` para abrir um shell ou executar um comando dentro de um contêiner de serviço compose específico.\n- **`coast docker`** — inspecione ou gerencie o daemon Docker interno (status de contêineres, imagens, redes, operações do compose).\n- **Aba Exec do Coastguard** — depuração interativa com sessões persistentes, múltiplas abas e suporte a agent shell. Ideal quando você quer manter vários terminais abertos enquanto navega pelo restante da interface.\n- **`coast logs`** — para ler a saída do serviço, use `coast logs` em vez de `coast docker compose logs`. Veja [Logs](LOGS.md).\n- **`coast ps`** — para verificar o status do serviço, use `coast ps` em vez de `coast docker compose ps`. Veja [Runtimes and Services](RUNTIMES_AND_SERVICES.md).\n", "concepts_and_terminology/FILESYSTEM.md": "# Sistema de arquivos\n\nSua máquina host e todas as instâncias do Coast compartilham os mesmos arquivos do projeto. A raiz do projeto no host é montada com leitura e escrita no contêiner DinD em `/host-project`, e o Coast faz um bind-mount da árvore de trabalho ativa em `/workspace`. É isso que torna possível que um agente rodando na sua máquina host edite código enquanto os serviços dentro do Coast capturam as alterações em tempo real.\n\n## A Montagem Compartilhada\n\n```text\nHost machine\n│\n├── ~/dev/my-app/ (project root)\n│ ├── src/\n│ ├── Coastfile\n│ ├── docker-compose.yml\n│ └── .worktrees/ (worktrees, gitignored)\n│ ├── feature-auth/\n│ └── feature-billing/\n│\n└── Docker daemon (host)\n │\n └── Coast: dev-1 (docker:dind)\n │\n ├── /host-project ← Docker bind mount of project root (RW, fixed)\n │\n ├── /workspace ← mount --bind /host-project (switchable)\n │ ├── src/ same files, same bytes, instant sync\n │ ├── Coastfile\n │ └── docker-compose.yml\n │\n └── Inner Docker daemon\n └── web service\n └── /app ← compose bind mount from /workspace/src\n```\n\nA raiz do projeto no host é montada com leitura e escrita em `/host-project` dentro do [contêiner DinD](RUNTIMES_AND_SERVICES.md) quando o contêiner é criado. Depois que o contêiner inicia, um `mount --bind /host-project /workspace` dentro do contêiner cria o caminho de trabalho `/workspace` com propagação de montagem compartilhada (`mount --make-rshared`), para que serviços do compose interno que fazem bind-mount de subdiretórios de `/workspace` vejam o conteúdo correto.\n\nEssa abordagem em duas etapas existe por um motivo: o bind mount do Docker em `/host-project` é fixo na criação do contêiner e não pode ser alterado sem recriar o contêiner. Mas o bind mount do Linux em `/workspace` dentro do contêiner pode ser desmontado e refeito apontando para um subdiretório diferente — uma worktree — sem tocar no ciclo de vida do contêiner. É isso que torna `coast assign` rápido.\n\n`/workspace` é leitura e escrita. As alterações de arquivos fluem instantaneamente nos dois sentidos. Salve um arquivo no host e um servidor de desenvolvimento dentro do Coast o captura. Crie um arquivo dentro do Coast e ele aparece no host.\n\n## Agentes no Host e Coast\n\n```text\n┌─── Host machine ──────────────────────────────────────────┐\n│ │\n│ AI Agent (Cursor, Claude Code, etc.) │\n│ │ │\n│ ├── reads/writes files at /src/ │\n│ │ ↕ (instant, same filesystem) │\n│ ├── coast logs dev-1 --service web --tail 50 │\n│ ├── coast ps dev-1 │\n│ └── coast exec dev-1 -- npm test │\n│ │\n├───────────────────────────────────────────────────────────┤\n│ │\n│ Coast: dev-1 │\n│ └── /workspace/src/ ← same bytes as host project/src │\n│ └── web service picks up changes on save │\n│ │\n└───────────────────────────────────────────────────────────┘\n```\n\nComo o sistema de arquivos é compartilhado, um agente de codificação por IA rodando no host pode editar arquivos livremente e os serviços em execução dentro do Coast veem as alterações imediatamente. O agente não precisa rodar dentro do contêiner do Coast — ele opera a partir do host normalmente.\n\nQuando o agente precisa de informações de runtime — logs, status de serviços, saída de testes — ele chama comandos da CLI do Coast a partir do host:\n\n- `coast logs dev-1 --service web --tail 50` para a saída do serviço (veja [Logs](LOGS.md))\n- `coast ps dev-1` para o status do serviço (veja [Runtimes and Services](RUNTIMES_AND_SERVICES.md))\n- `coast exec dev-1 -- npm test` para executar comandos dentro do Coast (veja [Exec & Docker](EXEC_AND_DOCKER.md))\n\nEsta é a vantagem arquitetural fundamental: **a edição de código acontece no host, o runtime acontece no Coast, e o sistema de arquivos compartilhado faz a ponte entre eles.** O agente no host nunca precisa estar \"dentro\" do Coast para fazer seu trabalho.\n\n## Troca de Worktree\n\nQuando `coast assign` alterna um Coast para uma worktree diferente, ele remonta `/workspace` para apontar para aquela worktree do git em vez da raiz do projeto:\n\n```text\ncoast assign dev-1 --worktree feature-auth\n\nBefore: /workspace ←──mount── /host-project (project root)\nAfter: /workspace ←──mount── /host-project/.worktrees/feature-auth (worktree)\n```\n\nA worktree é criada no host em `{project_root}/.worktrees/{worktree_name}`. O nome do diretório `.worktrees` é configurável via `worktree_dir` no seu Coastfile e deve estar no seu `.gitignore`.\n\nSe a worktree for nova, o Coast faz o bootstrap de arquivos selecionados ignorados pelo git a partir da raiz do projeto antes da remontagem. Ele enumera arquivos ignorados com `git ls-files --others --ignored --exclude-standard`, filtra diretórios comuns e pesados mais quaisquer `exclude_paths` configurados, e então usa `rsync --files-from` com `--link-dest` para criar hardlinks dos arquivos selecionados dentro da worktree. O Coast registra esse bootstrap em metadados internos da worktree e o pula em atribuições posteriores para a mesma worktree, a menos que você explicitamente o atualize com `coast assign --force-sync`.\n\nDentro do contêiner, `/workspace` é lazy-unmounted e refeito apontando para o subdiretório da worktree em `/host-project/.worktrees/{branch_name}`. Essa remontagem é rápida — ela não recria o contêiner DinD nem reinicia o daemon Docker interno. Serviços do compose e serviços bare ainda podem ser recriados ou reiniciados após a remontagem para que seus bind mounts resolvam através do novo `/workspace`.\n\nGrandes diretórios de dependências como `node_modules` não fazem parte deste caminho genérico de bootstrap. Eles normalmente são tratados por meio de caches ou volumes específicos do serviço.\n\nSe você usar `[assign.rebuild_triggers]`, o Coast também executa `git diff --name-only ..` no host para decidir se um serviço marcado como `rebuild` pode ser rebaixado para `restart`. Veja [Assign and Unassign](ASSIGN.md) e [Performance Optimizations](PERFORMANCE_OPTIMIZATIONS.md) para os detalhes que afetam a latência do assign.\n\n`coast unassign` reverte `/workspace` de volta para `/host-project` (a raiz do projeto). `coast start` após um stop reaplica a montagem correta com base em se a instância tem uma worktree atribuída.\n\n## Todas as Montagens\n\nTodo contêiner do Coast tem estas montagens:\n\n| Path | Type | Access | Purpose |\n|---|---|---|---|\n| `/workspace` | bind mount (in-container) | RW | Raiz do projeto ou worktree. Alternável no assign. |\n| `/host-project` | Docker bind mount | RW | Raiz bruta do projeto. Fixa na criação do contêiner. |\n| `/image-cache` | Docker bind mount | RO | Tarballs OCI pré-baixados de `~/.coast/image-cache/`. |\n| `/coast-artifact` | Docker bind mount | RO | Artefato de build com arquivos compose reescritos. |\n| `/coast-override` | Docker bind mount | RO | Overrides de compose gerados para [serviços compartilhados](SHARED_SERVICES.md). |\n| `/var/lib/docker` | Named volume | RW | Estado do daemon Docker interno. Persiste entre remoções do contêiner. |\n\nAs montagens somente leitura são infraestrutura — elas carregam o artefato de build, imagens em cache e overrides de compose que o Coast gera. Você interage com elas indiretamente por meio de `coast build` e do Coastfile. As montagens de leitura e escrita são onde seu código vive e onde o daemon interno armazena seu estado.\n", "concepts_and_terminology/LOGS.md": "# Logs\n\nOs serviços dentro de uma instância do Coast são executados em contêineres aninhados — seus serviços do compose são gerenciados por um daemon Docker interno dentro de um contêiner DinD. Isso significa que ferramentas de logging no nível do host não conseguem vê-los. Se o seu fluxo de trabalho inclui um logging MCP que lê logs do Docker no host, ele verá apenas o contêiner DinD externo, não o servidor web, banco de dados ou worker executando dentro dele.\n\nA solução é `coast logs`. Qualquer agente ou ferramenta que precise ler a saída de serviços de uma instância do Coast deve usar o Coast CLI em vez de acessar logs do Docker no nível do host.\n\n## The MCP Tradeoff\n\nSe você estiver usando um agente de IA com um logging MCP (uma ferramenta que captura logs de contêineres Docker do seu host — veja [MCP Servers](MCP_SERVERS.md)), esse MCP não funcionará para serviços executando dentro de uma instância do Coast. O daemon Docker do host vê um contêiner por instância do Coast — o contêiner DinD — e seus logs são apenas a saída de inicialização do daemon Docker interno.\n\nPara capturar os logs reais dos serviços, instrua seu agente a usar:\n\n```bash\ncoast logs --service --tail \n```\n\nPor exemplo, se o seu agente precisar inspecionar por que um serviço de backend está falhando:\n\n```bash\ncoast logs dev-1 --service backend --tail 100\n```\n\nIsso é o equivalente a `docker compose logs`, mas roteado pelo daemon do Coast para dentro do contêiner DinD interno. Se você tiver regras de agente ou prompts de sistema que referenciem um logging MCP, você precisará adicionar uma instrução que sobrescreva esse comportamento ao trabalhar dentro de uma instância do Coast.\n\n## `coast logs`\n\nO CLI oferece várias formas de ler logs de uma instância do Coast:\n\n```bash\ncoast logs dev-1 # last 200 lines, all services\ncoast logs dev-1 --service web # last 200 lines, web only\ncoast logs dev-1 --tail 50 # last 50 lines, then follow\ncoast logs dev-1 --tail # all lines, then follow\ncoast logs dev-1 --service backend -f # follow mode (stream new entries)\ncoast logs dev-1 --service web --tail 100 # last 100 lines + follow\n```\n\nSem `--tail` ou `-f`, o comando retorna as últimas 200 linhas e encerra. Com `--tail`, ele transmite a quantidade de linhas solicitada e então continua acompanhando a nova saída em tempo real. `-f` / `--follow` habilita o modo de acompanhamento por si só.\n\nA saída usa o formato de logs do compose com um prefixo de serviço em cada linha:\n\n```text\nweb | 2026/02/28 01:49:34 Listening on :3000\nbackend | 2026/02/28 01:49:34 [INFO] Server started on :8080\nbackend | 2026/02/28 01:49:34 [ProcessCreditsJob] starting at 2026-02-28T01:49:34Z\nredis | 1:M 28 Feb 2026 01:49:30.123 * Ready to accept connections\n```\n\nVocê também pode filtrar por serviço com a sintaxe posicional legada (`coast logs dev-1 web`), mas a flag `--service` é a preferida.\n\n## Coastguard Logs Tab\n\nA UI web do Coastguard oferece uma experiência mais rica de visualização de logs com streaming em tempo real via WebSocket.\n\n![Logs tab in Coastguard](../../assets/coastguard-logs.png)\n*A aba Logs do Coastguard transmitindo a saída do serviço backend com filtragem por serviço e pesquisa.*\n\nA aba Logs oferece:\n\n- **Streaming em tempo real** — os logs chegam por uma conexão WebSocket conforme são produzidos, com um indicador de status mostrando o estado da conexão.\n- **Filtro de serviço** — um dropdown preenchido a partir dos prefixos de serviço do stream de logs. Selecione um único serviço para focar na sua saída.\n- **Pesquisa** — filtre as linhas exibidas por texto ou regex (ative o botão de asterisco para o modo regex). Os termos correspondentes são destacados.\n- **Contagem de linhas** — mostra linhas filtradas vs linhas totais (por exemplo, \"200 / 971 lines\").\n- **Limpar** — trunca os arquivos de log do contêiner interno e reinicia o visualizador.\n- **Tela cheia** — expande o visualizador de logs para preencher a tela.\n\nAs linhas de log são renderizadas com suporte a cores ANSI, destaque de nível de log (ERROR em vermelho, WARN em âmbar, INFO em azul, DEBUG em cinza), atenuação de timestamp e badges de serviço coloridas para distinção visual entre serviços.\n\nServiços compartilhados executando no daemon do host têm seu próprio visualizador de logs acessível pela aba Shared Services. Veja [Shared Services](SHARED_SERVICES.md) para detalhes.\n\n## How It Works\n\nQuando você executa `coast logs`, o daemon executa `docker compose logs` dentro do contêiner DinD via `docker exec` e transmite a saída de volta para o seu terminal (ou para a UI do Coastguard via WebSocket).\n\n```text\ncoast logs dev-1 --service web --tail 50\n │\n ├── CLI sends LogsRequest to daemon (Unix socket)\n │\n ├── Daemon resolves instance → container ID\n │\n ├── Daemon exec's into DinD container:\n │ docker compose logs --tail 50 --follow web\n │\n └── Output streams back chunk by chunk\n └── CLI prints to stdout / Coastguard renders in UI\n```\n\nPara [bare services](BARE_SERVICES.md), o daemon faz tail dos arquivos de log em `/var/log/coast-services/` em vez de chamar `docker compose logs`. O formato de saída é o mesmo (`service | line`), então a filtragem por serviço funciona de forma idêntica em ambos os casos.\n\n## Related Commands\n\n- `coast ps ` — verifique quais serviços estão em execução e seu status. Veja [Runtimes and Services](RUNTIMES_AND_SERVICES.md).\n- [`coast exec `](EXEC_AND_DOCKER.md) — abra um shell dentro do contêiner do Coast para depuração manual.\n", "concepts_and_terminology/LOOKUP.md": "# Lookup\n\n`coast lookup` descobre quais instâncias do Coast estão em execução para o diretório de trabalho atual do chamador. É o primeiro comando que um agente do lado do host deve executar para se orientar — \"Estou editando código aqui, com qual(is) Coast(s) devo interagir?\"\n\n```bash\ncoast lookup\n```\n\nO Lookup detecta se você está dentro de um [worktree](ASSIGN.md) ou na raiz do projeto, consulta o daemon por instâncias correspondentes e imprime os resultados com portas, URLs e comandos de exemplo.\n\n## Por Que Isso Existe\n\nUm agente de codificação com IA rodando no host (Cursor, Claude Code, Codex, etc.) edita arquivos através do [filesystem compartilhado](FILESYSTEM.md) e chama comandos da Coast CLI para operações de runtime. Mas primeiro o agente precisa responder a uma pergunta básica: **qual instância do Coast corresponde ao diretório em que estou trabalhando?**\n\nSem `coast lookup`, o agente teria que executar `coast ls`, analisar a tabela completa de instâncias, descobrir em qual worktree está e fazer a correlação. `coast lookup` faz tudo isso em um único passo e retorna uma saída estruturada que os agentes podem consumir diretamente.\n\nEste comando deve ser incluído em qualquer SKILL.md, AGENTS.md ou arquivo de regras de nível superior para fluxos de trabalho de agentes que usam Coast. Ele é o ponto de entrada para um agente descobrir seu contexto de runtime.\n\n## Modos de Saída\n\n### Padrão (legível para humanos)\n\n```bash\ncoast lookup\n```\n\n```text\nCoast instances for worktree feature/oauth (my-app):\n\n dev-1 running ★ checked out\n\n Primary URL: http://dev-1.localhost:62217\n\n SERVICE CANONICAL DYNAMIC\n ★ web 3000 62217\n api 8080 63889\n postgres 5432 55681\n\n Examples (exec starts at the workspace root where your Coastfile is, cd to your target directory first):\n coast exec dev-1 -- sh -c \"cd && \"\n coast logs dev-1 --service \n coast ps dev-1\n```\n\nA seção de exemplos lembra agentes (e humanos) de que `coast exec` começa na raiz do workspace — o diretório onde o Coastfile está. Para executar um comando em um subdiretório, faça `cd` para ele dentro do exec.\n\n### Compacto (`--compact`)\n\nRetorna um array JSON de nomes de instâncias. Projetado para scripts e ferramentas de agentes que só precisam saber quais instâncias devem ser alvo.\n\n```bash\ncoast lookup --compact\n```\n\n```text\n[\"dev-1\"]\n```\n\nMúltiplas instâncias no mesmo worktree:\n\n```text\n[\"dev-1\",\"dev-2\"]\n```\n\nNenhuma correspondência:\n\n```text\n[]\n```\n\n### JSON (`--json`)\n\nRetorna a resposta estruturada completa como JSON com pretty-print. Projetado para agentes que precisam de portas, URLs e status em um formato legível por máquina.\n\n```bash\ncoast lookup --json\n```\n\n```json\n{\n \"project\": \"my-app\",\n \"worktree\": \"feature/oauth\",\n \"project_root\": \"/Users/dev/my-app\",\n \"instances\": [\n {\n \"name\": \"dev-1\",\n \"status\": \"Running\",\n \"checked_out\": true,\n \"branch\": \"feature/oauth\",\n \"primary_url\": \"http://dev-1.localhost:62217\",\n \"ports\": [\n { \"logical_name\": \"web\", \"canonical_port\": 3000, \"dynamic_port\": 62217, \"is_primary\": true },\n { \"logical_name\": \"api\", \"canonical_port\": 8080, \"dynamic_port\": 63889, \"is_primary\": false }\n ]\n }\n ]\n}\n```\n\n## Como Ele Resolve\n\nO Lookup sobe a partir do diretório de trabalho atual para encontrar o Coastfile mais próximo e, então, determina em qual worktree você está:\n\n1. Se seu cwd estiver sob `{project_root}/{worktree_dir}/{name}/...`, o lookup encontra instâncias atribuídas a esse worktree.\n2. Se seu cwd for a raiz do projeto (ou qualquer diretório que não esteja dentro de um worktree), o lookup encontra instâncias **sem worktree atribuída** — aquelas ainda apontadas para a raiz do projeto.\n\nIsso significa que o lookup funciona a partir de subdiretórios também. Se você estiver em `my-app/.worktrees/feature-oauth/src/api/`, o lookup ainda resolve `feature-oauth` como o worktree.\n\n## Códigos de Saída\n\n| Code | Meaning |\n|------|---------|\n| 0 | Uma ou mais instâncias correspondentes encontradas |\n| 1 | Nenhuma instância correspondente (resultado vazio) |\n\nIsso torna o lookup utilizável em condicionais do shell:\n\n```bash\nif coast lookup > /dev/null 2>&1; then\n coast exec dev-1 -- sh -c \"cd src && npm test\"\nfi\n```\n\n## Para Fluxos de Trabalho de Agentes\n\nO padrão típico de integração de agentes:\n\n1. O agente começa a trabalhar em um diretório de worktree.\n2. O agente executa `coast lookup` para descobrir nomes de instâncias, portas, URLs e comandos de exemplo.\n3. O agente usa o nome da instância para todos os comandos subsequentes do Coast: `coast exec`, `coast logs`, `coast ps`.\n\n```text\n┌─── Agent (host machine) ────────────────────────────┐\n│ │\n│ 1. coast lookup │\n│ → instance names, ports, URLs, examples │\n│ 2. coast exec dev-1 -- sh -c \"cd src && npm test\" │\n│ 3. coast logs dev-1 --service web --tail 50 │\n│ 4. coast ps dev-1 │\n│ │\n└──────────────────────────────────────────────────────┘\n```\n\nSe o agente estiver trabalhando em múltiplos worktrees, ele executa `coast lookup` a partir de cada diretório de worktree para resolver a instância correta para cada contexto.\n\nVeja também [Filesystem](FILESYSTEM.md) para saber como agentes do host interagem com o Coast, [Assign and Unassign](ASSIGN.md) para conceitos de worktree, e [Exec & Docker](EXEC_AND_DOCKER.md) para executar comandos dentro de um Coast.\n", @@ -2446,13 +2499,20 @@ "concepts_and_terminology/SHARED_SERVICES.md": "# Serviços Compartilhados\n\nServiços compartilhados são contêineres de banco de dados e infraestrutura (Postgres, Redis, MongoDB, etc.) que são executados no daemon Docker do seu host em vez de dentro de uma Coast. As instâncias Coast se conectam a eles por uma rede bridge, então toda Coast fala com o mesmo serviço no mesmo volume do host.\n\n![Shared services in Coastguard](../../assets/coastguard-shared-services.png)\n*A aba de serviços compartilhados do Coastguard mostrando Postgres, Redis e MongoDB gerenciados pelo host.*\n\n## Como Eles Funcionam\n\nQuando você declara um serviço compartilhado no seu Coastfile, o Coast o inicia no daemon do host e o remove da stack compose que é executada dentro de cada contêiner Coast. As Coasts então são configuradas para rotear o tráfego com nome de serviço de volta para o contêiner compartilhado, preservando a porta do lado do contêiner do serviço dentro da Coast.\n\n```text\nHost Docker daemon\n |\n +--> postgres (host volume: infra_postgres_data)\n +--> redis (host volume: infra_redis_data)\n +--> mongodb (host volume: infra_mongodb_data)\n |\n +--> Coast: dev-1 --bridge network--> host postgres, redis, mongodb\n +--> Coast: dev-2 --bridge network--> host postgres, redis, mongodb\n```\n\nComo os serviços compartilhados reutilizam seus volumes de host existentes, quaisquer dados que você já tenha de executar `docker-compose up` localmente ficam imediatamente disponíveis para suas Coasts.\n\nEssa distinção é importante quando você usa portas mapeadas:\n\n```toml\n[shared_services.postgis]\nimage = \"ghcr.io/baosystems/postgis:12-3.3\"\nports = [\"5433:5432\"]\n```\n\n- No host, o serviço compartilhado é publicado em `localhost:5433`.\n- Dentro de cada Coast, os contêineres da aplicação ainda se conectam a `postgis:5432`.\n- Um inteiro simples como `5432` é uma abreviação para o mapeamento de identidade `\"5432:5432\"`.\n\n## Quando Usar Serviços Compartilhados\n\n- Seu projeto tem integrações MCP que se conectam a um banco de dados local — serviços compartilhados permitem que elas continuem funcionando sem descoberta dinâmica de portas. Se você publicar o serviço compartilhado na mesma porta do host que suas ferramentas já usam (por exemplo `ports = [5432]`), essas ferramentas continuam funcionando sem alterações. Se você publicá-lo em uma porta diferente do host (por exemplo `\"5433:5432\"`), as ferramentas do lado do host devem usar essa porta do host enquanto as Coasts continuam usando a porta do contêiner.\n- Você quer instâncias Coast mais leves, já que elas não precisam executar seus próprios contêineres de banco de dados.\n- Você não precisa de isolamento de dados entre instâncias Coast (cada instância vê os mesmos dados).\n- Você está executando agentes de programação no host (veja [Filesystem](FILESYSTEM.md)) e quer que eles acessem o estado do banco de dados sem rotear por [`coast exec`](EXEC_AND_DOCKER.md). Com serviços compartilhados, as ferramentas de banco de dados e MCPs existentes do agente funcionam sem alterações.\n\nVeja a página [Topologia de Volumes](VOLUMES.md) para alternativas quando você precisar de isolamento.\n\n## Aviso de Desambiguação de Volumes\n\nOs nomes de volumes Docker nem sempre são globalmente únicos. Se você executar `docker-compose up` a partir de vários projetos diferentes, os volumes do host aos quais o Coast anexa serviços compartilhados podem não ser os que você espera.\n\nAntes de iniciar Coasts com serviços compartilhados, certifique-se de que o último `docker-compose up` que você executou foi do projeto que pretende usar com Coasts. Isso garante que os volumes do host correspondam ao que seu Coastfile espera.\n\n## Solução de Problemas\n\nSe seus serviços compartilhados parecerem estar apontando para o volume de host errado:\n\n1. Abra a interface [Coastguard](COASTGUARD.md) (`coast ui`).\n2. Navegue até a aba **Shared Services**.\n3. Selecione os serviços afetados e clique em **Remove**.\n4. Clique em **Refresh Shared Services** para recriá-los a partir da configuração atual do seu Coastfile.\n\nIsso desmonta e recria os contêineres de serviço compartilhado, reconectando-os aos volumes corretos do host.\n", "concepts_and_terminology/TROUBLESHOOTING.md": "# Solução de problemas\n\nA maioria dos problemas com o Coasts vem de estado desatualizado, recursos do Docker órfãos ou um daemon que saiu de sincronia. Esta página cobre o caminho de escalonamento do mais leve ao nuclear.\n\n## Doctor\n\nSe as coisas parecerem estranhas — instâncias aparecem como em execução, mas nada responde; portas parecem travadas; ou a UI mostra dados desatualizados — comece com `coast doctor`:\n\n```bash\ncoast doctor\n```\n\nO Doctor verifica o banco de dados de estado e o Docker em busca de inconsistências: registros de instâncias órfãos com contêineres ausentes, contêineres pendentes sem registro de estado e serviços compartilhados marcados como em execução que na verdade estão mortos. Ele corrige automaticamente o que encontrar.\n\nPara visualizar o que ele faria sem alterar nada:\n\n```bash\ncoast doctor --dry-run\n```\n\n## Reinício do daemon\n\nSe o próprio daemon parecer não responsivo ou você suspeitar que ele está em um estado ruim, reinicie-o:\n\n```bash\ncoast daemon restart\n```\n\nIsso envia um sinal de desligamento gracioso, espera o daemon encerrar e inicia um processo novo. Suas instâncias e seu estado são preservados.\n\n## Removendo um único projeto\n\nSe o problema estiver isolado a um projeto, você pode remover seus artefatos de build e os recursos do Docker associados sem afetar mais nada:\n\n```bash\ncoast rm-build my-project\n```\n\nIsso exclui o diretório de artefatos do projeto, imagens do Docker, volumes e contêineres. Ele pede confirmação primeiro. Passe `--force` para pular o prompt.\n\n## Imagens ausentes de serviços compartilhados\n\nSe `coast run` falhar ao criar um serviço compartilhado com um erro como `No such image: postgres:15`, a imagem está ausente do daemon do Docker no seu host.\n\nIsso acontece com mais frequência quando seu `Coastfile` define `shared_services`, como Postgres ou Redis, e o Docker ainda não fez pull dessas imagens.\n\nFaça pull da imagem ausente e, em seguida, execute a instância novamente:\n\n```bash\ndocker pull postgres:15\ndocker pull redis:7\ncoast run my-instance\n```\n\nSe você não tiver certeza de qual imagem está faltando, a saída do `coast run` que falhou incluirá o nome da imagem no erro do Docker. Após uma tentativa de provisionamento com falha, o Coasts limpa automaticamente a instância parcial, então é esperado ver a instância voltar para `stopped`.\n\n## Restauração de fábrica com Nuke\n\nQuando nada mais funciona — ou você só quer uma ficha completamente limpa — `coast nuke` executa uma restauração completa de fábrica:\n\n```bash\ncoast nuke\n```\n\nIsso irá:\n\n1. Parar o daemon `coastd`.\n2. Remover **todos** os contêineres do Docker gerenciados pelo coast.\n3. Remover **todos** os volumes do Docker gerenciados pelo coast.\n4. Remover **todas** as redes do Docker gerenciadas pelo coast.\n5. Remover **todas** as imagens do Docker do coast.\n6. Excluir todo o diretório `~/.coast/` (banco de dados de estado, builds, logs, segredos, cache de imagens).\n7. Recriar `~/.coast/` e reiniciar o daemon para que o coast fique imediatamente utilizável novamente.\n\nComo isso destrói tudo, você deve digitar `nuke` no prompt de confirmação:\n\n```text\n$ coast nuke\nWARNING: This will permanently destroy ALL coast data:\n\n - Stop the coastd daemon\n - Remove all coast-managed Docker containers\n - Remove all coast-managed Docker volumes\n - Remove all coast-managed Docker networks\n - Remove all coast Docker images\n - Delete ~/.coast/ (state DB, builds, logs, secrets, image cache)\n\nType \"nuke\" to confirm:\n```\n\nPasse `--force` para pular o prompt (útil em scripts):\n\n```bash\ncoast nuke --force\n```\n\nDepois de um nuke, o coast está pronto para uso — o daemon está em execução e o diretório home existe. Você só precisa executar `coast build` e `coast run` nos seus projetos novamente.\n\n## Relatando bugs\n\nSe você encontrar um problema que não seja resolvido por nenhum dos itens acima, inclua os logs do daemon ao relatar:\n\n```bash\ncoast daemon logs\n```\n", "concepts_and_terminology/VOLUMES.md": "# Topologia de Volumes\n\nO Coast oferece três estratégias de volumes que controlam como serviços com muitos dados (bancos de dados, caches, etc.) armazenam e compartilham seus dados entre instâncias do Coast. Escolher a estratégia certa depende de quanta isolação você precisa e de quanto overhead você consegue tolerar.\n\n## Serviços Compartilhados\n\n[Serviços compartilhados](SHARED_SERVICES.md) rodam no daemon Docker do seu host, fora de qualquer contêiner do Coast. Serviços como Postgres, MongoDB e Redis permanecem na máquina host e as instâncias do Coast roteiam suas chamadas de volta para o host por meio de uma rede bridge.\n\n```text\nHost machine\n |\n +--> Postgres (host daemon, existing volume)\n +--> Redis (host daemon, existing volume)\n |\n +--> Coast: dev-1 --connects to--> host Postgres, host Redis\n +--> Coast: dev-2 --connects to--> host Postgres, host Redis\n```\n\nNão há isolação de dados entre instâncias — todo Coast fala com o mesmo banco de dados. Em troca, você obtém:\n\n- Instâncias do Coast mais leves, já que não executam seus próprios contêineres de banco de dados.\n- Seus volumes existentes no host são reutilizados diretamente, então quaisquer dados que você já tenha ficam disponíveis imediatamente.\n- Integrações MCP que se conectam ao seu banco de dados local continuam a funcionar prontas para uso.\n\nIsso é configurado no seu [Coastfile](COASTFILE_TYPES.md) em `[shared_services]`.\n\n## Volumes Compartilhados\n\nVolumes compartilhados montam um único volume Docker que é compartilhado entre todas as instâncias do Coast. Os serviços em si (Postgres, Redis, etc.) rodam dentro de cada contêiner do Coast, mas todos leem e escrevem no mesmo volume subjacente.\n\n```text\nCoast: dev-1 --mounts--> shared volume \"my-project-postgres\"\nCoast: dev-2 --mounts--> shared volume \"my-project-postgres\"\n```\n\nIsso isola seus dados do Coast do que quer que esteja na sua máquina host, mas as instâncias ainda compartilham dados entre si. Isso é útil quando você quer uma separação limpa do seu ambiente de desenvolvimento no host sem o overhead de volumes por instância.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## Volumes Isolados\n\nVolumes isolados dão a cada instância do Coast seu próprio volume independente. Nenhum dado é compartilhado entre instâncias nem com o host. Cada instância começa vazia (ou a partir de um snapshot — veja abaixo) e diverge de forma independente.\n\n```text\nCoast: dev-1 --mounts--> volume \"dev-1-postgres\"\nCoast: dev-2 --mounts--> volume \"dev-2-postgres\"\n```\n\nEsta é a melhor escolha para projetos que dependem muito de testes de integração e precisam de verdadeira isolação de volume entre ambientes paralelos. A desvantagem é uma inicialização mais lenta e builds do Coast maiores, já que cada instância mantém sua própria cópia dos dados.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## Snapshotting\n\nTanto as estratégias compartilhada quanto isolada começam com volumes vazios por padrão. Se você quiser que as instâncias comecem com uma cópia de um volume existente do host, defina `snapshot_source` com o nome do volume Docker do qual copiar:\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\nO snapshot é tirado no [momento do build](BUILDS.md). Após a criação, o volume de cada instância diverge de forma independente — mutações não se propagam de volta para a origem nem para outras instâncias.\n\nO Coast ainda não oferece suporte a snapshotting em tempo de execução (por exemplo, tirar um snapshot de um volume a partir de uma instância em execução). Isso está planejado para uma versão futura.\n", - "harnesses/README.md": "# Harnesses\n\nCada harness cria git worktrees em um local diferente. No Coasts, o array\n[`worktree_dir`](../coastfiles/WORKTREE_DIR.md) informa onde ele deve procurar --\nincluindo caminhos externos como `~/.codex/worktrees` que exigem bind mounts\nadicionais.\n\nCada harness também tem suas próprias convenções para instruções no nível do projeto, skills e comandos. A matriz abaixo mostra o que cada harness oferece para que você saiba onde colocar orientações para o Coasts. Cada página cobre a configuração do Coastfile, o layout de arquivos recomendado e quaisquer ressalvas específicas desse harness.\n\nSe um repositório for usado por vários harnesses, consulte [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n\n| Harness | Worktree location | Project instructions | Skills | Commands | Page |\n|---------|-------------------|----------------------|--------|----------|------|\n| OpenAI Codex | `~/.codex/worktrees` | `AGENTS.md` | `.agents/skills/` | Skills aparecem como comandos `/` | [Codex](CODEX.md) |\n| Claude Code | `.claude/worktrees` | `CLAUDE.md` | `.claude/skills/` | `.claude/commands/` | [Claude Code](CLAUDE_CODE.md) |\n| Cursor | `~/.cursor/worktrees/` | `AGENTS.md` ou `.cursor/rules/` | `.cursor/skills/` ou `.agents/skills/` | `.cursor/commands/` | [Cursor](CURSOR.md) |\n| Conductor | `~/conductor/workspaces/` | `CLAUDE.md` | -- | -- | [Conductor](CONDUCTOR.md) |\n| T3 Code | `~/.t3/worktrees/` | `AGENTS.md` | `.agents/skills/` | -- | [T3 Code](T3_CODE.md) |\n\n## Skills vs Commands\n\nSkills e comandos permitem definir um fluxo de trabalho `/coasts` reutilizável. Você pode usar um ou ambos, dependendo do que o harness suporta.\n\nSe o seu harness suporta comandos e você quer um ponto de entrada `/coasts`\nexplícito, uma opção simples é adicionar um comando que reutilize a skill.\nComandos são invocados explicitamente pelo nome, então você sabe exatamente\nquando o fluxo de trabalho `/coasts` é executado. Skills também podem ser\ncarregadas automaticamente pelo agente com base no contexto, o que é útil, mas\nsignifica que você tem menos controle sobre quando as instruções são incluídas.\n\nVocê pode usar ambos. Se fizer isso, deixe o comando reutilizar a skill em vez\nde manter uma cópia separada do fluxo de trabalho.\n\nSe o harness suporta apenas skills (T3 Code), use uma skill. Se não suporta\nnenhum dos dois (Conductor), coloque o fluxo de trabalho `/coasts` diretamente\nno arquivo de instruções do projeto.\n", - "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) cria\nworktrees dentro do projeto em `.claude/worktrees/`. Como esse diretório\nfica dentro do repositório, o Coasts pode descobrir e atribuir worktrees do\nClaude Code sem qualquer bind mount externo.\n\nO Claude Code também é o harness aqui com a separação mais clara entre três\ncamadas para o Coasts:\n\n- `CLAUDE.md` para regras curtas, sempre ativas, para trabalhar com o Coasts\n- `.claude/skills/coasts/SKILL.md` para o fluxo reutilizável `/coasts`\n- `.claude/commands/coasts.md` somente quando você quiser um arquivo de comando como um ponto de entrada\n extra\n\n## Setup\n\nAdicione `.claude/worktrees` a `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\nComo `.claude/worktrees` é relativo ao projeto, nenhum bind mount externo é\nnecessário.\n\n## Onde a orientação do Coasts vai\n\n### `CLAUDE.md`\n\nColoque aqui as regras para o Coasts que devem se aplicar em toda tarefa. Mantenha isto curto e\noperacional:\n\n- execute `coast lookup` antes do primeiro comando de runtime em uma sessão\n- use `coast exec` para testes, builds e comandos de serviço\n- use `coast ps` e `coast logs` para feedback de runtime\n- pergunte antes de criar ou reatribuir um Coast quando não existir correspondência\n\n### `.claude/skills/coasts/SKILL.md`\n\nColoque aqui o fluxo reutilizável `/coasts`. Este é o lugar certo para um fluxo\nque:\n\n1. executa `coast lookup` e reutiliza o Coast correspondente\n2. recorre a `coast ls` quando não há correspondência\n3. oferece `coast run`, `coast assign`, `coast unassign`, `coast checkout` e\n `coast ui`\n4. usa diretamente a CLI do Coast como contrato em vez de encapsulá-la\n\nSe este repositório também usa Codex, T3 Code ou Cursor, veja\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) e mantenha a skill canônica em\n`.agents/skills/coasts/`, depois exponha-a ao Claude Code.\n\n### `.claude/commands/coasts.md`\n\nO Claude Code também oferece suporte a arquivos de comando do projeto. Para a documentação sobre Coasts, trate\nisto como opcional:\n\n- use isso somente quando você quiser especificamente um arquivo de comando\n- uma opção simples é fazer o comando reutilizar a mesma skill\n- se você der ao comando suas próprias instruções separadas, estará assumindo uma\n segunda cópia do fluxo para manter\n\n## Exemplo de estrutura\n\n### Apenas Claude Code\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\nSe este repositório também usa Codex, T3 Code ou Cursor, use o padrão compartilhado em\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) em vez de duplicá-lo aqui,\nporque orientações específicas de provedor duplicadas ficam mais difíceis de manter em sincronia a cada\nvez que você adiciona outro harness.\n\n## O que o Coasts faz\n\n- **Executar** — `coast run ` cria uma nova instância Coast a partir da build mais recente. Use `coast run -w ` para criar e atribuir uma worktree do Claude Code em uma etapa. Veja [Run](../concepts_and_terminology/RUN.md).\n- **Descoberta** — O Coasts lê `.claude/worktrees` como qualquer outro diretório local de\n worktree.\n- **Nomenclatura** — As worktrees do Claude Code seguem o mesmo comportamento de nomenclatura\n de worktree local que outras worktrees dentro do repositório na UI e na CLI do Coasts.\n- **Atribuir** — `coast assign` pode alternar `/workspace` para uma worktree do Claude Code\n sem qualquer indireção de bind-mount externo.\n- **Sincronização de itens ignorados pelo Git** — Funciona normalmente porque as worktrees vivem dentro da\n árvore do repositório.\n- **Detecção de órfãos** — Se o Claude Code remover uma worktree, o Coasts pode detectar\n o gitdir ausente e desatribui-la quando necessário.\n\n## Exemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — worktrees do Claude Code\n- `~/.codex/worktrees/` — worktrees do Codex se você também usar Codex neste repositório\n\n## Limitações\n\n- Se você duplicar o mesmo fluxo `/coasts` em `CLAUDE.md`,\n `.claude/skills` e `.claude/commands`, essas cópias entrarão em divergência. Mantenha\n `CLAUDE.md` curto e mantenha o fluxo reutilizável em uma única skill.\n- Se você quiser que um repositório funcione bem em múltiplos harnesses, prefira o padrão compartilhado\n em [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", - "harnesses/CODEX.md": "# Codex\n\n[Codex](https://developers.openai.com/codex/app/worktrees/) cria worktrees em `$CODEX_HOME/worktrees` (normalmente `~/.codex/worktrees`). Cada worktree fica sob um diretório de hash opaco como `~/.codex/worktrees/a0db/project-name`, começa em um HEAD destacado e é limpo automaticamente com base na política de retenção do Codex.\n\nDa [documentação do Codex](https://developers.openai.com/codex/app/worktrees/):\n\n> Posso controlar onde os worktrees são criados?\n> Ainda não. O Codex cria worktrees em `$CODEX_HOME/worktrees` para que possa gerenciá-los de forma consistente.\n\nComo esses worktrees ficam fora da raiz do projeto, o Coasts precisa de\nconfiguração explícita para descobri-los e montá-los.\n\n## Setup\n\nAdicione `~/.codex/worktrees` a `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nO Coasts expande `~` em tempo de execução e trata qualquer caminho que comece com `~/` ou `/` como\nexterno. Veja [Worktree Directories](../coastfiles/WORKTREE_DIR.md) para\ndetalhes.\n\nApós alterar `worktree_dir`, as instâncias existentes devem ser **recriadas** para que o bind mount entre em vigor:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nA listagem de worktrees é atualizada imediatamente (o Coasts lê o novo Coastfile), mas\natribuir a um worktree do Codex requer o bind mount dentro do contêiner.\n\n## Onde vai a orientação do Coasts\n\nUse o arquivo de instruções de projeto do Codex e o layout compartilhado de skill para trabalhar com\nCoasts:\n\n- coloque as regras curtas do Coast Runtime em `AGENTS.md`\n- coloque o fluxo de trabalho reutilizável `/coasts` em `.agents/skills/coasts/SKILL.md`\n- o Codex expõe essa skill como o comando `/coasts`\n- se você usar metadados específicos do Codex, mantenha-os ao lado da skill em\n `.agents/skills/coasts/agents/openai.yaml`\n- não crie um arquivo de comando de projeto separado apenas para documentação sobre Coasts; a\n skill é a superfície reutilizável\n- se este repositório também usar Cursor ou Claude Code, mantenha a skill canônica em\n `.agents/skills/` e exponha-a a partir daí. Veja\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) e\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\nPor exemplo, um `.agents/skills/coasts/agents/openai.yaml` mínimo poderia ser\nassim:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\nIsso mantém a skill visível no Codex com um rótulo melhor e torna `/coasts` um\ncomando explícito. Só adicione `dependencies.tools` se a skill também precisar de servidores MCP\nou outro encadeamento de ferramentas gerenciado pela OpenAI.\n\n## O que o Coasts faz\n\n- **Run** -- `coast run ` cria uma nova instância do Coast a partir do build mais recente. Use `coast run -w ` para criar e atribuir um worktree do Codex em uma única etapa. Veja [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** -- Na criação do contêiner, o Coasts monta\n `~/.codex/worktrees` no contêiner em `/host-external-wt/{index}`.\n- **Descoberta** -- `git worktree list --porcelain` tem escopo de repositório, então apenas os worktrees do Codex pertencentes ao projeto atual aparecem, mesmo que o diretório contenha worktrees de muitos projetos.\n- **Nomenclatura** -- Worktrees com HEAD destacado aparecem como seu caminho relativo dentro do diretório externo (`a0db/my-app`, `eca7/my-app`). Worktrees baseados em branch mostram o nome da branch.\n- **Atribuição** -- `coast assign` remonta `/workspace` a partir do caminho do bind mount externo.\n- **Sincronização de arquivos ignorados pelo Git** -- É executada no sistema de arquivos do host com caminhos absolutos, funciona sem o bind mount.\n- **Detecção de órfãos** -- O observador do git varre diretórios externos\n recursivamente, filtrando por ponteiros gitdir em `.git`. Se o Codex excluir um\n worktree, o Coasts remove automaticamente a atribuição da instância.\n\n## Exemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code (local, sem tratamento especial)\n- `~/.codex/worktrees/` -- Codex (externo, com bind mount)\n\n## Limitações\n\n- O Codex pode limpar worktrees a qualquer momento. A detecção de órfãos no Coasts\n lida com isso de forma elegante.\n", - "harnesses/CONDUCTOR.md": "# Conductor\n\n[Conductor](https://conductor.build/) executa agentes Claude Code em paralelo, cada um em seu próprio workspace isolado. Workspaces são git worktrees armazenados em `~/conductor/workspaces//`. Cada workspace é feito checkout em uma branch nomeada.\n\nComo esses worktrees ficam fora da raiz do projeto, o Coasts precisa de\nconfiguração explícita para descobri-los e montá-los.\n\n## Configuração\n\nAdicione `~/conductor/workspaces/` a `worktree_dir`. Diferentemente do Codex (que armazena todos os projetos em um único diretório plano), o Conductor aninha worktrees em um subdiretório por projeto, então o caminho deve incluir o nome do projeto. No exemplo abaixo, `my-app` deve corresponder ao nome real da pasta em `~/conductor/workspaces/` para o seu repositório.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nO Conductor permite configurar o caminho dos workspaces por repositório, então o padrão `~/conductor/workspaces` pode não corresponder à sua configuração. Verifique as configurações do repositório no Conductor para encontrar o caminho real e ajuste conforme necessário — o princípio é o mesmo independentemente de onde o diretório esteja.\n\nO Coasts expande `~` em tempo de execução e trata qualquer caminho que comece com `~/` ou `/` como\nexterno. Consulte [Worktree Directories](../coastfiles/WORKTREE_DIR.md) para\ndetalhes.\n\nApós alterar `worktree_dir`, instâncias existentes devem ser **recriadas** para que o bind mount entre em vigor:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nA listagem de worktrees é atualizada imediatamente (o Coasts lê o novo Coastfile), mas\natribuir a um worktree do Conductor requer o bind mount dentro do container.\n\n## Onde vai a orientação do Coasts\n\nTrate o Conductor como seu próprio harness para trabalhar com Coasts:\n\n- coloque as regras curtas do Coast Runtime em `CLAUDE.md`\n- use scripts de Configurações de Repositório do Conductor para comportamento de setup ou execução que seja\n realmente específico do Conductor\n- não presuma aqui o comportamento completo de comandos de projeto ou project skills do Claude Code\n- se você adicionar um comando e ele não aparecer, feche e reabra completamente o\n Conductor antes de testar novamente\n- se este repositório também usar outros harnesses, consulte\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) e\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md) para maneiras de manter o\n fluxo de trabalho compartilhado de `/coasts` em um só lugar\n\n## O que o Coasts faz\n\n- **Run** — `coast run ` cria uma nova instância do Coast a partir da build mais recente. Use `coast run -w ` para criar e atribuir um worktree do Conductor em uma única etapa. Veja [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — Na criação do container, o Coasts monta\n `~/conductor/workspaces/` dentro do container em\n `/host-external-wt/{index}`.\n- **Discovery** — `git worktree list --porcelain` tem escopo de repositório, então apenas worktrees pertencentes ao projeto atual aparecem.\n- **Naming** — Worktrees do Conductor usam branches nomeadas, então aparecem pelo nome da branch\n na UI e CLI do Coasts (por exemplo, `scroll-to-bottom-btn`). Uma branch só pode\n estar em checkout em um workspace do Conductor por vez.\n- **Assign** — `coast assign` remonta `/workspace` a partir do caminho do bind mount externo.\n- **Gitignored sync** — É executado no sistema de arquivos do host com caminhos absolutos e funciona sem o bind mount.\n- **Orphan detection** — O watcher do git varre diretórios externos\n recursivamente, filtrando por ponteiros `.git` gitdir. Se o Conductor arquivar ou\n excluir um workspace, o Coasts remove automaticamente a atribuição da instância.\n\n## Exemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor (externo, com bind mount; substitua `my-app` pelo nome da pasta do seu repositório)\n\n## Variáveis de Ambiente do Conductor\n\n- Evite depender de variáveis de ambiente específicas do Conductor (por exemplo,\n `CONDUCTOR_PORT`, `CONDUCTOR_WORKSPACE_PATH`) para configuração em tempo de execução\n dentro do Coasts. O Coasts gerencia portas, caminhos de workspace e descoberta de serviços\n de forma independente — use Coastfile `[ports]` e `coast exec` em vez disso.\n", - "harnesses/CURSOR.md": "# Cursor\n\n[Cursor](https://cursor.com/docs/agent/overview) pode trabalhar diretamente no seu\ncheckout atual, e seu recurso de Parallel Agents também pode criar git\nworktrees em `~/.cursor/worktrees//`.\n\nPara a documentação sobre Coasts, isso significa que há dois casos de configuração:\n\n- se você estiver apenas usando o Cursor no checkout atual, nenhuma entrada\n `worktree_dir` específica do Cursor é necessária\n- se você usar Cursor Parallel Agents, adicione o diretório de worktree do\n Cursor a `worktree_dir` para que o Coasts possa descobrir e atribuir esses worktrees\n\n## Configuração\n\n### Apenas checkout atual\n\nSe o Cursor estiver apenas editando o checkout que você já abriu, o Coasts não precisa\nde nenhum caminho de worktree específico do Cursor. O Coasts tratará esse checkout como\nqualquer outra raiz de repositório local.\n\n### Cursor Parallel Agents\n\nSe você usa Parallel Agents, adicione `~/.cursor/worktrees/` a\n`worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nO Cursor armazena cada worktree de agente sob esse diretório por projeto. O Coasts\nexpande `~` em tempo de execução e trata o caminho como externo, então instâncias\nexistentes devem ser recriadas para que o bind mount tenha efeito:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nA listagem de worktrees é atualizada imediatamente após a alteração no Coastfile, mas\natribuir a um worktree do Cursor Parallel Agent requer o bind mount externo\ndentro do contêiner.\n\n## Onde a orientação do Coasts deve ficar\n\n### `AGENTS.md` ou `.cursor/rules/coast.md`\n\nColoque aqui as regras curtas e sempre ativas do Coast Runtime:\n\n- use `AGENTS.md` se quiser as instruções de projeto mais portáveis\n- use `.cursor/rules/coast.md` se quiser regras de projeto nativas do Cursor e\n suporte à UI de configurações\n- não duplique o mesmo bloco do Coast Runtime em ambos, a menos que tenha um motivo\n claro\n\n### `.cursor/skills/coasts/SKILL.md` ou `.agents/skills/coasts/SKILL.md` compartilhado\n\nColoque aqui o fluxo de trabalho reutilizável de `/coasts`:\n\n- para um repositório somente Cursor, `.cursor/skills/coasts/SKILL.md` é um local natural\n- para um repositório com múltiplos harnesses, mantenha a skill canônica em\n `.agents/skills/coasts/SKILL.md`; o Cursor pode carregá-la diretamente\n- a skill deve ser dona do fluxo de trabalho real de `/coasts`: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout` e `coast ui`\n\n### `.cursor/commands/coasts.md`\n\nO Cursor também oferece suporte a comandos de projeto. Para a documentação sobre Coasts,\ntrate os comandos como opcionais:\n\n- adicione um comando apenas quando quiser um ponto de entrada explícito para `/coasts`\n- uma opção simples é fazer o comando reutilizar a mesma skill\n- se você der ao comando suas próprias instruções separadas, estará assumindo a manutenção\n de uma segunda cópia do fluxo de trabalho\n\n### `.cursor/worktrees.json`\n\nUse `.cursor/worktrees.json` para o bootstrap de worktree do próprio Cursor, não para\na política do Coasts:\n\n- instalar dependências\n- copiar ou criar symlinks de arquivos `.env`\n- executar migrações de banco de dados ou outras etapas de bootstrap únicas\n\nNão mova as regras do Coast Runtime nem o fluxo de trabalho da Coast CLI para\n`.cursor/worktrees.json`.\n\n## Exemplo de layout\n\n### Somente Cursor\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # opcional\n.cursor/rules/coast.md # alternativa opcional ao AGENTS.md\n.cursor/worktrees.json # opcional, para bootstrap de Parallel Agents\n```\n\n### Cursor mais outros harnesses\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # opcional\n```\n\n## O que o Coasts faz\n\n- **Executar** — `coast run ` cria uma nova instância do Coast a partir da build mais recente. Use `coast run -w ` para criar e atribuir um worktree do Cursor em uma única etapa. Veja [Run](../concepts_and_terminology/RUN.md).\n- **Checkout atual** — Nenhum tratamento especial do Cursor é necessário quando o Cursor está\n trabalhando diretamente no repositório que você abriu.\n- **Bind mount** — Para Parallel Agents, o Coasts monta\n `~/.cursor/worktrees/` no contêiner em\n `/host-external-wt/{index}`.\n- **Descoberta** — `git worktree list --porcelain` continua com escopo de repositório, então o Coasts\n mostra apenas worktrees do Cursor que pertencem ao projeto atual.\n- **Nomenclatura** — Os worktrees do Cursor Parallel Agent aparecem por seus nomes de branch no\n CLI e na UI do Coasts.\n- **Atribuir** — `coast assign` remonta `/workspace` a partir do caminho de bind mount\n externo quando um worktree do Cursor é selecionado.\n- **Sincronização de arquivos ignorados pelo Git** — Continua funcionando no sistema de arquivos do host com caminhos\n absolutos.\n- **Detecção de órfãos** — Se o Cursor limpar worktrees antigos, o Coasts pode detectar\n o gitdir ausente e desatribuí-los quando necessário.\n\n## Exemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — worktrees do Claude Code\n- `~/.codex/worktrees/` — worktrees do Codex\n- `~/.cursor/worktrees/my-app/` — worktrees do Cursor Parallel Agent\n\n## Limitações\n\n- Se você não estiver usando Cursor Parallel Agents, não adicione\n `~/.cursor/worktrees/` só porque por acaso está editando no\n Cursor.\n- Mantenha as regras do Coast Runtime em um único lugar sempre ativo: `AGENTS.md` ou\n `.cursor/rules/coast.md`. Duplicar ambos convida à divergência.\n- Mantenha o fluxo de trabalho reutilizável de `/coasts` em uma skill. `.cursor/worktrees.json` é\n para bootstrap do Cursor, não política do Coasts.\n- Se um repositório for compartilhado entre Cursor, Codex, Claude Code ou T3 Code, prefira\n o layout compartilhado em [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", + "harnesses/README.md": "# Harnesses\n\nCada harness cria git worktrees em um local diferente. No Coasts, o array\n[`worktree_dir`](../coastfiles/WORKTREE_DIR.md) informa onde ele deve procurar --\nincluindo caminhos externos como `~/.codex/worktrees` que exigem bind mounts\nadicionais.\n\nCada harness também tem suas próprias convenções para instruções no nível do projeto, skills e comandos. A matriz abaixo mostra o que cada harness oferece para que você saiba onde colocar orientações para o Coasts. Cada página cobre a configuração do Coastfile, o layout de arquivos recomendado e quaisquer ressalvas específicas desse harness.\n\nSe um repositório for usado por vários harnesses, consulte [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n\n| Harness | Worktree location | Project instructions | Skills | Commands | Page |\n|---------|-------------------|----------------------|--------|----------|------|\n| OpenAI Codex | `~/.codex/worktrees` | `AGENTS.md` | `.agents/skills/` | Skills aparecem como comandos `/` | [Codex](CODEX.md) |\n| Claude Code | `.claude/worktrees` | `CLAUDE.md` | `.claude/skills/` | `.claude/commands/` | [Claude Code](CLAUDE_CODE.md) |\n| Cursor | `~/.cursor/worktrees/` | `AGENTS.md` ou `.cursor/rules/` | `.cursor/skills/` ou `.agents/skills/` | `.cursor/commands/` | [Cursor](CURSOR.md) |\n| Conductor | `~/conductor/workspaces/` | `CLAUDE.md` | -- | -- | [Conductor](CONDUCTOR.md) |\n| T3 Code | `~/.t3/worktrees/` | `AGENTS.md` | `.agents/skills/` | -- | [T3 Code](T3_CODE.md) |\n| Shep | `~/.shep/repos/*/wt` | `CLAUDE.md` | `.agents/skills/` ou `.claude/skills/` | -- | [Shep](SHEP.md) |\n\n## Skills vs Commands\n\nSkills e comandos permitem definir um fluxo de trabalho `/coasts` reutilizável. Você pode usar um ou ambos, dependendo do que o harness suporta.\n\nSe o seu harness suporta comandos e você quer um ponto de entrada `/coasts`\nexplícito, uma opção simples é adicionar um comando que reutilize a skill.\nComandos são invocados explicitamente pelo nome, então você sabe exatamente\nquando o fluxo de trabalho `/coasts` é executado. Skills também podem ser\ncarregadas automaticamente pelo agente com base no contexto, o que é útil, mas\nsignifica que você tem menos controle sobre quando as instruções são incluídas.\n\nVocê pode usar ambos. Se fizer isso, deixe o comando reutilizar a skill em vez\nde manter uma cópia separada do fluxo de trabalho.\n\nSe o harness suporta apenas skills (T3 Code), use uma skill. Se não suporta\nnenhum dos dois (Conductor), coloque o fluxo de trabalho `/coasts` diretamente\nno arquivo de instruções do projeto.\n", + "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n## Configuração rápida\n\nRequer a [Coast CLI](../GETTING_STARTED.md). Copie este prompt para o chat do seu\nagente para configurar o Coasts automaticamente:\n\n```prompt-copy\nclaude_code_setup_prompt.txt\n```\n\nVocê também pode obter o conteúdo da skill pela CLI: `coast skills-prompt`.\n\nApós a configuração, **inicie uma nova sessão do Claude Code** — as skills e as alterações em `CLAUDE.md`\nsão carregadas no início da sessão.\n\n---\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) cria\nworktrees dentro do projeto em `.claude/worktrees/`. Como esse diretório\nfica dentro do repositório, o Coasts pode descobrir e atribuir worktrees do\nClaude Code sem qualquer bind mount externo.\n\nO Claude Code também é o harness aqui com a separação mais clara entre três\ncamadas para o Coasts:\n\n- `CLAUDE.md` para regras curtas, sempre ativas, para trabalhar com o Coasts\n- `.claude/skills/coasts/SKILL.md` para o fluxo reutilizável `/coasts`\n- `.claude/commands/coasts.md` somente quando você quiser um arquivo de comando como um ponto de entrada\n extra\n\n## Setup\n\nAdicione `.claude/worktrees` a `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\nComo `.claude/worktrees` é relativo ao projeto, nenhum bind mount externo é\nnecessário.\n\n## Onde a orientação do Coasts vai\n\n### `CLAUDE.md`\n\nColoque aqui as regras para o Coasts que devem se aplicar em toda tarefa. Mantenha isto curto e\noperacional:\n\n- execute `coast lookup` antes do primeiro comando de runtime em uma sessão\n- use `coast exec` para testes, builds e comandos de serviço\n- use `coast ps` e `coast logs` para feedback de runtime\n- pergunte antes de criar ou reatribuir um Coast quando não existir correspondência\n\n### `.claude/skills/coasts/SKILL.md`\n\nColoque aqui o fluxo reutilizável `/coasts`. Este é o lugar certo para um fluxo\nque:\n\n1. executa `coast lookup` e reutiliza o Coast correspondente\n2. recorre a `coast ls` quando não há correspondência\n3. oferece `coast run`, `coast assign`, `coast unassign`, `coast checkout` e\n `coast ui`\n4. usa diretamente a CLI do Coast como contrato em vez de encapsulá-la\n\nSe este repositório também usa Codex, T3 Code ou Cursor, veja\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) e mantenha a skill canônica em\n`.agents/skills/coasts/`, depois exponha-a ao Claude Code.\n\n### `.claude/commands/coasts.md`\n\nO Claude Code também oferece suporte a arquivos de comando do projeto. Para a documentação sobre Coasts, trate\nisto como opcional:\n\n- use isso somente quando você quiser especificamente um arquivo de comando\n- uma opção simples é fazer o comando reutilizar a mesma skill\n- se você der ao comando suas próprias instruções separadas, estará assumindo uma\n segunda cópia do fluxo para manter\n\n## Exemplo de estrutura\n\n### Apenas Claude Code\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\nSe este repositório também usa Codex, T3 Code ou Cursor, use o padrão compartilhado em\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) em vez de duplicá-lo aqui,\nporque orientações específicas de provedor duplicadas ficam mais difíceis de manter em sincronia a cada\nvez que você adiciona outro harness.\n\n## O que o Coasts faz\n\n- **Executar** — `coast run ` cria uma nova instância Coast a partir da build mais recente. Use `coast run -w ` para criar e atribuir uma worktree do Claude Code em uma etapa. Veja [Run](../concepts_and_terminology/RUN.md).\n- **Descoberta** — O Coasts lê `.claude/worktrees` como qualquer outro diretório local de\n worktree.\n- **Nomenclatura** — As worktrees do Claude Code seguem o mesmo comportamento de nomenclatura\n de worktree local que outras worktrees dentro do repositório na UI e na CLI do Coasts.\n- **Atribuir** — `coast assign` pode alternar `/workspace` para uma worktree do Claude Code\n sem qualquer indireção de bind-mount externo.\n- **Sincronização de itens ignorados pelo Git** — Funciona normalmente porque as worktrees vivem dentro da\n árvore do repositório.\n- **Detecção de órfãos** — Se o Claude Code remover uma worktree, o Coasts pode detectar\n o gitdir ausente e desatribui-la quando necessário.\n\n## Exemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — worktrees do Claude Code\n- `~/.codex/worktrees/` — worktrees do Codex se você também usar Codex neste repositório\n\n## Limitações\n\n- Se você duplicar o mesmo fluxo `/coasts` em `CLAUDE.md`,\n `.claude/skills` e `.claude/commands`, essas cópias entrarão em divergência. Mantenha\n `CLAUDE.md` curto e mantenha o fluxo reutilizável em uma única skill.\n- Se você quiser que um repositório funcione bem em múltiplos harnesses, prefira o padrão compartilhado\n em [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", + "harnesses/CODEX.md": "# Codex\n\n## Quick setup\n\nRequer a [Coast CLI](../GETTING_STARTED.md). Copie este prompt para o chat do seu\nagente para configurar o Coasts automaticamente:\n\n```prompt-copy\ncodex_setup_prompt.txt\n```\n\nVocê também pode obter o conteúdo da skill pela CLI: `coast skills-prompt`.\n\nApós a configuração, **feche e reabra o Codex** para que a nova skill e `AGENTS.md` passem a\nfazer efeito.\n\n---\n\n[Codex](https://developers.openai.com/codex/app/worktrees/) cria worktrees em `$CODEX_HOME/worktrees` (normalmente `~/.codex/worktrees`). Cada worktree fica sob um diretório de hash opaco como `~/.codex/worktrees/a0db/project-name`, começa em um HEAD destacado e é limpo automaticamente com base na política de retenção do Codex.\n\nDa [documentação do Codex](https://developers.openai.com/codex/app/worktrees/):\n\n> Posso controlar onde os worktrees são criados?\n> Ainda não. O Codex cria worktrees em `$CODEX_HOME/worktrees` para que possa gerenciá-los de forma consistente.\n\nComo esses worktrees ficam fora da raiz do projeto, o Coasts precisa de\nconfiguração explícita para descobri-los e montá-los.\n\n## Setup\n\nAdicione `~/.codex/worktrees` a `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nO Coasts expande `~` em tempo de execução e trata qualquer caminho que comece com `~/` ou `/` como\nexterno. Veja [Worktree Directories](../coastfiles/WORKTREE_DIR.md) para\ndetalhes.\n\nApós alterar `worktree_dir`, as instâncias existentes devem ser **recriadas** para que o bind mount entre em vigor:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nA listagem de worktrees é atualizada imediatamente (o Coasts lê o novo Coastfile), mas\natribuir a um worktree do Codex requer o bind mount dentro do contêiner.\n\n## Onde vai a orientação do Coasts\n\nUse o arquivo de instruções de projeto do Codex e o layout compartilhado de skill para trabalhar com\nCoasts:\n\n- coloque as regras curtas do Coast Runtime em `AGENTS.md`\n- coloque o fluxo de trabalho reutilizável `/coasts` em `.agents/skills/coasts/SKILL.md`\n- o Codex expõe essa skill como o comando `/coasts`\n- se você usar metadados específicos do Codex, mantenha-os ao lado da skill em\n `.agents/skills/coasts/agents/openai.yaml`\n- não crie um arquivo de comando de projeto separado apenas para documentação sobre Coasts; a\n skill é a superfície reutilizável\n- se este repositório também usar Cursor ou Claude Code, mantenha a skill canônica em\n `.agents/skills/` e exponha-a a partir daí. Veja\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) e\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\nPor exemplo, um `.agents/skills/coasts/agents/openai.yaml` mínimo poderia ser\nassim:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\nIsso mantém a skill visível no Codex com um rótulo melhor e torna `/coasts` um\ncomando explícito. Só adicione `dependencies.tools` se a skill também precisar de servidores MCP\nou outro encadeamento de ferramentas gerenciado pela OpenAI.\n\n## O que o Coasts faz\n\n- **Run** -- `coast run ` cria uma nova instância do Coast a partir do build mais recente. Use `coast run -w ` para criar e atribuir um worktree do Codex em uma única etapa. Veja [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** -- Na criação do contêiner, o Coasts monta\n `~/.codex/worktrees` no contêiner em `/host-external-wt/{index}`.\n- **Descoberta** -- `git worktree list --porcelain` tem escopo de repositório, então apenas os worktrees do Codex pertencentes ao projeto atual aparecem, mesmo que o diretório contenha worktrees de muitos projetos.\n- **Nomenclatura** -- Worktrees com HEAD destacado aparecem como seu caminho relativo dentro do diretório externo (`a0db/my-app`, `eca7/my-app`). Worktrees baseados em branch mostram o nome da branch.\n- **Atribuição** -- `coast assign` remonta `/workspace` a partir do caminho do bind mount externo.\n- **Sincronização de arquivos ignorados pelo Git** -- É executada no sistema de arquivos do host com caminhos absolutos, funciona sem o bind mount.\n- **Detecção de órfãos** -- O observador do git varre diretórios externos\n recursivamente, filtrando por ponteiros gitdir em `.git`. Se o Codex excluir um\n worktree, o Coasts remove automaticamente a atribuição da instância.\n\n## Exemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code (local, sem tratamento especial)\n- `~/.codex/worktrees/` -- Codex (externo, com bind mount)\n\n## Limitações\n\n- O Codex pode limpar worktrees a qualquer momento. A detecção de órfãos no Coasts\n lida com isso de forma elegante.\n", + "harnesses/CONDUCTOR.md": "# Conductor\n\n## Configuração rápida\n\nRequer a [Coast CLI](../GETTING_STARTED.md). Copie este prompt para o chat do seu\nagente para configurar o Coasts automaticamente:\n\n```prompt-copy\nconductor_setup_prompt.txt\n```\n\nVocê também pode obter o conteúdo da skill pela CLI: `coast skills-prompt`.\n\n> **Importante:** O Conductor executa cada sessão em um git worktree isolado. O\n> prompt de configuração cria arquivos que só existem no workspace atual —\n> faça commit deles e mescle-os na sua branch principal ou eles não estarão\n> disponíveis em novas sessões.\n\nApós a configuração, **feche e reabra completamente o Conductor** para que as alterações entrem em vigor. Se\no comando `/coasts` não aparecer, feche e reabra novamente.\n\n## Configuração\n\nAdicione `~/conductor/workspaces/` a `worktree_dir`. Diferentemente do Codex (que armazena todos os projetos em um único diretório plano), o Conductor aninha worktrees em um subdiretório por projeto, então o caminho deve incluir o nome do projeto. No exemplo abaixo, `my-app` deve corresponder ao nome real da pasta em `~/conductor/workspaces/` para o seu repositório.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nO Conductor permite configurar o caminho dos workspaces por repositório, então o padrão `~/conductor/workspaces` pode não corresponder à sua configuração. Verifique as configurações do repositório no Conductor para encontrar o caminho real e ajuste conforme necessário — o princípio é o mesmo independentemente de onde o diretório esteja.\n\nO Coasts expande `~` em tempo de execução e trata qualquer caminho que comece com `~/` ou `/` como\nexterno. Consulte [Worktree Directories](../coastfiles/WORKTREE_DIR.md) para\ndetalhes.\n\nApós alterar `worktree_dir`, instâncias existentes devem ser **recriadas** para que o bind mount entre em vigor:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nA listagem de worktrees é atualizada imediatamente (o Coasts lê o novo Coastfile), mas\natribuir a um worktree do Conductor requer o bind mount dentro do container.\n\n## Onde vai a orientação do Coasts\n\nTrate o Conductor como seu próprio harness para trabalhar com Coasts:\n\n- coloque as regras curtas do Coast Runtime em `CLAUDE.md`\n- use scripts de Configurações de Repositório do Conductor para comportamento de setup ou execução que seja\n realmente específico do Conductor\n- não presuma aqui o comportamento completo de comandos de projeto ou project skills do Claude Code\n- se você adicionar um comando e ele não aparecer, feche e reabra completamente o\n Conductor antes de testar novamente\n- se este repositório também usar outros harnesses, consulte\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) e\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md) para maneiras de manter o\n fluxo de trabalho compartilhado de `/coasts` em um só lugar\n\n## O que o Coasts faz\n\n- **Run** — `coast run ` cria uma nova instância do Coast a partir da build mais recente. Use `coast run -w ` para criar e atribuir um worktree do Conductor em uma única etapa. Veja [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — Na criação do container, o Coasts monta\n `~/conductor/workspaces/` dentro do container em\n `/host-external-wt/{index}`.\n- **Discovery** — `git worktree list --porcelain` tem escopo de repositório, então apenas worktrees pertencentes ao projeto atual aparecem.\n- **Naming** — Worktrees do Conductor usam branches nomeadas, então aparecem pelo nome da branch\n na UI e CLI do Coasts (por exemplo, `scroll-to-bottom-btn`). Uma branch só pode\n estar em checkout em um workspace do Conductor por vez.\n- **Assign** — `coast assign` remonta `/workspace` a partir do caminho do bind mount externo.\n- **Gitignored sync** — É executado no sistema de arquivos do host com caminhos absolutos e funciona sem o bind mount.\n- **Orphan detection** — O watcher do git varre diretórios externos\n recursivamente, filtrando por ponteiros `.git` gitdir. Se o Conductor arquivar ou\n excluir um workspace, o Coasts remove automaticamente a atribuição da instância.\n\n## Exemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor (externo, com bind mount; substitua `my-app` pelo nome da pasta do seu repositório)\n\n## Variáveis de Ambiente do Conductor\n\n- Evite depender de variáveis de ambiente específicas do Conductor (por exemplo,\n `CONDUCTOR_PORT`, `CONDUCTOR_WORKSPACE_PATH`) para configuração em tempo de execução\n dentro do Coasts. O Coasts gerencia portas, caminhos de workspace e descoberta de serviços\n de forma independente — use Coastfile `[ports]` e `coast exec` em vez disso.\n", + "harnesses/CURSOR.md": "# Cursor\n\n## Configuração rápida\n\nRequer a [Coast CLI](../GETTING_STARTED.md). Copie este prompt para o chat do seu\nagente para configurar o Coasts automaticamente:\n\n```prompt-copy\ncursor_setup_prompt.txt\n```\n\nVocê também pode obter o conteúdo da skill pela CLI: `coast skills-prompt`.\n\nApós a configuração, **reinicie o Cursor** para que as alterações na skill e nas regras entrem em vigor.\n\n---\n\n[Cursor](https://cursor.com/docs/agent/overview) pode trabalhar diretamente no seu\ncheckout atual, e seu recurso de Parallel Agents também pode criar git\nworktrees em `~/.cursor/worktrees//`.\n\nPara a documentação sobre Coasts, isso significa que há dois casos de configuração:\n\n- se você estiver apenas usando o Cursor no checkout atual, nenhuma entrada\n `worktree_dir` específica do Cursor é necessária\n- se você usar Cursor Parallel Agents, adicione o diretório de worktree do\n Cursor a `worktree_dir` para que o Coasts possa descobrir e atribuir esses worktrees\n\n## Configuração\n\n### Apenas checkout atual\n\nSe o Cursor estiver apenas editando o checkout que você já abriu, o Coasts não precisa\nde nenhum caminho de worktree específico do Cursor. O Coasts tratará esse checkout como\nqualquer outra raiz de repositório local.\n\n### Cursor Parallel Agents\n\nSe você usa Parallel Agents, adicione `~/.cursor/worktrees/` a\n`worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nO Cursor armazena cada worktree de agente sob esse diretório por projeto. O Coasts\nexpande `~` em tempo de execução e trata o caminho como externo, então instâncias\nexistentes devem ser recriadas para que o bind mount tenha efeito:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nA listagem de worktrees é atualizada imediatamente após a alteração no Coastfile, mas\natribuir a um worktree do Cursor Parallel Agent requer o bind mount externo\ndentro do contêiner.\n\n## Onde a orientação do Coasts deve ficar\n\n### `AGENTS.md` ou `.cursor/rules/coast.md`\n\nColoque aqui as regras curtas e sempre ativas do Coast Runtime:\n\n- use `AGENTS.md` se quiser as instruções de projeto mais portáveis\n- use `.cursor/rules/coast.md` se quiser regras de projeto nativas do Cursor e\n suporte à UI de configurações\n- não duplique o mesmo bloco do Coast Runtime em ambos, a menos que tenha um motivo\n claro\n\n### `.cursor/skills/coasts/SKILL.md` ou `.agents/skills/coasts/SKILL.md` compartilhado\n\nColoque aqui o fluxo de trabalho reutilizável de `/coasts`:\n\n- para um repositório somente Cursor, `.cursor/skills/coasts/SKILL.md` é um local natural\n- para um repositório com múltiplos harnesses, mantenha a skill canônica em\n `.agents/skills/coasts/SKILL.md`; o Cursor pode carregá-la diretamente\n- a skill deve ser dona do fluxo de trabalho real de `/coasts`: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout` e `coast ui`\n\n### `.cursor/commands/coasts.md`\n\nO Cursor também oferece suporte a comandos de projeto. Para a documentação sobre Coasts,\ntrate os comandos como opcionais:\n\n- adicione um comando apenas quando quiser um ponto de entrada explícito para `/coasts`\n- uma opção simples é fazer o comando reutilizar a mesma skill\n- se você der ao comando suas próprias instruções separadas, estará assumindo a manutenção\n de uma segunda cópia do fluxo de trabalho\n\n### `.cursor/worktrees.json`\n\nUse `.cursor/worktrees.json` para o bootstrap de worktree do próprio Cursor, não para\na política do Coasts:\n\n- instalar dependências\n- copiar ou criar symlinks de arquivos `.env`\n- executar migrações de banco de dados ou outras etapas de bootstrap únicas\n\nNão mova as regras do Coast Runtime nem o fluxo de trabalho da Coast CLI para\n`.cursor/worktrees.json`.\n\n## Exemplo de layout\n\n### Somente Cursor\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # opcional\n.cursor/rules/coast.md # alternativa opcional ao AGENTS.md\n.cursor/worktrees.json # opcional, para bootstrap de Parallel Agents\n```\n\n### Cursor mais outros harnesses\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # opcional\n```\n\n## O que o Coasts faz\n\n- **Executar** — `coast run ` cria uma nova instância do Coast a partir da build mais recente. Use `coast run -w ` para criar e atribuir um worktree do Cursor em uma única etapa. Veja [Run](../concepts_and_terminology/RUN.md).\n- **Checkout atual** — Nenhum tratamento especial do Cursor é necessário quando o Cursor está\n trabalhando diretamente no repositório que você abriu.\n- **Bind mount** — Para Parallel Agents, o Coasts monta\n `~/.cursor/worktrees/` no contêiner em\n `/host-external-wt/{index}`.\n- **Descoberta** — `git worktree list --porcelain` continua com escopo de repositório, então o Coasts\n mostra apenas worktrees do Cursor que pertencem ao projeto atual.\n- **Nomenclatura** — Os worktrees do Cursor Parallel Agent aparecem por seus nomes de branch no\n CLI e na UI do Coasts.\n- **Atribuir** — `coast assign` remonta `/workspace` a partir do caminho de bind mount\n externo quando um worktree do Cursor é selecionado.\n- **Sincronização de arquivos ignorados pelo Git** — Continua funcionando no sistema de arquivos do host com caminhos\n absolutos.\n- **Detecção de órfãos** — Se o Cursor limpar worktrees antigos, o Coasts pode detectar\n o gitdir ausente e desatribuí-los quando necessário.\n\n## Exemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — worktrees do Claude Code\n- `~/.codex/worktrees/` — worktrees do Codex\n- `~/.cursor/worktrees/my-app/` — worktrees do Cursor Parallel Agent\n\n## Limitações\n\n- Se você não estiver usando Cursor Parallel Agents, não adicione\n `~/.cursor/worktrees/` só porque por acaso está editando no\n Cursor.\n- Mantenha as regras do Coast Runtime em um único lugar sempre ativo: `AGENTS.md` ou\n `.cursor/rules/coast.md`. Duplicar ambos convida à divergência.\n- Mantenha o fluxo de trabalho reutilizável de `/coasts` em uma skill. `.cursor/worktrees.json` é\n para bootstrap do Cursor, não política do Coasts.\n- Se um repositório for compartilhado entre Cursor, Codex, Claude Code ou T3 Code, prefira\n o layout compartilhado em [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", "harnesses/MULTIPLE_HARNESSES.md": "# Múltiplos Harnesses\n\nSe um repositório é usado por mais de um harness, uma forma de consolidar\na configuração do Coasts é manter o workflow compartilhado de `/coasts` em um lugar e manter\nas regras always-on específicas do harness nos arquivos de cada harness.\n\n## Layout recomendado\n\n```text\nAGENTS.md\nCLAUDE.md\n.cursor/rules/coast.md # optional Cursor-native always-on rules\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional, thin, harness-specific\n.claude/commands/coasts.md # optional, thin, harness-specific\n```\n\nUse este layout assim:\n\n- `AGENTS.md` — regras curtas, always-on, para trabalhar com Coasts no Codex e no T3\n Code\n- `.cursor/rules/coast.md` — regras opcionais, always-on nativas do Cursor\n- `CLAUDE.md` — regras curtas, always-on, para trabalhar com Coasts no Claude Code\n e no Conductor\n- `.agents/skills/coasts/SKILL.md` — workflow `/coasts` reutilizável canônico\n- `.agents/skills/coasts/agents/openai.yaml` — metadados opcionais do Codex/OpenAI\n- `.claude/skills/coasts` — espelho ou symlink voltado para o Claude quando o Claude Code\n também precisar da mesma skill\n- `.cursor/commands/coasts.md` — arquivo de comando opcional do Cursor; uma opção\n simples é fazer com que ele reutilize a mesma skill\n- `.claude/commands/coasts.md` — arquivo de comando explícito opcional; uma opção\n simples é fazer com que ele reutilize a mesma skill\n\n## Passo a passo\n\n1. Coloque as regras do Coast Runtime nos arquivos de instruções always-on.\n - `AGENTS.md`, `CLAUDE.md` ou `.cursor/rules/coast.md` devem responder às\n regras de \"every task\": executar `coast lookup` primeiro, usar `coast exec`, ler logs\n com `coast logs`, pedir antes de `coast assign` ou `coast run` quando não houver\n correspondência.\n2. Crie uma skill canônica para Coasts.\n - Coloque o workflow `/coasts` reutilizável em `.agents/skills/coasts/SKILL.md`.\n - Use a CLI do Coast diretamente dentro dessa skill: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout` e `coast ui`.\n3. Exponha essa skill apenas onde um harness precisar de um caminho diferente.\n - Codex, T3 Code e Cursor podem usar `.agents/skills/` diretamente.\n - Claude Code precisa de `.claude/skills/`, então espelhe ou crie um symlink da\n skill canônica para esse local.\n4. Adicione um arquivo de comando apenas se você quiser um ponto de entrada `/coasts` explícito.\n - Se você criar `.claude/commands/coasts.md` ou\n `.cursor/commands/coasts.md`, uma opção simples é fazer com que o comando\n reutilize a mesma skill.\n - Se você der ao comando suas próprias instruções separadas, estará assumindo uma\n segunda cópia do workflow para manter.\n5. Mantenha a configuração específica do Conductor no Conductor, não na skill.\n - Use scripts de Repository Settings do Conductor para comportamento de bootstrap ou execução\n que pertença ao próprio Conductor.\n - Mantenha a política de Coasts e o uso da CLI `coast` em `CLAUDE.md` e na\n skill compartilhada.\n\n## Exemplo concreto de `/coasts`\n\nUma boa skill compartilhada de `coasts` deve fazer três trabalhos:\n\n1. `Use Existing Coast`\n - execute `coast lookup`\n - se existir uma correspondência, use `coast exec`, `coast ps` e `coast logs`\n2. `Manage Assignment`\n - execute `coast ls`\n - ofereça `coast run`, `coast assign`, `coast unassign` ou\n `coast checkout`\n - pergunte antes de reutilizar ou interromper um slot existente\n3. `Open UI`\n - execute `coast ui`\n\nEsse é o lugar certo para o workflow `/coasts`. Os arquivos always-on devem\nconter apenas as regras curtas que precisam se aplicar mesmo quando a skill nunca é invocada.\n\n## Padrão de symlink\n\nSe você quiser que o Claude Code reutilize a mesma skill que Codex, T3 Code ou Cursor,\numa opção é um symlink:\n\n```bash\nmkdir -p .claude/skills\nln -s ../../.agents/skills/coasts .claude/skills/coasts\n```\n\nUm espelho versionado também é válido se sua equipe preferir não usar symlinks. O\nobjetivo principal é apenas evitar divergência desnecessária entre cópias.\n\n## Cuidados específicos por harness\n\n- Claude Code: skills de projeto e comandos de projeto opcionais são ambos válidos, mas\n mantenha a lógica na skill.\n- Cursor: use `AGENTS.md` ou `.cursor/rules/coast.md` para as regras curtas do Coast\n Runtime, use uma skill para o workflow reutilizável e mantenha\n `.cursor/commands` opcional.\n- Conductor: trate-o primeiro como `CLAUDE.md` mais scripts e configurações do Conductor.\n Se você adicionar um comando e ele não aparecer, feche completamente e reabra o aplicativo\n antes de verificar novamente.\n- T3 Code: esta é a superfície de harness mais enxuta aqui. Use o padrão\n `AGENTS.md` no estilo Codex mais `.agents/skills`, e não invente um layout de comando\n separado e específico do T3 para documentação sobre Coasts.\n- Codex: mantenha `AGENTS.md` curto e coloque o workflow reutilizável em\n `.agents/skills`.\n", - "harnesses/T3_CODE.md": "# T3 Code\n\n[T3 Code](https://github.com/pingdotgg/t3code) cria git worktrees em\n`~/.t3/worktrees//`, com checkout em branches nomeadas.\n\nNo T3 Code, coloque as regras sempre ativas do Coast Runtime em `AGENTS.md` e o\nworkflow reutilizável `/coasts` em `.agents/skills/coasts/SKILL.md`.\n\nComo essas worktrees ficam fora da raiz do projeto, o Coasts precisa de\nconfiguração explícita para descobri-las e montá-las.\n\n## Configuração\n\nAdicione `~/.t3/worktrees/` a `worktree_dir`. O T3 Code aninha worktrees em um subdiretório por projeto, então o caminho deve incluir o nome do projeto. No exemplo abaixo, `my-app` deve corresponder ao nome real da pasta em `~/.t3/worktrees/` para o seu repositório.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nO Coasts expande `~` em tempo de execução e trata qualquer caminho que comece com `~/` ou `/` como externo. Veja [Worktree Directories](../coastfiles/WORKTREE_DIR.md) para detalhes.\n\nApós alterar `worktree_dir`, instâncias existentes devem ser **recriadas** para que o bind mount tenha efeito:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nA listagem de worktrees é atualizada imediatamente (o Coasts lê o novo Coastfile), mas\natribuir a uma worktree do T3 Code requer o bind mount dentro do container.\n\n## Onde vai a orientação do Coasts\n\nUse este layout para T3 Code:\n\n- coloque as regras curtas do Coast Runtime em `AGENTS.md`\n- coloque o workflow reutilizável `/coasts` em `.agents/skills/coasts/SKILL.md`\n- não adicione uma camada separada de comando de projeto ou slash-command específica do T3 para\n Coasts\n- se este repositório usar múltiplos harnesses, veja\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) e\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\n## O que o Coasts faz\n\n- **Run** — `coast run ` cria uma nova instância do Coast a partir do build mais recente. Use `coast run -w ` para criar e atribuir uma worktree do T3 Code em uma única etapa. Veja [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — Na criação do container, o Coasts monta\n `~/.t3/worktrees/` no container em\n `/host-external-wt/{index}`.\n- **Descoberta** — `git worktree list --porcelain` é delimitado ao repositório, então apenas worktrees pertencentes ao projeto atual aparecem.\n- **Nomenclatura** — As worktrees do T3 Code usam branches nomeadas, então aparecem pelo nome da branch na UI e CLI do Coasts.\n- **Atribuição** — `coast assign` remonta `/workspace` a partir do caminho de bind mount externo.\n- **Sincronização de arquivos ignorados pelo Git** — É executada no sistema de arquivos do host com caminhos absolutos, funciona sem o bind mount.\n- **Detecção de órfãos** — O watcher do git varre diretórios externos\n recursivamente, filtrando por ponteiros gitdir de `.git`. Se o T3 Code remover um\n workspace, o Coasts remove automaticamente a atribuição da instância.\n\n## Exemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code (local, sem tratamento especial)\n- `~/.codex/worktrees/` — Codex (externo, montado com bind mount)\n- `~/.t3/worktrees/my-app/` — T3 Code (externo, montado com bind mount; substitua `my-app` pelo nome da pasta do seu repositório)\n\n## Limitações\n\n- Evite depender de variáveis de ambiente específicas do T3 Code para configuração de runtime dentro do Coasts. O Coasts gerencia portas, caminhos de workspace e descoberta de serviços de forma independente — use Coastfile `[ports]` e `coast exec` em vez disso.\n", + "harnesses/SHEP.md": "# Shep\n\n## Configuração rápida\n\nRequer o [Coast CLI](../GETTING_STARTED.md). Copie este prompt para o chat do seu\nagente para configurar Coasts automaticamente:\n\n```prompt-copy\nshep_setup_prompt.txt\n```\n\nVocê também pode obter o conteúdo da skill pelo CLI: `coast skills-prompt`.\n\nApós a configuração, **feche e reabra seu editor** para que a nova skill e as\ninstruções do projeto entrem em vigor.\n\n---\n\n[Shep](https://shep-ai.github.io/cli/) cria worktrees em `~/.shep/repos/{hash}/wt/{branch-slug}`. O hash são os primeiros 16 caracteres hexadecimais do SHA-256 do caminho absoluto do repositório, portanto ele é determinístico por repositório, mas opaco. Todos os worktrees de um determinado repositório compartilham o mesmo hash e são diferenciados pelo subdiretório `wt/{branch-slug}`.\n\nNo Shep CLI, `shep feat show ` imprime o caminho do worktree, ou\n`ls ~/.shep/repos` lista os diretórios de hash por repositório.\n\nComo o hash varia por repositório, Coasts usa um **padrão glob** para descobrir\nworktrees do shep sem exigir que o usuário codifique o hash manualmente.\n\n## Configuração\n\nAdicione `~/.shep/repos/*/wt` a `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\nO `*` corresponde ao diretório de hash por repositório. Em tempo de execução, o Coasts expande o glob,\nencontra o diretório correspondente (por exemplo, `~/.shep/repos/a21f0cda9ab9d456/wt`) e\nfaz o bind mount dele no contêiner. Veja\n[Worktree Directories](../coastfiles/WORKTREE_DIR.md) para detalhes completos sobre padrões\nglob.\n\nApós alterar `worktree_dir`, instâncias existentes devem ser **recriadas** para que o bind mount entre em vigor:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nA listagem de worktrees é atualizada imediatamente (o Coasts lê o novo Coastfile), mas\natribuir a um worktree do Shep requer o bind mount dentro do contêiner.\n\n## Onde a orientação do Coasts vai\n\nO Shep encapsula o Claude Code internamente, então siga as convenções do Claude Code:\n\n- coloque as regras curtas do Coast Runtime em `CLAUDE.md`\n- coloque o fluxo de trabalho reutilizável `/coasts` em `.claude/skills/coasts/SKILL.md` ou\n em `.agents/skills/coasts/SKILL.md` compartilhado\n- se este repositório também usa outros harnesses, veja\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) e\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)\n\n## O que o Coasts faz\n\n- **Run** -- `coast run ` cria uma nova instância do Coast a partir da build mais recente. Use `coast run -w ` para criar e atribuir um worktree do Shep em uma única etapa. Veja [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** -- Na criação do contêiner, o Coasts resolve o glob\n `~/.shep/repos/*/wt` e monta cada diretório correspondente no contêiner em\n `/host-external-wt/{index}`.\n- **Discovery** -- `git worktree list --porcelain` é restrito ao escopo do repositório, então apenas\n worktrees pertencentes ao projeto atual aparecem.\n- **Naming** -- Worktrees do Shep usam branches nomeados, então aparecem pelo nome\n da branch na UI e no CLI do Coasts (por exemplo, `feat-green-background`).\n- **Assign** -- `coast assign` remonta `/workspace` a partir do caminho do bind mount externo.\n- **Gitignored sync** -- Executa no sistema de arquivos do host com caminhos absolutos, funciona sem o bind mount.\n- **Orphan detection** -- O observador do git varre diretórios externos\n recursivamente, filtrando por ponteiros gitdir de `.git`. Se o Shep excluir um\n worktree, o Coasts desatribui automaticamente a instância.\n\n## Exemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/.shep/repos/*/wt` -- Shep (externo, montado por bind via expansão de glob)\n\n## Estrutura de caminho do Shep\n\n```\n~/.shep/repos/\n {sha256-of-repo-path-first-16-chars}/\n wt/\n {branch-slug}/ <-- git worktree\n {branch-slug}/\n```\n\nPontos principais:\n- Mesmo repositório = mesmo hash todas as vezes (determinístico, não aleatório)\n- Repositórios diferentes = hashes diferentes\n- Separadores de caminho são normalizados para `/` antes do hash\n- O hash pode ser encontrado via `shep feat show ` ou `ls ~/.shep/repos`\n", + "harnesses/T3_CODE.md": "# T3 Code\n\n## Configuração rápida\n\nRequer a [Coast CLI](../GETTING_STARTED.md). Copie este prompt para o chat do seu\nagente para configurar o Coasts automaticamente:\n\n```prompt-copy\nt3_code_setup_prompt.txt\n```\n\nVocê também pode obter o conteúdo da skill pela CLI: `coast skills-prompt`.\n\nApós a configuração, **reinicie o T3 Code** para que as mudanças de skill e\nregras entrem em vigor.\n\n**Observação:** O T3 Code talvez ainda não carregue skills no nível do projeto\nde `.agents/skills/` ou `.claude/skills/`. O prompt de configuração também\ncoloca a skill em `~/.codex/skills/coasts/` para que ela fique disponível\nglobalmente para o provedor Codex. As regras do Coast Runtime em `AGENTS.md` e\n`CLAUDE.md` ainda se aplicam em toda tarefa independentemente disso.\n\n---\n\n[T3 Code](https://github.com/pingdotgg/t3code) cria git worktrees em\n`~/.t3/worktrees//`, com checkout em branches nomeadas.\n\nO T3 Code encapsula o Codex, então usa `AGENTS.md` para regras sempre ativas e\n`.agents/skills/coasts/SKILL.md` para o workflow reutilizável `/coasts`.\n\nComo essas worktrees ficam fora da raiz do projeto, o Coasts precisa de\nconfiguração explícita para descobri-las e montá-las.\n\n## Configuração\n\nAdicione `~/.t3/worktrees/` a `worktree_dir`. O T3 Code aninha worktrees em um subdiretório por projeto, então o caminho deve incluir o nome do projeto. No exemplo abaixo, `my-app` deve corresponder ao nome real da pasta em `~/.t3/worktrees/` para o seu repositório.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nO Coasts expande `~` em tempo de execução e trata qualquer caminho que comece com `~/` ou `/` como externo. Veja [Worktree Directories](../coastfiles/WORKTREE_DIR.md) para detalhes.\n\nApós alterar `worktree_dir`, instâncias existentes devem ser **recriadas** para que o bind mount tenha efeito:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nA listagem de worktrees é atualizada imediatamente (o Coasts lê o novo Coastfile), mas\natribuir a uma worktree do T3 Code requer o bind mount dentro do container.\n\n## Onde vai a orientação do Coasts\n\nUse este layout para T3 Code:\n\n- coloque as regras curtas do Coast Runtime em `AGENTS.md`\n- coloque o workflow reutilizável `/coasts` em `.agents/skills/coasts/SKILL.md`\n- não adicione uma camada separada de comando de projeto ou slash-command específica do T3 para\n Coasts\n- se este repositório usar múltiplos harnesses, veja\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) e\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\n## O que o Coasts faz\n\n- **Run** — `coast run ` cria uma nova instância do Coast a partir do build mais recente. Use `coast run -w ` para criar e atribuir uma worktree do T3 Code em uma única etapa. Veja [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — Na criação do container, o Coasts monta\n `~/.t3/worktrees/` no container em\n `/host-external-wt/{index}`.\n- **Descoberta** — `git worktree list --porcelain` é delimitado ao repositório, então apenas worktrees pertencentes ao projeto atual aparecem.\n- **Nomenclatura** — As worktrees do T3 Code usam branches nomeadas, então aparecem pelo nome da branch na UI e CLI do Coasts.\n- **Atribuição** — `coast assign` remonta `/workspace` a partir do caminho de bind mount externo.\n- **Sincronização de arquivos ignorados pelo Git** — É executada no sistema de arquivos do host com caminhos absolutos, funciona sem o bind mount.\n- **Detecção de órfãos** — O watcher do git varre diretórios externos\n recursivamente, filtrando por ponteiros gitdir de `.git`. Se o T3 Code remover um\n workspace, o Coasts remove automaticamente a atribuição da instância.\n\n## Exemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code (local, sem tratamento especial)\n- `~/.codex/worktrees/` — Codex (externo, montado com bind mount)\n- `~/.t3/worktrees/my-app/` — T3 Code (externo, montado com bind mount; substitua `my-app` pelo nome da pasta do seu repositório)\n\n## Limitações\n\n- Evite depender de variáveis de ambiente específicas do T3 Code para configuração de runtime dentro do Coasts. O Coasts gerencia portas, caminhos de workspace e descoberta de serviços de forma independente — use Coastfile `[ports]` e `coast exec` em vez disso.\n", + "harnesses/claude_code_setup_prompt.txt": "Você está configurando a skill Coasts para o Claude Code neste projeto. Execute todos\nos comandos a partir da raiz do projeto.\n\n## Etapa 1: Verificar a CLI do Coast\n\nExecute este comando:\n\n coast --version\n\nSe o comando `coast` não for encontrado, pare aqui e diga ao usuário:\n\n \"A CLI do Coast não está instalada. Instale-a primeiro: https://coasts.dev/docs/getting-started\"\n\nNão continue até que a CLI esteja disponível.\n\n## Etapa 2: Obter o conteúdo da skill\n\nExecute este comando:\n\n coast skills-prompt\n\nA saída tem duas partes:\n\n- **Regras do Runtime do Coast** — tudo desde o início até (mas não incluindo) a linha que começa com `---`\n- **Skill Coasts** — tudo a partir do bloco de frontmatter `---` em diante (incluindo as linhas `---` e tudo depois delas)\n\nSalve ambas as partes para as etapas abaixo.\n\n## Etapa 3: Perguntar ao usuário\n\nPergunte ao usuário: devo configurar isso **globalmente** (disponível em todos os projetos nesta máquina) ou **apenas para este projeto**?\n\n## Etapa 4: Colocar os arquivos\n\nSe um arquivo de destino já existir, anexe a seção Coast Runtime em vez de sobrescrever — mas verifique primeiro se uma seção `# Coast Runtime` já está presente e pule se estiver.\n\n**Configuração global:**\n- Anexe as regras do Coast Runtime a `~/.claude/CLAUDE.md`\n- Grave a skill Coasts em `~/.claude/skills/coasts/SKILL.md`\n\n**Configuração do projeto:**\n- Anexe as regras do Coast Runtime a `CLAUDE.md` na raiz do projeto\n- Grave a skill Coasts em `.claude/skills/coasts/SKILL.md`\n\n## Etapa 5: Atualizar o Coastfile\n\nLeia o `Coastfile` na raiz do projeto. Observe o campo `worktree_dir` na\nseção `[coast]`.\n\nSe `.claude/worktrees` **ainda não** estiver listado em `worktree_dir`:\n\n- Se `worktree_dir` for uma única string, converta-o em um array e anexe\n `.claude/worktrees`. Por exemplo, `worktree_dir = \".worktrees\"` torna-se\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]`.\n- Se `worktree_dir` já for um array, anexe `.claude/worktrees` a ele.\n- Se `worktree_dir` não estiver presente, adicione\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]`.\n\nEste é um caminho relativo (dentro da raiz do projeto), então não é necessária\nnenhuma recriação do contêiner — as alterações entram em vigor imediatamente para a listagem de worktrees.\n\n## Etapa 6: Confirmar\n\nApós colocar os arquivos, mostre ao usuário um resumo do que foi criado e onde.\n\nDiga ao usuário: **Inicie uma nova sessão do Claude Code** para que a skill e as alterações no CLAUDE.md entrem em vigor.\n", + "harnesses/codex_setup_prompt.txt": "Você está configurando a skill Coasts para o OpenAI Codex neste projeto. Execute todos os\ncomandos a partir da raiz do projeto.\n\n## Etapa 1: Verificar o Coast CLI\n\nExecute este comando:\n\n coast --version\n\nSe o comando `coast` não for encontrado, pare aqui e diga ao usuário:\n\n \"O Coast CLI não está instalado. Instale-o primeiro: https://coasts.dev/docs/getting-started\"\n\nNão continue até que o CLI esteja disponível.\n\n## Etapa 2: Obter o conteúdo da skill\n\nExecute este comando:\n\n coast skills-prompt\n\nA saída tem duas partes:\n\n- **Regras do Coast Runtime** — tudo desde o início até (mas não incluindo) a linha que começa com `---`\n- **Skill Coasts** — tudo a partir do bloco de frontmatter `---` em diante (incluindo as linhas `---` e tudo depois delas)\n\nSalve ambas as partes para as etapas abaixo.\n\n## Etapa 3: Colocar os arquivos\n\nA configuração do Codex é sempre no nível do projeto. Se um arquivo de destino já existir, acrescente a seção Coast Runtime em vez de sobrescrever — mas verifique primeiro se uma seção `# Coast Runtime` já está presente e, nesse caso, ignore.\n\n- Acrescente as regras do Coast Runtime a `AGENTS.md` na raiz do projeto\n- Grave a skill Coasts em `.agents/skills/coasts/SKILL.md`\n- Crie `.agents/skills/coasts/agents/openai.yaml` com este conteúdo:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## Etapa 4: Atualizar o Coastfile\n\nLeia o `Coastfile` na raiz do projeto. Veja o campo `worktree_dir` na\nseção `[coast]`.\n\nSe `~/.codex/worktrees` **ainda não** estiver listado em `worktree_dir`:\n\n- Se `worktree_dir` for uma única string, converta-o em um array e acrescente\n `~/.codex/worktrees`. Por exemplo, `worktree_dir = \".worktrees\"` torna-se\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]`.\n- Se `worktree_dir` já for um array, acrescente `~/.codex/worktrees` a ele.\n- Se `worktree_dir` não estiver presente, adicione\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]`.\n\nEste é um caminho externo, então se uma instância do Coast já estiver em execução para este\nprojeto, ela deverá ser recriada com `coast run` para que a nova montagem de bind\ntenha efeito. Informe isso ao usuário.\n\n## Etapa 5: Confirmar\n\nApós colocar os arquivos, mostre ao usuário um resumo do que foi criado e onde.\n\nDiga ao usuário: **Saia e reabra o Codex** para que a skill e as alterações em AGENTS.md\ntenham efeito.\n", + "harnesses/conductor_setup_prompt.txt": "Você está configurando a skill Coasts para o Conductor neste projeto. Execute todos\nos comandos a partir da raiz do projeto.\n\n## Etapa 1: Verificar o Coast CLI\n\nExecute este comando:\n\n coast --version\n\nSe o comando `coast` não for encontrado, pare aqui e diga ao usuário:\n\n \"O Coast CLI não está instalado. Instale-o primeiro: https://coasts.dev/docs/getting-started\"\n\nNão continue até que o CLI esteja disponível.\n\n## Etapa 2: Obter o conteúdo da skill\n\nExecute este comando:\n\n coast skills-prompt\n\nA saída tem duas partes:\n\n- **Regras do Coast Runtime** — tudo desde o início até (mas não incluindo) a linha que começa com `---`\n- **Skill do Coasts** — tudo a partir do bloco de frontmatter `---` em diante (incluindo as linhas `---` e tudo depois delas)\n\nSalve ambas as partes para as etapas abaixo.\n\n## Etapa 3: Perguntar ao usuário\n\nPergunte ao usuário: quais provedores você usa no Conductor?\n\n- **Claude** (Anthropic)\n- **Codex** (OpenAI)\n- **Ambos**\n- **Outro** — se o usuário nomear um provedor diferente, execute\n `coast docs --path SKILLS_FOR_HOST_AGENTS.md` e\n `coast docs --path harnesses/README.md` para determinar onde esse provedor\n espera instruções do projeto e skills, então siga o mesmo padrão\n\n## Etapa 4: Colocar os arquivos\n\nA configuração do Conductor é sempre no nível do projeto. Se um arquivo de destino já existir, acrescente\na seção Coast Runtime em vez de sobrescrever — mas verifique primeiro se uma\nseção `# Coast Runtime` já está presente e, nesse caso, ignore.\n\n**Se o usuário selecionou Claude (ou ambos):**\n- Acrescente as regras do Coast Runtime a `CLAUDE.md` na raiz do projeto\n- Grave a skill do Coasts em `.claude/skills/coasts/SKILL.md`\n\n**Se o usuário selecionou Codex (ou ambos):**\n- Acrescente as regras do Coast Runtime a `AGENTS.md` na raiz do projeto\n- Grave a skill do Coasts em `.agents/skills/coasts/SKILL.md`\n- Crie `.agents/skills/coasts/agents/openai.yaml` com este conteúdo:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## Etapa 5: Confirmar\n\nApós colocar os arquivos, mostre ao usuário um resumo do que foi criado e onde.\n\nDiga ao usuário: **Feche totalmente e reabra o Conductor** para que as alterações tenham efeito.\nSe o comando `/coasts` não aparecer imediatamente, feche e reabra novamente.\n\n## Etapa 6: Atualizar o Coastfile\n\nLeia o `Coastfile` na raiz do projeto. Observe o campo `worktree_dir` na\nseção `[coast]`. Leia também o campo `name` — você precisará dele para construir o\ncaminho da worktree.\n\nO diretório de worktree do Conductor é `~/conductor/workspaces/`, onde\n`` é o valor do campo `name` no Coastfile.\n\nSe esse caminho **ainda não** estiver listado em `worktree_dir`:\n\n- Se `worktree_dir` for uma única string, converta-o em um array e acrescente o\n caminho do Conductor. Por exemplo, `worktree_dir = \".worktrees\"` torna-se\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]`.\n- Se `worktree_dir` já for um array, acrescente o caminho do Conductor a ele.\n- Se `worktree_dir` não estiver presente, adicione\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/\"]` usando o\n nome real do projeto.\n\nEste é um caminho externo, portanto, se uma instância do Coast já estiver em execução para este\nprojeto, ela deverá ser recriada com `coast run` para que a nova montagem de bind tenha\nefeito. Informe isso ao usuário.\n\n## Etapa 7: Fazer commit dos novos arquivos\n\nO Conductor executa cada sessão em uma git worktree isolada. Arquivos sem commit não\nserão levados para novas sessões. Faça commit dos arquivos que você acabou de criar para que eles estejam\ndisponíveis em todos os workspaces futuros:\n\n git add CLAUDE.md .claude/ AGENTS.md .agents/ 2>/dev/null; git status\n\nMostre ao usuário quais arquivos estão em stage e peça que ele confirme antes de fazer o commit.\nUse uma mensagem de commit como `[dh] feat: add Coasts skill for Conductor`.\n", + "harnesses/cursor_setup_prompt.txt": "Você está configurando a skill Coasts para o Cursor neste projeto. Execute todos\nos comandos a partir da raiz do projeto.\n\n## Etapa 1: Verificar o Coast CLI\n\nExecute este comando:\n\n coast --version\n\nSe o comando `coast` não for encontrado, pare aqui e diga ao usuário:\n\n \"O Coast CLI não está instalado. Instale-o primeiro: https://coasts.dev/docs/getting-started\"\n\nNão continue até que o CLI esteja disponível.\n\n## Etapa 2: Obter o conteúdo da skill\n\nExecute este comando:\n\n coast skills-prompt\n\nA saída tem duas partes:\n\n- **Regras do Coast Runtime** — tudo desde o início até (mas sem incluir) a linha que começa com `---`\n- **Skill Coasts** — tudo a partir do bloco de frontmatter `---` em diante (incluindo as linhas `---` e tudo após elas)\n\nSalve ambas as partes para as etapas abaixo.\n\n## Etapa 3: Perguntar ao usuário\n\nPergunte ao usuário: devo configurar isso **globalmente** (disponível em todos os projetos nesta máquina) ou **apenas para este projeto**?\n\n## Etapa 4: Colocar os arquivos\n\nSe um arquivo de destino já existir, acrescente a seção Coast Runtime em vez de sobrescrever — mas verifique primeiro se uma seção `# Coast Runtime` já está presente e, nesse caso, ignore.\n\n**Configuração global:**\n- Acrescente as regras do Coast Runtime às regras globais do Cursor do usuário\n- Grave a skill Coasts em `~/.cursor/skills/coasts/SKILL.md`\n\n**Configuração do projeto:**\n- Acrescente as regras do Coast Runtime a `AGENTS.md` na raiz do projeto (ou `.cursor/rules/coast.md` se o usuário preferir regras nativas do Cursor — pergunte a ele)\n- Grave a skill Coasts em `.cursor/skills/coasts/SKILL.md`\n\n## Etapa 5: Atualizar o Coastfile\n\nLeia o `Coastfile` na raiz do projeto. Observe o campo `worktree_dir` na\nseção `[coast]`. Leia também o campo `name` — você precisará dele para construir o\ncaminho da worktree.\n\nO diretório de worktree do Cursor é `~/.cursor/worktrees/`, onde `` é\no valor do campo `name` no Coastfile.\n\nSe esse caminho **ainda não** estiver listado em `worktree_dir`:\n\n- Se `worktree_dir` for uma única string, converta-o em um array e acrescente o\n caminho do Cursor. Por exemplo, `worktree_dir = \".worktrees\"` torna-se\n `worktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]`.\n- Se `worktree_dir` já for um array, acrescente o caminho do Cursor a ele.\n- Se `worktree_dir` não estiver presente, adicione\n `worktree_dir = [\".worktrees\", \"~/.cursor/worktrees/\"]` usando o\n nome real do projeto.\n\nEste é um caminho externo, então, se uma instância do Coast já estiver em execução para este\nprojeto, ela deverá ser recriada com `coast run` para que a nova montagem de bind\nentre em vigor. Informe isso ao usuário.\n\n## Etapa 6: Confirmar\n\nApós colocar os arquivos, mostre ao usuário um resumo do que foi criado e onde.\n\nDiga ao usuário: **Reinicie o Cursor** para que as alterações na skill e nas regras\nentrem em vigor.\n", + "harnesses/shep_setup_prompt.txt": "Você está configurando a skill Coasts para o Shep neste projeto. Execute todos\nos comandos a partir da raiz do projeto.\n\n## Etapa 1: Verificar se o Coast CLI está instalado\n\nExecute este comando:\n\n coast --version\n\nSe o comando `coast` não for encontrado, pare aqui e informe ao usuário:\n\n \"O Coast CLI não está instalado. Instale-o primeiro: https://coasts.dev/docs/getting-started\"\n\nNão continue até que o CLI esteja disponível.\n\n## Etapa 2: Obter o conteúdo da skill\n\nExecute este comando:\n\n coast skills-prompt\n\nA saída tem duas partes:\n\n- **Regras do Coast Runtime** — tudo desde o início até (mas não incluindo) a linha que começa com `---`\n- **Skill Coasts** — tudo a partir do bloco de frontmatter `---` em diante (incluindo as linhas `---` e tudo o que vem depois delas)\n\nSalve ambas as partes para as etapas abaixo.\n\n## Etapa 3: Colocar os arquivos\n\nO Shep encapsula o Claude Code, então use o layout de arquivos do Claude Code. Se um arquivo de destino\njá existir, anexe a seção Coast Runtime em vez de sobrescrever — mas\nverifique primeiro se uma seção `# Coast Runtime` já está presente e ignore se\nestiver.\n\n- Anexe as regras do Coast Runtime a `CLAUDE.md` na raiz do projeto\n- Grave a skill Coasts em `.agents/skills/coasts/SKILL.md` (ou\n `.claude/skills/coasts/SKILL.md` se o projeto já usar esse layout)\n\n## Etapa 4: Atualizar o Coastfile\n\nLeia o `Coastfile` na raiz do projeto. Observe o campo `worktree_dir` na\nseção `[coast]`.\n\nSe `~/.shep/repos/*/wt` **ainda não** estiver listado em `worktree_dir`:\n\n- Se `worktree_dir` for uma única string, converta-o em um array e anexe\n `~/.shep/repos/*/wt`. Por exemplo, `worktree_dir = \".worktrees\"` torna-se\n `worktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]`.\n- Se `worktree_dir` já for um array, anexe `~/.shep/repos/*/wt` a ele.\n- Se `worktree_dir` não estiver presente, adicione\n `worktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]`.\n\nO `*` é um padrão glob que corresponde ao diretório de hash por repositório. O Coasts\no expande em tempo de execução.\n\nEste é um caminho externo, portanto, se uma instância do Coast já estiver em execução para este\nprojeto, ela deverá ser recriada com `coast run` para que a nova montagem de bind tenha efeito.\nInforme isso ao usuário.\n\n## Etapa 5: Confirmar\n\nDepois de colocar os arquivos, mostre ao usuário um resumo do que foi criado e onde.\n\nDiga ao usuário: **Feche e reabra seu editor** para que a skill e as alterações em CLAUDE.md\ntenham efeito.\n", + "harnesses/t3_code_setup_prompt.txt": "Você está configurando a skill Coasts para o T3 Code neste projeto. Execute todos\nos comandos a partir da raiz do projeto.\n\n## Etapa 1: Verificar o Coast CLI\n\nExecute este comando:\n\n coast --version\n\nSe o comando `coast` não for encontrado, pare aqui e diga ao usuário:\n\n \"O Coast CLI não está instalado. Instale-o primeiro: https://coasts.dev/docs/getting-started\"\n\nNão continue até que o CLI esteja disponível.\n\n## Etapa 2: Obter o conteúdo da skill\n\nExecute este comando:\n\n coast skills-prompt\n\nA saída tem duas partes:\n\n- **Regras do Coast Runtime** — tudo desde o início até (mas não incluindo) a linha que começa com `---`\n- **Skill Coasts** — tudo a partir do bloco de frontmatter `---` em diante (incluindo as linhas `---` e tudo depois delas)\n\nSalve ambas as partes para as etapas abaixo.\n\n## Etapa 3: Perguntar ao usuário\n\nO T3 Code oferece suporte a vários provedores. Pergunte ao usuário: quais provedores você usa\nno T3 Code?\n\n- **Codex** (OpenAI)\n- **Claude** (Anthropic)\n- **Ambos**\n- **Outro** — se o usuário mencionar um provedor diferente, execute\n `coast docs --path SKILLS_FOR_HOST_AGENTS.md` e\n `coast docs --path harnesses/README.md` para determinar onde esse provedor\n espera instruções de projeto e skills, então siga o mesmo padrão\n\n## Etapa 4: Colocar os arquivos\n\nA configuração do T3 Code é sempre no nível do projeto. Se um arquivo de destino já existir, acrescente\na seção Coast Runtime em vez de sobrescrever — mas verifique primeiro se uma\nseção `# Coast Runtime` já está presente e ignore se estiver.\n\n**Se o usuário selecionou Codex (ou ambos):**\n- Acrescente as regras do Coast Runtime a `AGENTS.md` na raiz do projeto\n- Grave a skill Coasts em `.agents/skills/coasts/SKILL.md` (nível do projeto)\n- Grave também a skill Coasts em `~/.codex/skills/coasts/SKILL.md` (fallback\n global — o T3 Code talvez ainda não examine `.agents/skills/` no nível do projeto)\n- Crie `.agents/skills/coasts/agents/openai.yaml` com este conteúdo:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n**Se o usuário selecionou Claude (ou ambos):**\n- Acrescente as regras do Coast Runtime a `CLAUDE.md` na raiz do projeto\n- Grave a skill Coasts em `.claude/skills/coasts/SKILL.md` (nível do projeto)\n- Grave também a skill Coasts em `~/.claude/skills/coasts/SKILL.md` (fallback\n global — o T3 Code talvez ainda não examine `.claude/skills/` no nível do projeto de forma confiável)\n\n**Nota:** O T3 Code talvez ainda não carregue skills no nível do projeto a partir de `.agents/skills/` ou\n`.claude/skills/`. As regras em `AGENTS.md` e `CLAUDE.md` ainda se aplicam em\ntodas as tarefas independentemente disso. O fallback global `~/.codex/skills/coasts/` garante\nque o provedor Codex possa encontrar a skill.\n\n## Etapa 5: Atualizar o Coastfile\n\nLeia o `Coastfile` na raiz do projeto. Observe o campo `worktree_dir` na\nseção `[coast]`. Leia também o campo `name` — você precisará dele para construir o\ncaminho da worktree.\n\nO diretório de worktree do T3 Code é `~/.t3/worktrees/`, onde `` é\no valor do campo `name` no Coastfile.\n\nSe esse caminho **ainda não** estiver listado em `worktree_dir`:\n\n- Se `worktree_dir` for uma única string, converta-o em um array e acrescente o\n caminho do T3 Code. Por exemplo, `worktree_dir = \".worktrees\"` se torna\n `worktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]`.\n- Se `worktree_dir` já for um array, acrescente a ele o caminho do T3 Code.\n- Se `worktree_dir` não estiver presente, adicione\n `worktree_dir = [\".worktrees\", \"~/.t3/worktrees/\"]` usando o\n nome real do projeto.\n\nEste é um caminho externo, portanto, se uma instância do Coast já estiver em execução para este\nprojeto, ela deverá ser recriada com `coast run` para que a nova montagem de bind\ntenha efeito. Informe isso ao usuário.\n\n## Etapa 6: Confirmar\n\nApós colocar os arquivos, mostre ao usuário um resumo do que foi criado e onde.\nExplique que a cópia global em `~/.codex/skills/coasts/` é uma solução temporária para\no T3 Code ainda não carregar skills no nível do projeto.\n\nDiga ao usuário: **Reinicie o T3 Code** para que as alterações na skill e nas regras entrem\nem vigor.\n", "learn-coasts-videos/README.md": "# Curso em Vídeo do Coasts\n\nUm curso curto em vídeo cobrindo as ideias centrais por trás do Coasts. Cada lição tem menos de três minutos. Assista em ordem para ter a visão completa, ou pule para o tópico de que você precisa.\n\n```youtube\nMBGKSKau4sU\n```\n\n## Lições\n\n1. [Coasts](coasts.md) — o que é um Coast e como o modelo central funciona.\n2. [Ports](ports.md) — como o Coasts lida com o isolamento de portas e o acesso paralelo em tempo de execução.\n3. [Assign](assign.md) — alternar um Coast em execução entre worktrees.\n4. [Checkout](checkout.md) — trazer um Coast para suas portas canônicas para uso ativo.\n5. [Volumes](volumes.md) — como o Coasts lida com volumes e estado persistente de serviço.\n6. [Secrets](secrets.md) — gerenciamento de segredos dentro de um Coast.\n7. [Getting Started](getting-started.md) — um passo a passo prático para experimentar o Coasts em um projeto real.\n8. [Coast UI](coast-ui.md) — a interface do Coastguard e as informações de tempo de execução que ela expõe.\n", "learn-coasts-videos/assign.md": "# Atribuir\n\n```youtube\nLYCeequ54nk\n```\n\nAtribuir move um Coast em execução de uma worktree para outra sem desmontar o runtime. Este vídeo aborda como a atribuição funciona e quando você a utilizaria para entregar um Coast a uma branch diferente.\n\nPara a referência completa, consulte [Atribuir e Desatribuir](../concepts_and_terminology/ASSIGN.md).\n", "learn-coasts-videos/checkout.md": "# Checkout\n\n```youtube\nJRAXkM4U1UE\n```\n\nCheckout mapeia as portas canônicas do seu projeto para uma instância específica do Coast. Este vídeo mostra como trazer um Coast para a frente para que seu navegador, clientes de API e suítes de teste atinjam o ambiente correto sem alterar nenhum número de porta.\n\nPara a referência completa, veja [Checkout](../concepts_and_terminology/CHECKOUT.md).\n", @@ -2732,6 +2792,11 @@ "path": "harnesses/MULTIPLE_HARNESSES.md", "type": "file" }, + { + "name": "SHEP.md", + "path": "harnesses/SHEP.md", + "type": "file" + }, { "name": "T3_CODE.md", "path": "harnesses/T3_CODE.md", @@ -2812,11 +2877,11 @@ "files": { "README.md": "# Documentación de Coasts\n\n```youtube\nMBGKSKau4sU\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## Instalación\n\n- `curl -fsSL https://coasts.dev/install | sh`\n- `coast daemon install`\n\n*Si decides no ejecutar `coast daemon install`, eres responsable de iniciar el daemon manualmente con `coast daemon start` cada vez.*\n\n## ¿Qué son Coasts?\n\nUn Coast (**host contenedorizado**) es un runtime local de desarrollo. Coasts te permiten ejecutar múltiples entornos aislados para el mismo proyecto en una sola máquina.\n\nCoasts son especialmente útiles para stacks complejos de `docker-compose` con muchos servicios interdependientes, pero son igualmente eficaces para configuraciones locales de desarrollo no contenedorizadas. Coasts admiten una amplia gama de [patrones de configuración de runtime](concepts_and_terminology/RUNTIMES_AND_SERVICES.md) para que puedas diseñar el entorno ideal para múltiples agentes trabajando en paralelo.\n\nCoasts están construidos para el desarrollo local, no como un servicio cloud alojado. Tus entornos se ejecutan localmente en tu máquina.\n\nEl proyecto Coasts es software gratuito, local, con licencia MIT, agnóstico al proveedor de agentes y agnóstico al arnés de agentes, sin ventas adicionales de IA.\n\nCoasts funcionan con cualquier flujo de trabajo de programación agéntica que use worktrees. No se requiere ninguna configuración especial del lado del arnés.\n\n## Por qué Coasts para Worktrees\n\nLos worktrees de Git son excelentes para aislar cambios de código, pero por sí solos no resuelven el aislamiento del runtime.\n\nCuando ejecutas múltiples worktrees en paralelo, rápidamente te encuentras con problemas de ergonomía:\n\n- [Conflictos de puertos](concepts_and_terminology/PORTS.md) entre servicios que esperan los mismos puertos del host.\n- Configuración de base de datos y [volúmenes](concepts_and_terminology/VOLUMES.md) por worktree que es tediosa de gestionar.\n- Entornos de pruebas de integración que necesitan cableado de runtime personalizado por worktree.\n- El infierno viviente de cambiar de worktree y reconstruir el contexto del runtime cada vez. Ver [Asignar y Desasignar](concepts_and_terminology/ASSIGN.md).\n\nSi Git es control de versiones para tu código, Coasts son como Git para los runtimes de tus worktrees.\n\nCada entorno obtiene sus propios puertos, así que puedes inspeccionar el runtime de cualquier worktree en paralelo. Cuando [haces checkout](concepts_and_terminology/CHECKOUT.md) de un runtime de worktree, Coasts remapean ese runtime a los puertos canónicos de tu proyecto.\n\nCoasts abstraen la configuración del runtime en una capa modular simple encima de los worktrees, para que cada worktree pueda ejecutarse con el aislamiento que necesita sin mantener manualmente una configuración compleja por worktree.\n\n## Requisitos\n\n- macOS o Linux\n- Docker Desktop en macOS, o Docker Engine con el plugin Compose en Linux\n- Un proyecto que use Git\n- Node.js\n- `socat` (`brew install socat` en macOS, `sudo apt install socat` en Ubuntu)\n\n```text\nNota sobre Linux: Los puertos dinámicos funcionan de inmediato en Linux.\nSi necesitas puertos canónicos por debajo de `1024`, consulta la documentación de checkout para la configuración de host necesaria.\n```\n\n## ¿Contenerizar agentes?\n\nPuedes contenerizar un agente con un Coast. Eso podría sonar como una gran idea al principio, pero en muchos casos en realidad no necesitas ejecutar tu agente de programación dentro de un contenedor.\n\nDebido a que Coasts comparten el [sistema de archivos](concepts_and_terminology/FILESYSTEM.md) con tu máquina host mediante un montaje de volumen compartido, el flujo de trabajo más fácil y fiable es ejecutar el agente en tu host e indicarle que ejecute tareas pesadas de runtime (como pruebas de integración) dentro de la instancia de Coast usando [`coast exec`](concepts_and_terminology/EXEC_AND_DOCKER.md).\n\nSin embargo, si sí quieres ejecutar tu agente en un contenedor, Coasts lo soportan absolutamente mediante [Agent Shells](concepts_and_terminology/AGENT_SHELLS.md). Puedes construir un rig increíblemente intrincado para esta configuración, incluyendo la [configuración del servidor MCP](concepts_and_terminology/MCP_SERVERS.md), pero puede que no interopere limpiamente con el software de orquestación que existe hoy. Para la mayoría de los flujos de trabajo, los agentes del lado del host son más simples y más fiables.\n\n## Coasts vs Dev Containers\n\nCoasts no son dev containers, y no son lo mismo.\n\nLos dev containers generalmente están diseñados para montar un IDE dentro de un único espacio de trabajo de desarrollo contenedorizado. Coasts son headless y están optimizados como entornos ligeros para el uso de agentes en paralelo con worktrees — múltiples entornos de runtime aislados y conscientes de worktrees ejecutándose lado a lado, con cambios rápidos de checkout y controles de aislamiento del runtime para cada instancia.\n\n## Repo de demostración\n\nSi quieres un pequeño proyecto de ejemplo para probar con Coasts, empieza con el repositorio [`coasts-demo`](https://github.com/coast-guard/coasts-demo).\n\n## Coasts Video Course\n\nSi prefieres el video, el [Coasts Video Course](learn-coasts-videos/README.md) cubre cada concepto central en menos de tres minutos cada uno.\n", "GETTING_STARTED.md": "# Primeros pasos con Coasts\n\n```youtube\nJe921fgJ4RY\nPart of the [Coasts Video Course](learn-coasts-videos/README.md).\n```\n\n## Instalación\n\n```bash\ncurl -fsSL https://coasts.dev/install | sh\ncoast daemon install\n```\n\n*Si decides no ejecutar `coast daemon install`, eres responsable de iniciar el daemon manualmente con `coast daemon start` cada vez.*\n\n## Requisitos\n\n- macOS o Linux\n- Docker Desktop en macOS, o Docker Engine con el plugin Compose en Linux\n- Un proyecto que use Git\n- Node.js\n- `socat` (`brew install socat` en macOS, `sudo apt install socat` en Ubuntu)\n\n```text\nLinux note: Dynamic ports work out of the box on Linux.\nIf you need canonical ports below `1024`, see the checkout docs for the required host configuration.\n```\n\n## Configurar Coasts en un proyecto\n\nAgrega un Coastfile en la raíz de tu proyecto. Asegúrate de no estar en un worktree al instalar.\n\n```text\nmy-project/\n├── Coastfile <-- esto es lo que lee Coast\n├── docker-compose.yml\n├── Dockerfile\n├── src/\n│ └── ...\n└── ...\n```\n\nEl `Coastfile` apunta a tus recursos existentes de desarrollo local y añade configuración específica de Coasts — consulta la [documentación de Coastfiles](coastfiles/README.md) para el esquema completo:\n\n```toml\n[coast]\nname = \"my-project\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\ndb = 5432\n```\n\nUn Coastfile es un archivo TOML ligero que *típicamente* apunta a tu `docker-compose.yml` existente (también funciona con configuraciones de desarrollo local sin contenedores) y describe las modificaciones necesarias para ejecutar tu proyecto en paralelo: asignaciones de puertos, estrategias de volúmenes y secretos. Colócalo en la raíz de tu proyecto.\n\nLa forma más rápida de crear un Coastfile para tu proyecto es dejar que tu agente de programación lo haga.\n\nLa CLI de Coasts incluye un prompt integrado que enseña a cualquier agente de IA el esquema completo del Coastfile y la CLI. Cópialo en el chat de tu agente y analizará tu proyecto y generará un Coastfile.\n\n```prompt-copy\ninstallation_prompt.txt\n```\n\nTambién puedes obtener el mismo resultado desde la CLI ejecutando `coast installation-prompt`.\n\n## Tu primer Coast\n\nAntes de iniciar tu primer Coast, baja cualquier entorno de desarrollo en ejecución. Si estás usando Docker Compose, ejecuta `docker-compose down`. Si tienes servidores de desarrollo local ejecutándose, detenlos. Coasts gestiona sus propios puertos y entrará en conflicto con cualquier cosa que ya esté escuchando.\n\nUna vez que tu Coastfile esté listo:\n\n```bash\ncoast build\ncoast run dev-1\n```\n\nVerifica que tu instancia esté en ejecución:\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ~/dev/my-project\n```\n\nMira dónde están escuchando tus servicios:\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\nCada instancia obtiene su propio conjunto de puertos dinámicos para que múltiples instancias puedan ejecutarse en paralelo. Para mapear una instancia de vuelta a los puertos canónicos de tu proyecto, haz checkout de ella:\n\n```bash\ncoast checkout dev-1\n```\n\nEsto significa que el runtime ahora está en checkout y los puertos canónicos de tu proyecto (como `3000`, `5432`) se enrutarán a esta instancia de Coast.\n\n```bash\ncoast ls\n\n# NAME PROJECT STATUS BRANCH RUNTIME WORKTREE CO ROOT\n# dev-1 my-project running main dind - ✓ ~/dev/my-project\n```\n\nPara abrir la UI de observabilidad de Coastguard para tu proyecto:\n\n```bash\ncoast ui\n```\n\n## ¿Qué sigue?\n\n- Configura una [skill para tu agente host](SKILLS_FOR_HOST_AGENTS.md) para que sepa cómo interactuar con Coasts\n", - "SKILLS_FOR_HOST_AGENTS.md": "# Habilidades para agentes host\n\nSi usas agentes de codificación con IA en el host mientras tu aplicación se\nejecuta dentro de Coasts, tu agente normalmente necesita dos piezas de\nconfiguración específicas de Coast:\n\n1. una sección de Coast Runtime siempre activa en el archivo de instrucciones\n del proyecto o archivo de reglas del harness\n2. una habilidad reutilizable de flujo de trabajo de Coast como `/coasts`\n cuando el harness admite habilidades de proyecto\n\nSin la primera pieza, el agente edita archivos pero olvida usar `coast exec`.\nSin la segunda, cada asignación de Coast, registro y flujo de UI tiene que\nvolver a explicarse en el chat.\n\nEsta guía mantiene la configuración concreta y específica de Coast: qué archivo\ncrear, qué texto va en él y cómo cambia según el harness.\n\n## Por qué los agentes necesitan esto\n\nCoasts comparte el [sistema de archivos](concepts_and_terminology/FILESYSTEM.md) entre\ntu máquina host y el contenedor de Coast. Tu agente edita archivos en el host\ny los servicios en ejecución dentro del Coast ven los cambios inmediatamente.\nPero el agente aún necesita:\n\n1. descubrir qué instancia de Coast coincide con el checkout actual\n2. ejecutar pruebas, compilaciones y comandos de runtime dentro de ese Coast\n3. leer registros y estado de servicios desde el Coast\n4. manejar de forma segura la asignación de worktree cuando todavía no hay un Coast adjunto\n\n## Qué va en cada lugar\n\n- `AGENTS.md`, `CLAUDE.md` o `.cursor/rules/coast.md` — reglas cortas de Coast\n que deben aplicarse en cada tarea, incluso si no se invoca ninguna habilidad\n- habilidad (`.agents/skills/...`, `.claude/skills/...` o `.cursor/skills/...`)\n — el propio flujo de trabajo reutilizable de Coast, como `/coasts`\n- archivo de comando (`.claude/commands/...` o `.cursor/commands/...`) — punto\n de entrada explícito opcional para harnesses que lo admiten; una opción\n sencilla es hacer que el comando reutilice la habilidad\n\nSi un repositorio usa más de un harness, mantén la habilidad canónica de Coast\nen un solo lugar y expónla donde sea necesario. Consulta\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md).\n\n## 1. Reglas siempre activas de Coast Runtime\n\nAgrega el siguiente bloque al archivo de instrucciones del proyecto siempre\nactivo del harness o al archivo de reglas (`AGENTS.md`, `CLAUDE.md`,\n`.cursor/rules/coast.md` o equivalente):\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\nEste bloque pertenece al archivo siempre activo porque las reglas deben\naplicarse en cada tarea, no solo cuando el agente entra explícitamente en un\nflujo de trabajo `/coasts`.\n\n## 2. Habilidad reutilizable `/coasts`\n\nCuando el harness admite habilidades de proyecto, guarda el contenido de la\nhabilidad como un `SKILL.md` en tu directorio de habilidades. El texto completo\nde la habilidad está en [skills_prompt.txt](skills_prompt.txt) (si estás en modo CLI, usa\n`coast skills-prompt`) — todo lo que aparece después del bloque Coast Runtime\nes el contenido de la habilidad, comenzando desde el frontmatter `---`.\n\nSi estás usando superficies específicas de Codex u OpenAI, opcionalmente puedes\nagregar `agents/openai.yaml` junto a la habilidad para metadatos de visualización\no política de invocación. Esos metadatos deben vivir junto a la habilidad, no\nreemplazarla.\n\n## Inicio rápido por harness\n\n| Harness | Archivo siempre activo | Flujo de trabajo reutilizable de Coast | Notas |\n|---------|------------------------|----------------------------------------|-------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | No hay un archivo de comando de proyecto separado que recomendar para la documentación de Coast. Consulta [Codex](harnesses/CODEX.md). |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md` es opcional, pero mantén la lógica en la habilidad. Consulta [Claude Code](harnesses/CLAUDE_CODE.md). |\n| Cursor | `AGENTS.md` o `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` o `.agents/skills/coasts/SKILL.md` compartido | `.cursor/commands/coasts.md` es opcional. `.cursor/worktrees.json` es para el bootstrap de worktree de Cursor, no para la política de Coast. Consulta [Cursor](harnesses/CURSOR.md). |\n| Conductor | `CLAUDE.md` | Empieza con `CLAUDE.md`; usa scripts y ajustes de Conductor para comportamiento específico de Conductor | No asumas el comportamiento completo de comandos de proyecto de Claude Code. Si un comando nuevo no aparece, cierra y vuelve a abrir Conductor por completo. Consulta [Conductor](harnesses/CONDUCTOR.md). |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Esta es la superficie de harness más limitada aquí. Usa la disposición estilo Codex y no inventes una capa de comandos nativa de T3 para la documentación de Coast. Consulta [T3 Code](harnesses/T3_CODE.md). |\n\n## Deja que el agente se configure a sí mismo\n\nLa forma más rápida es dejar que el agente escriba por sí mismo los archivos\ncorrectos. Copia el prompt de abajo en el chat de tu agente — incluye el bloque\nde Coast Runtime, el bloque de habilidad `coasts` y las instrucciones\nespecíficas del harness sobre dónde pertenece cada pieza.\n\n```prompt-copy\nskills_prompt.txt\n```\n\nTambién puedes obtener la misma salida desde la CLI ejecutando `coast skills-prompt`.\n\n## Configuración manual\n\n- **Codex:** coloca la sección Coast Runtime en `AGENTS.md`, luego coloca la\n habilidad reutilizable `coasts` en `.agents/skills/coasts/SKILL.md`.\n- **Claude Code:** coloca la sección Coast Runtime en `CLAUDE.md`, luego coloca la\n habilidad reutilizable `coasts` en `.claude/skills/coasts/SKILL.md`. Solo agrega\n `.claude/commands/coasts.md` si específicamente quieres un archivo de comando.\n- **Cursor:** coloca la sección Coast Runtime en `AGENTS.md` si quieres las\n instrucciones más portables, o en `.cursor/rules/coast.md` si quieres una\n regla de proyecto nativa de Cursor. Coloca el flujo de trabajo reutilizable\n `coasts` en `.cursor/skills/coasts/SKILL.md` para un repositorio solo de\n Cursor, o en `.agents/skills/coasts/SKILL.md` si el repositorio se comparte\n con otros harnesses. Solo agrega `.cursor/commands/coasts.md` si\n específicamente quieres un archivo de comando explícito.\n- **Conductor:** coloca la sección Coast Runtime en `CLAUDE.md`. Usa los scripts\n de Repository Settings de Conductor para bootstrap o comportamiento de\n ejecución específicos de Conductor. Si agregas un comando y no aparece,\n cierra y vuelve a abrir por completo la aplicación.\n- **T3 Code:** usa la misma disposición que Codex: `AGENTS.md` más\n `.agents/skills/coasts/SKILL.md`. Trata T3 Code aquí como un harness\n ligero de estilo Codex, no como una superficie separada de comandos de Coast.\n- **Multiple harnesses:** mantén la habilidad canónica en\n `.agents/skills/coasts/SKILL.md`. Cursor puede cargarla directamente; exponla a\n Claude Code mediante `.claude/skills/coasts/` si hace falta.\n\n## Lecturas adicionales\n\n- Lee la [guía de Harnesses](harnesses/README.md) para la matriz por harness\n- Lee [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md) para el patrón de\n disposición compartida\n- Lee la [documentación de Coastfiles](coastfiles/README.md) para aprender el\n esquema completo de configuración\n- Aprende los comandos de la [CLI de Coast](concepts_and_terminology/CLI.md) para gestionar\n instancias\n- Explora [Coastguard](concepts_and_terminology/COASTGUARD.md), la interfaz web para\n observar y controlar tus Coasts\n", + "SKILLS_FOR_HOST_AGENTS.md": "# Habilidades para agentes host\n\nSi usas agentes de codificación con IA en el host mientras tu aplicación se\nejecuta dentro de Coasts, tu agente normalmente necesita dos piezas de\nconfiguración específicas de Coast:\n\n1. una sección de Coast Runtime siempre activa en el archivo de instrucciones\n del proyecto o archivo de reglas del harness\n2. una habilidad reutilizable de flujo de trabajo de Coast como `/coasts`\n cuando el harness admite habilidades de proyecto\n\nSin la primera pieza, el agente edita archivos pero olvida usar `coast exec`.\nSin la segunda, cada asignación de Coast, registro y flujo de UI tiene que\nvolver a explicarse en el chat.\n\nEsta guía mantiene la configuración concreta y específica de Coast: qué archivo\ncrear, qué texto va en él y cómo cambia según el harness.\n\n## Por qué los agentes necesitan esto\n\nCoasts comparte el [sistema de archivos](concepts_and_terminology/FILESYSTEM.md) entre\ntu máquina host y el contenedor de Coast. Tu agente edita archivos en el host\ny los servicios en ejecución dentro del Coast ven los cambios inmediatamente.\nPero el agente aún necesita:\n\n1. descubrir qué instancia de Coast coincide con el checkout actual\n2. ejecutar pruebas, compilaciones y comandos de runtime dentro de ese Coast\n3. leer registros y estado de servicios desde el Coast\n4. manejar de forma segura la asignación de worktree cuando todavía no hay un Coast adjunto\n\n## Qué va en cada lugar\n\n- `AGENTS.md`, `CLAUDE.md` o `.cursor/rules/coast.md` — reglas cortas de Coast\n que deben aplicarse en cada tarea, incluso si no se invoca ninguna habilidad\n- habilidad (`.agents/skills/...`, `.claude/skills/...` o `.cursor/skills/...`)\n — el propio flujo de trabajo reutilizable de Coast, como `/coasts`\n- archivo de comando (`.claude/commands/...` o `.cursor/commands/...`) — punto\n de entrada explícito opcional para harnesses que lo admiten; una opción\n sencilla es hacer que el comando reutilice la habilidad\n\nSi un repositorio usa más de un harness, mantén la habilidad canónica de Coast\nen un solo lugar y expónla donde sea necesario. Consulta\n[Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md).\n\n## 1. Reglas siempre activas de Coast Runtime\n\nAgrega el siguiente bloque al archivo de instrucciones del proyecto siempre\nactivo del harness o al archivo de reglas (`AGENTS.md`, `CLAUDE.md`,\n`.cursor/rules/coast.md` o equivalente):\n\n```text-copy\n# Coast Runtime\n\nThis project uses Coasts — containerized runtimes for running services, tests,\nand other runtime commands. The filesystem is shared between the host and the\ncontainer, so file edits on either side are visible to both immediately.\n\n## Discovery\n\nBefore the first runtime command in a session, run:\n\n coast lookup\n\nThis prints the instance name, ports, and example commands. Use the instance\nname from the output for all subsequent commands.\n\n## What runs where\n\nThe filesystem is shared, so only use `coast exec` for things that need the\ncontainer runtime (databases, services, integration tests). Everything else\nruns directly on the host.\n\nUse `coast exec` for:\n- Tests that need running services (integration tests, API tests)\n- Service restarts or compose operations\n- Anything that talks to databases, caches, or other container services\n\nRun directly on the host:\n- Linting, typechecking, formatting\n- Git operations\n- Playwright and browser tests\n- Installing host-side dependencies (npm install, pip install)\n- File search, code generation, static analysis\n\nExample:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n coast exec --service # service shell\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nIf `coast lookup` returns no match, run `coast ls` to see what exists.\n\nIf an unassigned Coast is already running for this project, prefer assigning\nyour worktree to it rather than creating a new one:\n\n coast assign -w \n\nIf no Coast is running, ask the user before creating one — Coasts can be\nmemory intensive:\n\n coast run -w \n\nA project must be built before instances can be created. If `coast run` fails\nbecause no build exists, run `coast build` first.\n\n## Coastfile setup\n\nIf the project does not have a Coastfile yet, or if you need to modify the\nCoastfile, read the Coastfile docs first:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nBefore guessing about Coast behavior, explore the docs:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Always run `coast lookup` before your first runtime command in a session.\n- Use `coast exec` only for things that need the container runtime.\n- Use `coast exec --service ` when you need to run inside an app/service container.\n- Run linting, typechecking, formatting, and git on the host directly.\n- Use `coast docs` or `coast search-docs` before guessing about Coast behavior.\n- Do not run services directly on the host when the project expects Coast.\n```\n\nEste bloque pertenece al archivo siempre activo porque las reglas deben\naplicarse en cada tarea, no solo cuando el agente entra explícitamente en un\nflujo de trabajo `/coasts`.\n\n## 2. Habilidad reutilizable `/coasts`\n\nCuando el harness admite habilidades de proyecto, guarda el contenido de la\nhabilidad como un `SKILL.md` en tu directorio de habilidades. El texto completo\nde la habilidad está en [skills_prompt.txt](skills_prompt.txt) (si estás en modo CLI, usa\n`coast skills-prompt`) — todo lo que aparece después del bloque Coast Runtime\nes el contenido de la habilidad, comenzando desde el frontmatter `---`.\n\nSi estás usando superficies específicas de Codex u OpenAI, opcionalmente puedes\nagregar `agents/openai.yaml` junto a la habilidad para metadatos de visualización\no política de invocación. Esos metadatos deben vivir junto a la habilidad, no\nreemplazarla.\n\n## Inicio rápido por harness\n\n| Harness | Archivo siempre activo | Flujo de trabajo reutilizable de Coast | Notas |\n|---------|------------------------|----------------------------------------|-------|\n| OpenAI Codex | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | No hay un archivo de comando de proyecto separado que recomendar para la documentación de Coast. Consulta [Codex](harnesses/CODEX.md). |\n| Claude Code | `CLAUDE.md` | `.claude/skills/coasts/SKILL.md` | `.claude/commands/coasts.md` es opcional, pero mantén la lógica en la habilidad. Consulta [Claude Code](harnesses/CLAUDE_CODE.md). |\n| Cursor | `AGENTS.md` o `.cursor/rules/coast.md` | `.cursor/skills/coasts/SKILL.md` o `.agents/skills/coasts/SKILL.md` compartido | `.cursor/commands/coasts.md` es opcional. `.cursor/worktrees.json` es para el bootstrap de worktree de Cursor, no para la política de Coast. Consulta [Cursor](harnesses/CURSOR.md). |\n| Conductor | `CLAUDE.md` | Empieza con `CLAUDE.md`; usa scripts y ajustes de Conductor para comportamiento específico de Conductor | No asumas el comportamiento completo de comandos de proyecto de Claude Code. Si un comando nuevo no aparece, cierra y vuelve a abrir Conductor por completo. Consulta [Conductor](harnesses/CONDUCTOR.md). |\n| T3 Code | `AGENTS.md` | `.agents/skills/coasts/SKILL.md` | Esta es la superficie de harness más limitada aquí. Usa la disposición estilo Codex y no inventes una capa de comandos nativa de T3 para la documentación de Coast. Consulta [T3 Code](harnesses/T3_CODE.md). |\n\n## Deja que el agente se configure a sí mismo\n\nLa forma más rápida es dejar que el agente escriba por sí mismo los archivos\ncorrectos. Copia el prompt de abajo en el chat de tu agente — incluye el bloque\nde Coast Runtime, el bloque de habilidad `coasts` y las instrucciones\nespecíficas del harness sobre dónde pertenece cada pieza.\n\n```prompt-copy\nskills_prompt.txt\n```\n\nTambién puedes obtener la misma salida desde la CLI ejecutando `coast skills-prompt`.\n\n## Configuración manual\n\n- **Codex:** coloca la sección Coast Runtime en `AGENTS.md`, luego coloca la\n habilidad reutilizable `coasts` en `.agents/skills/coasts/SKILL.md`.\n- **Claude Code:** coloca la sección Coast Runtime en `CLAUDE.md`, luego coloca la\n habilidad reutilizable `coasts` en `.claude/skills/coasts/SKILL.md`. Solo agrega\n `.claude/commands/coasts.md` si específicamente quieres un archivo de comando.\n- **Cursor:** coloca la sección Coast Runtime en `AGENTS.md` si quieres las\n instrucciones más portables, o en `.cursor/rules/coast.md` si quieres una\n regla de proyecto nativa de Cursor. Coloca el flujo de trabajo reutilizable\n `coasts` en `.cursor/skills/coasts/SKILL.md` para un repositorio solo de\n Cursor, o en `.agents/skills/coasts/SKILL.md` si el repositorio se comparte\n con otros harnesses. Solo agrega `.cursor/commands/coasts.md` si\n específicamente quieres un archivo de comando explícito.\n- **Conductor:** coloca la sección Coast Runtime en `CLAUDE.md`. Usa los scripts\n de Repository Settings de Conductor para bootstrap o comportamiento de\n ejecución específicos de Conductor. Si agregas un comando y no aparece,\n cierra y vuelve a abrir por completo la aplicación.\n- **T3 Code:** usa la misma disposición que Codex: `AGENTS.md` más\n `.agents/skills/coasts/SKILL.md`. Trata T3 Code aquí como un harness\n ligero de estilo Codex, no como una superficie separada de comandos de Coast.\n- **Multiple harnesses:** mantén la habilidad canónica en\n `.agents/skills/coasts/SKILL.md`. Cursor puede cargarla directamente; exponla a\n Claude Code mediante `.claude/skills/coasts/` si hace falta.\n\n## Lecturas adicionales\n\n- Lee la [guía de Harnesses](harnesses/README.md) para la matriz por harness\n- Lee [Multiple Harnesses](harnesses/MULTIPLE_HARNESSES.md) para el patrón de\n disposición compartida\n- Lee la [documentación de Coastfiles](coastfiles/README.md) para aprender el\n esquema completo de configuración\n- Aprende los comandos de la [CLI de Coast](concepts_and_terminology/CLI.md) para gestionar\n instancias\n- Explora [Coastguard](concepts_and_terminology/COASTGUARD.md), la interfaz web para\n observar y controlar tus Coasts\n", "VIDEO_TUTORIALS.md": "# Tutoriales en video\n\nEsta página recopila los videos oficiales de tutoriales de Coasts del canal de YouTube de Coasts.\n\nSi prefieres un recorrido rápido en video antes de leer el resto de la documentación, comienza con los videos de descripción general y de primeros pasos, y luego pasa a los temas específicos de características a continuación.\n\n## Enlaces\n\n- [Canal de YouTube de Coasts](https://www.youtube.com/@coasts-dev) - El canal oficial para los videos de Coasts.\n- [Lista de reproducción de Coasts](https://www.youtube.com/playlist?list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw) - La lista completa de tutoriales en un solo lugar.\n\n## Videos\n\n- [Descripción general de Coasts](https://www.youtube.com/watch?v=MBGKSKau4sU&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=1&pp=iAQB) (2:42) - Una introducción de alto nivel a qué son Coasts y por qué podrías usarlos.\n- [Coasts](https://www.youtube.com/watch?v=kYlB5U9O92E&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=2&pp=iAQB) (1:29) - Un breve recorrido por el modelo central de Coasts.\n- [Ports](https://www.youtube.com/watch?v=pBKkBiJ3o-g&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=3&pp=iAQB) (1:46) - Cómo Coasts maneja el aislamiento de puertos y el acceso en tiempo de ejecución en paralelo.\n- [Assign](https://www.youtube.com/watch?v=LYCeequ54nk&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=4&pp=iAQB) (1:57) - Cómo cambiar un Coast en ejecución entre worktrees.\n- [Checkout](https://www.youtube.com/watch?v=JRAXkM4U1UE&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=5&pp=iAQB) (1:46) - Cómo traer un Coast a tus puertos canónicos para uso activo.\n- [Volumes](https://www.youtube.com/watch?v=k1es1Wf0zp0&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=6&pp=iAQB) (2:00) - Cómo Coasts gestiona los volúmenes y el estado persistente del servicio.\n- [Secrets](https://www.youtube.com/watch?v=4lAfHUjqn50&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=7&pp=iAQB) (2:09) - Gestión de secretos dentro de un Coast.\n- [Getting Started](https://www.youtube.com/watch?v=Je921fgJ4RY&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=8&pp=iAQB) (2:40) - Un recorrido rápido de incorporación para probar Coasts.\n- [Coast UI](https://www.youtube.com/watch?v=Ts-YWkhHR8I&list=PLplJaH2mu9vQFqnyJHrrls6JU0yt9CUuw&index=9&pp=iAQB0gcJCa4KAYcqIYzv) (1:46) - Un recorrido por la interfaz de Coastguard y la información de tiempo de ejecución que expone.\n\nEsta página refleja el contenido actual de la lista de reproducción oficial y puede actualizarse a medida que se agreguen nuevos videos de tutorial.\n", - "doc_ordering.txt": "# Nivel superior\nREADME.md\nGETTING_STARTED.md\nSKILLS_FOR_HOST_AGENTS.md\n\n# Aprender Coasts\nlearn-coasts-videos/README.md\nlearn-coasts-videos/coasts.md\nlearn-coasts-videos/ports.md\nlearn-coasts-videos/assign.md\nlearn-coasts-videos/checkout.md\nlearn-coasts-videos/volumes.md\nlearn-coasts-videos/secrets.md\nlearn-coasts-videos/getting-started.md\nlearn-coasts-videos/coast-ui.md\n\n# Arneses\nharnesses/README.md\nharnesses/CODEX.md\nharnesses/CONDUCTOR.md\nharnesses/CLAUDE_CODE.md\nharnesses/CURSOR.md\nharnesses/T3_CODE.md\nharnesses/MULTIPLE_HARNESSES.md\n\n# Conceptos y terminología\nconcepts_and_terminology/README.md\nconcepts_and_terminology/COASTS.md\nconcepts_and_terminology/RUN.md\nconcepts_and_terminology/REMOVE.md\nconcepts_and_terminology/FILESYSTEM.md\nconcepts_and_terminology/DAEMON.md\nconcepts_and_terminology/CLI.md\nconcepts_and_terminology/COASTGUARD.md\nconcepts_and_terminology/PORTS.md\nconcepts_and_terminology/PRIMARY_PORT_AND_DNS.md\nconcepts_and_terminology/ASSIGN.md\nconcepts_and_terminology/CHECKOUT.md\nconcepts_and_terminology/LOOKUP.md\nconcepts_and_terminology/VOLUMES.md\nconcepts_and_terminology/SHARED_SERVICES.md\nconcepts_and_terminology/SECRETS.md\nconcepts_and_terminology/BUILDS.md\nconcepts_and_terminology/COASTFILE_TYPES.md\nconcepts_and_terminology/RUNTIMES_AND_SERVICES.md\nconcepts_and_terminology/BARE_SERVICES.md\nconcepts_and_terminology/MIXED_SERVICE_TYPES.md\nconcepts_and_terminology/LOGS.md\nconcepts_and_terminology/EXEC_AND_DOCKER.md\nconcepts_and_terminology/AGENT_SHELLS.md\nconcepts_and_terminology/MCP_SERVERS.md\nconcepts_and_terminology/PERFORMANCE_OPTIMIZATIONS.md\nconcepts_and_terminology/TROUBLESHOOTING.md\n\n# Coastfiles\ncoastfiles/README.md\ncoastfiles/PROJECT.md\ncoastfiles/WORKTREE_DIR.md\ncoastfiles/PORTS.md\ncoastfiles/SHARED_SERVICES.md\ncoastfiles/SERVICES.md\ncoastfiles/SECRETS.md\ncoastfiles/VOLUMES.md\ncoastfiles/ASSIGN.md\ncoastfiles/INHERITANCE.md\ncoastfiles/AGENT_SHELL.md\ncoastfiles/MCP.md\n\n# Recetas\nrecipes/README.md\nrecipes/FULLSTACK_MONOREPO.md\n", - "installation_prompt.txt": "Estás instalando Coasts en este proyecto. Coast (host en contenedores) es una herramienta CLI que ejecuta múltiples entornos de desarrollo aislados en una sola máquina usando contenedores Docker-in-Docker. Cada entorno obtiene sus propios puertos, volúmenes y runtime — ideal para flujos de trabajo paralelos con worktrees.\n\nTu trabajo: analizar este proyecto y generar un Coastfile (un archivo TOML llamado \"Coastfile\" en la raíz del proyecto).\n\n=== DOCUMENTACIÓN ===\n\nCoast tiene documentación integrada accesible desde la CLI. Úsala para entender el esquema completo de Coastfile, estrategias de volúmenes, comportamiento de assign y otras opciones de configuración antes de generar un Coastfile.\n\nNavega el árbol de documentación:\n\n coast docs\n\nEsto imprime el árbol completo de documentación. Empieza leyendo los archivos README — proporcionan índices para ayudarte a encontrar la documentación correcta para cada tema:\n\n coast docs --path README.md\n coast docs --path coastfiles/README.md\n coast docs --path concepts_and_terminology/README.md\n\nLee un documento específico:\n\n coast docs --path coastfiles/PROJECT.md\n coast docs --path coastfiles/VOLUMES.md\n\nBusca en la documentación (búsqueda semántica — describe lo que buscas en lenguaje natural):\n\n coast search-docs \"how do volume strategies work\"\n coast search-docs \"shared postgres across instances\"\n coast search-docs \"secret injection from environment variables\"\n\nUsa la documentación para tomar decisiones informadas sobre la configuración del Coastfile de este proyecto. La sección coastfiles/ cubre cada directiva de Coastfile en detalle.\n\n=== ESQUEMA DE COASTFILE (referencia rápida) ===\n\n[coast] — Requerido. Metadatos del proyecto.\n\n name (string, requerido) Identificador del proyecto usado en el nombrado de contenedores/volúmenes.\n compose (string, opcional) Ruta a docker-compose.yml relativa al Coastfile.\n runtime (string, opcional) \"dind\" (predeterminado), \"sysbox\" o \"podman\".\n root (string, opcional) Anulación de la raíz del proyecto (relativa o absoluta).\n worktree_dir (string, opcional) Directorio para git worktrees (predeterminado: \".worktrees\"). Se detecta automáticamente a partir de worktrees existentes en tiempo de ejecución.\n\n[coast.setup] — Opcional. Personaliza el contenedor DinD en sí.\n\n packages (array of strings) Paquetes de Alpine a instalar (p. ej. [\"nodejs\", \"npm\", \"git\"]).\n run (array of strings) Comandos arbitrarios a ejecutar durante la configuración.\n\n[ports] — Requerido (al menos uno). Mapa de nombre lógico a número de puerto.\n Estos puertos se reenvían al host cuando se hace checkout del coast.\n\n Ejemplo:\n [ports]\n web = 3000\n api = 8080\n postgres = 5432\n\n[volumes.*] — Opcional. Configuración por volumen.\n\n strategy \"isolated\" (predeterminado) o \"shared\"\n service Nombre del servicio de Compose que posee este volumen.\n mount Ruta de montaje dentro del contenedor del servicio.\n snapshot_source (solo isolated) Semilla desde un nombre de volumen existente.\n\n Ejemplo:\n [volumes.postgres_data]\n strategy = \"isolated\"\n service = \"db\"\n mount = \"/var/lib/postgresql/data\"\n\n[secrets.*] — Opcional. Extracción e inyección de secretos.\n\n extractor \"file\", \"env\", \"command\" o \"macos-keychain\"\n inject \"env:VAR_NAME\" o \"file:/path/in/container\"\n ttl Caducidad opcional (p. ej. \"1h\", \"30m\").\n\n Parámetros específicos del extractor:\n file: path = \"./path/to/secret\"\n env: var = \"HOST_ENV_VAR\"\n command: run = \"echo secret-value\"\n macos-keychain: item = \"keychain-item-name\"\n\n Ejemplo:\n [secrets.db_password]\n extractor = \"env\"\n var = \"DB_PASSWORD\"\n inject = \"env:DATABASE_PASSWORD\"\n\n[inject] — Opcional. Inyección de archivos/env del host no secretos.\n\n env Array de nombres de variables de entorno del host a reenviar.\n files Array de rutas de archivos del host a montar.\n\n Ejemplo:\n [inject]\n env = [\"NODE_ENV\", \"DEBUG\"]\n files = [\"~/.ssh/id_ed25519\", \"~/.gitconfig\"]\n\n[shared_services.*] — Opcional. Servicios en el daemon de Docker del host compartidos entre instancias.\n\n image Imagen de Docker.\n ports Array de números de puerto.\n volumes Array de montajes de volumen.\n env Tabla inline de variables de entorno.\n auto_create_db (bool) Crea automáticamente una base de datos por instancia.\n inject Inyecta la cadena de conexión en los contenedores de coast.\n\n Ejemplo:\n [shared_services.postgres]\n image = \"postgres:16-alpine\"\n ports = [5432]\n volumes = [\"postgres_data:/var/lib/postgresql/data\"]\n env = { POSTGRES_USER = \"dev\", POSTGRES_PASSWORD = \"dev\", POSTGRES_DB = \"app\" }\n auto_create_db = true\n inject = \"env:DATABASE_URL\"\n\n[assign] — Opcional. Controla lo que ocurre al cambiar de rama (coast assign).\n\n default \"none\", \"restart\" o \"rebuild\"\n [assign.services] Anulaciones por servicio.\n [assign.rebuild_triggers] Globs de archivos por servicio que disparan rebuild.\n\n Ejemplo:\n [assign]\n default = \"none\"\n [assign.services]\n api = \"restart\"\n worker = \"rebuild\"\n [assign.rebuild_triggers]\n worker = [\"Dockerfile\", \"package.json\"]\n\n[services.*] — Opcional. Servicios de proceso “bare” (no se necesita docker-compose).\n\n command Comando de shell a ejecutar.\n port Número de puerto.\n restart \"on-failure\" o \"always\".\n\n Ejemplo:\n [services.web]\n command = \"node server.js\"\n port = 3000\n restart = \"on-failure\"\n\n=== EJEMPLO: Mínimo (sin compose) ===\n\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[ports]\napp = 3000\n\n=== EJEMPLO: Con docker-compose ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\npostgres = 5432\nredis = 6379\n\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n\n=== EJEMPLO: Con secretos ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\n\n[secrets.api_key]\nextractor = \"env\"\nvar = \"API_KEY\"\ninject = \"env:API_KEY\"\n\n[secrets.ssh_key]\nextractor = \"file\"\npath = \"~/.ssh/id_ed25519\"\ninject = \"file:/run/secrets/ssh_key\"\n\n=== PUNTOS CLAVE A DISCUTIR CON EL USUARIO ===\n\nAntes de generar el Coastfile, pregunta al usuario sobre cualquier elección de configuración ambigua. Estas son las principales:\n\nEstrategia de base de datos e infraestructura — hay tres opciones para servicios como postgres y redis:\n - Volúmenes aislados (predeterminado): cada instancia de Coast obtiene su propia copia de los datos dentro de su contenedor DinD. Las instancias no pueden interferir entre sí. Lo mejor cuando quieres estado de base de datos por rama.\n - Volúmenes compartidos: todas las instancias leen y escriben el mismo volumen dentro de sus contenedores DinD. Ahorra espacio en disco, pero escrituras concurrentes desde múltiples instancias pueden corromper los datos.\n - Servicios compartidos: ejecuta la base de datos en el daemon de Docker del host en lugar de dentro de cada Coast. Todas las instancias se conectan a un servidor compartido. Usa la menor memoria, admite auto_create_db para bases de datos por instancia en un único postgres, y los datos sobreviven a la eliminación de instancias. Lo mejor para equipos grandes o máquinas con memoria limitada.\n - Si el proyecto tiene una base de datos, pregunta al usuario qué enfoque quiere. Explica los tradeoffs — aislado es lo más seguro, servicios compartidos es lo más eficiente en memoria.\n\nEstrategia de assign — qué ocurre al cambiar un Coast entre worktrees:\n - \"none\": no hacer nada (para servicios como postgres/redis que no cambian entre ramas).\n - \"restart\": reiniciar el contenedor (para servicios interpretados que solo necesitan reinicio del proceso).\n - \"rebuild\": reconstruir la imagen de Docker y reiniciar (para servicios donde el cambio de rama afecta al Dockerfile o a dependencias de build).\n - Si el proyecto tiene múltiples servicios, pregunta cuáles necesitan rebuild vs restart al cambiar de rama.\n\n=== INSTRUCCIONES ===\n\n1. Mira la estructura de este proyecto. Si hay un docker-compose.yml, léelo para identificar servicios, puertos y volúmenes.\n2. Detecta el directorio de git worktree existente. Ejecuta `git worktree list` para comprobar si el proyecto ya tiene git worktrees configurados.\n - Si existen worktrees, examina sus rutas para determinar el directorio padre común (p. ej., si los worktrees están en `../.worktrees/feat-a` y `../.worktrees/feat-b`, el worktree_dir es `\"../.worktrees\"`).\n - Establece `worktree_dir` en el Coastfile para que coincida con el directorio detectado.\n - Si no existen worktrees, omite `worktree_dir` (Coast usa por defecto \".worktrees\"). NO uses \".coasts\" — eso contamina el proyecto con un directorio con marca de Coast.\n3. Lee la documentación relevante de Coast (usa `coast docs` y `coast search-docs`) para entender estrategias de volúmenes, comportamiento de assign y cualquier opción de configuración que aplique al stack de este proyecto.\n4. Pregunta al usuario sobre cualquier elección de configuración ambigua (ver puntos clave arriba). No adivines — explica las opciones y deja que decidan.\n5. Genera un Coastfile en la raíz del proyecto basado en el análisis del proyecto y la entrada del usuario.\n6. Si el proyecto no tiene docker-compose.yml, usa [services.*] para definiciones de procesos “bare” o [coast.setup] para instalar dependencias.\n7. Ejecuta `coast build`. Si falla, revisa el error y consulta la documentación (`coast search-docs \"\"`) para solucionar problemas.\n8. Ejecuta `coast run dev-1`. Si falla, revisa el error y consulta la documentación.\n9. Ejecuta `coast ui` para abrir el panel de Coastguard (esto es para el usuario cuando hayas terminado).\n", - "skills_prompt.txt": "# Coast Runtime\n\nEste proyecto usa Coasts — runtimes en contenedores para ejecutar servicios, pruebas\ny otros comandos de runtime. El sistema de archivos se comparte entre el host y el\ncontenedor, por lo que las ediciones de archivos en cualquiera de los dos lados son visibles\npara ambos de inmediato.\n\n## Discovery\n\nAntes del primer comando de runtime en una sesión, ejecuta:\n\n coast lookup\n\nEsto imprime el nombre de la instancia, los puertos y comandos de ejemplo. Usa el nombre\nde la instancia de la salida para todos los comandos posteriores.\n\n## What runs where\n\nEl sistema de archivos se comparte, así que usa `coast exec` solo para las cosas que necesitan\nel runtime del contenedor (bases de datos, servicios, pruebas de integración). Todo lo demás\nse ejecuta directamente en el host.\n\nUsa `coast exec` para:\n- Pruebas que necesitan servicios en ejecución (pruebas unitarias integradas con servicios o dbs, pruebas de integración, pruebas de API)\n- Reinicios de servicios u operaciones de compose\n- Cualquier cosa que se comunique con bases de datos, cachés u otros servicios del contenedor\n\nEjecuta directamente en el host:\n- Linting, verificación de tipos, formateo\n- Operaciones de Git\n- Playwright y pruebas de navegador\n- Instalar dependencias del lado del host (npm install, pip install)\n- Búsqueda de archivos, generación de código, análisis estático\n\nEjemplo:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nSi `coast lookup` no devuelve ninguna coincidencia, ejecuta `coast ls` para ver qué existe.\n\nSi ya hay un Coast sin asignar en ejecución para este proyecto, prefiere asignarle\ntu worktree en lugar de crear uno nuevo:\n\n coast assign -w \n\nUn Coast ya ocupado también puede reasignarse con `coast assign`, pero primero consúltalo\ncon el usuario porque eso interrumpirá el slot actual.\n\nSi no hay ningún Coast en ejecución, pregunta al usuario antes de crear uno — los Coasts\npueden consumir mucha memoria:\n\n coast run -w \n\nUn proyecto debe compilarse antes de que se puedan crear instancias. Si `coast run` falla\nporque no existe ninguna compilación, ejecuta primero `coast build`.\n\n## Coastfile setup\n\nSi el proyecto todavía no tiene un Coastfile, o si necesitas modificar el\nCoastfile, primero lee la documentación del Coastfile:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nAntes de hacer suposiciones sobre el comportamiento de Coast, explora la documentación:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Ejecuta siempre `coast lookup` antes de tu primer comando de runtime en una sesión.\n- Usa `coast exec` solo para las cosas que necesitan el runtime del contenedor.\n- Ejecuta linting, verificación de tipos, formateo y git directamente en el host.\n- Usa `coast docs` o `coast search-docs` antes de hacer suposiciones sobre el comportamiento de Coast.\n- No ejecutes servicios directamente en el host cuando el proyecto espera Coast.\n\n---\nname: coasts\ndescription: Inspect and control Coast instances for the current checkout. Use\n when the user says \"/coasts\", asks to assign or reassign a Coast, wants to\n run commands or read logs in the matching Coast, wants to create a new Coast,\n or explicitly asks to open Coast UI.\n---\n\n# Coasts\n\nUsa directamente el CLI de Coast. No añadas wrappers.\n\n## Orient Yourself\n\nEmpieza explorando el CLI y la documentación:\n\n coast # see all available commands\n coast docs # list all doc pages\n coast search-docs \"your question\" # semantic search\n\nCuando algo sobre el comportamiento de Coast no esté claro, lee la documentación antes de hacer suposiciones:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\nEnruta las solicitudes a uno de estos modos:\n\n1. **Usar Coast** — ejecuta `coast lookup`, luego usa `coast exec`, `coast ps`\n o `coast logs` con la instancia correspondiente.\n2. **Crear o asignar** — ejecuta `coast ls`, luego `coast run` para crear un nuevo\n Coast o `coast assign` para reapuntar uno existente.\n3. **Abrir UI** — ejecuta `coast ui`.\n\n## What Runs Where\n\nEl host y el Coast comparten el sistema de archivos. Usa `coast exec` solo para las cosas\nque necesitan servicios en ejecución dentro del contenedor.\n\n**Usa `coast exec` para:**\n- Pruebas de integración, pruebas de API, cualquier cosa que necesite bases de datos o servicios\n- Reinicios de servicios, operaciones de compose\n- Comandos que se comuniquen con procesos solo disponibles en el contenedor\n\n**Ejecuta en el host:**\n- Linting (`eslint`, `rubocop`, `golangci-lint`)\n- Verificación de tipos (`tsc --noEmit`, `go vet`)\n- Formateo (`prettier`, `gofmt`)\n- Operaciones de Git\n- Playwright y pruebas de navegador\n- Análisis estático, generación de código\n- Instalación de paquetes (`npm install`, `pip install`)\n\n## Create and Assign\n\nCuando `coast lookup` no devuelve ninguna coincidencia:\n\n1. Ejecuta `coast ls` para ver los slots disponibles.\n2. Prefiere `coast run -w ` para crear y asignar en un solo paso.\n3. Si todavía no existe ninguna compilación, ejecuta primero `coast build`.\n4. Después de crear, vuelve a ejecutar `coast lookup` para confirmar.\n\nCuando quieras cambiar un Coast existente a un worktree diferente:\n\n coast assign -w \n\nEso también funciona para un Coast ya asignado o ya checked-out, pero consulta primero\ncon el usuario antes de reasignar un slot ocupado.\n\n## Coastfile Setup\n\nSi el proyecto necesita un Coastfile nuevo o modificado, primero lee la documentación:\n\n coast docs --path coastfiles/README.md\n\nLa documentación del Coastfile cubre la configuración de compose, puertos, volúmenes, secretos,\nservicios compartidos, servicios sin contenedor auxiliar y herencia.\n\n## Safety Rules\n\n- Ejecuta `coast lookup` antes de actuar y de nuevo después de cualquier cambio de topología.\n- Pregunta antes de `coast assign`, `coast unassign` o `coast checkout` si eso fuera a\n interrumpir un slot existente.\n- Prefiere crear un nuevo Coast en lugar de reutilizar uno ya checked-out o ya asignado,\n a menos que el usuario quiera explícitamente que se reasigne el slot existente.\n- Usa `coast docs` o `coast search-docs` antes de hacer suposiciones.\n", + "doc_ordering.txt": "# Nivel superior\nREADME.md\nGETTING_STARTED.md\nSKILLS_FOR_HOST_AGENTS.md\n\n# Aprender Coasts\nlearn-coasts-videos/README.md\nlearn-coasts-videos/coasts.md\nlearn-coasts-videos/ports.md\nlearn-coasts-videos/assign.md\nlearn-coasts-videos/checkout.md\nlearn-coasts-videos/volumes.md\nlearn-coasts-videos/secrets.md\nlearn-coasts-videos/getting-started.md\nlearn-coasts-videos/coast-ui.md\n\n# Arneses\nharnesses/README.md\nharnesses/CODEX.md\nharnesses/CONDUCTOR.md\nharnesses/CLAUDE_CODE.md\nharnesses/CURSOR.md\nharnesses/T3_CODE.md\nharnesses/SHEP.md\nharnesses/MULTIPLE_HARNESSES.md\n\n# Conceptos y terminología\nconcepts_and_terminology/README.md\nconcepts_and_terminology/COASTS.md\nconcepts_and_terminology/RUN.md\nconcepts_and_terminology/REMOVE.md\nconcepts_and_terminology/FILESYSTEM.md\nconcepts_and_terminology/DAEMON.md\nconcepts_and_terminology/CLI.md\nconcepts_and_terminology/COASTGUARD.md\nconcepts_and_terminology/PORTS.md\nconcepts_and_terminology/PRIMARY_PORT_AND_DNS.md\nconcepts_and_terminology/ASSIGN.md\nconcepts_and_terminology/CHECKOUT.md\nconcepts_and_terminology/LOOKUP.md\nconcepts_and_terminology/VOLUMES.md\nconcepts_and_terminology/SHARED_SERVICES.md\nconcepts_and_terminology/SECRETS.md\nconcepts_and_terminology/BUILDS.md\nconcepts_and_terminology/COASTFILE_TYPES.md\nconcepts_and_terminology/RUNTIMES_AND_SERVICES.md\nconcepts_and_terminology/BARE_SERVICES.md\nconcepts_and_terminology/MIXED_SERVICE_TYPES.md\nconcepts_and_terminology/LOGS.md\nconcepts_and_terminology/EXEC_AND_DOCKER.md\nconcepts_and_terminology/AGENT_SHELLS.md\nconcepts_and_terminology/MCP_SERVERS.md\nconcepts_and_terminology/PERFORMANCE_OPTIMIZATIONS.md\nconcepts_and_terminology/TROUBLESHOOTING.md\n\n# Coastfiles\ncoastfiles/README.md\ncoastfiles/PROJECT.md\ncoastfiles/WORKTREE_DIR.md\ncoastfiles/PORTS.md\ncoastfiles/SHARED_SERVICES.md\ncoastfiles/SERVICES.md\ncoastfiles/SECRETS.md\ncoastfiles/VOLUMES.md\ncoastfiles/ASSIGN.md\ncoastfiles/INHERITANCE.md\ncoastfiles/AGENT_SHELL.md\ncoastfiles/MCP.md\n\n# Recetas\nrecipes/README.md\nrecipes/FULLSTACK_MONOREPO.md\n", + "installation_prompt.txt": "Estás instalando Coasts en este proyecto. Coast (host en contenedores) es una herramienta CLI que ejecuta múltiples entornos de desarrollo aislados en una sola máquina usando contenedores Docker-in-Docker. Cada entorno obtiene sus propios puertos, volúmenes y runtime — ideal para flujos de trabajo paralelos con worktrees.\n\nTu trabajo: analizar este proyecto y generar un Coastfile (un archivo TOML llamado \"Coastfile\" en la raíz del proyecto).\n\n=== DOCUMENTACIÓN ===\n\nCoast tiene documentación integrada accesible desde la CLI. Úsala para entender el esquema completo de Coastfile, estrategias de volúmenes, comportamiento de assign y otras opciones de configuración antes de generar un Coastfile.\n\nNavega el árbol de documentación:\n\n coast docs\n\nEsto imprime el árbol completo de documentación. Empieza leyendo los archivos README — proporcionan índices para ayudarte a encontrar la documentación correcta para cada tema:\n\n coast docs --path README.md\n coast docs --path coastfiles/README.md\n coast docs --path concepts_and_terminology/README.md\n\nLee un documento específico:\n\n coast docs --path coastfiles/PROJECT.md\n coast docs --path coastfiles/VOLUMES.md\n\nBusca en la documentación (búsqueda semántica — describe lo que buscas en lenguaje natural):\n\n coast search-docs \"how do volume strategies work\"\n coast search-docs \"shared postgres across instances\"\n coast search-docs \"secret injection from environment variables\"\n\nUsa la documentación para tomar decisiones informadas sobre la configuración del Coastfile de este proyecto. La sección coastfiles/ cubre cada directiva de Coastfile en detalle.\n\n=== ESQUEMA DE COASTFILE (referencia rápida) ===\n\n[coast] — Requerido. Metadatos del proyecto.\n\n name (string, requerido) Identificador del proyecto usado en el nombrado de contenedores/volúmenes.\n compose (string, opcional) Ruta a docker-compose.yml relativa al Coastfile.\n runtime (string, opcional) \"dind\" (predeterminado), \"sysbox\" o \"podman\".\n root (string, opcional) Anulación de la raíz del proyecto (relativa o absoluta).\n worktree_dir (string o array, opcional) Directorio o directorios para git worktrees (predeterminado: \".worktrees\"). Acepta un único string o un array de strings. Se detecta automáticamente a partir de worktrees existentes en tiempo de ejecución.\n\n[coast.setup] — Opcional. Personaliza el contenedor DinD en sí.\n\n packages (array of strings) Paquetes de Alpine a instalar (p. ej. [\"nodejs\", \"npm\", \"git\"]).\n run (array of strings) Comandos arbitrarios a ejecutar durante la configuración.\n\n[ports] — Requerido (al menos uno). Mapa de nombre lógico a número de puerto.\n Estos puertos se reenvían al host cuando se hace checkout del coast.\n\n Ejemplo:\n [ports]\n web = 3000\n api = 8080\n postgres = 5432\n\n[volumes.*] — Opcional. Configuración por volumen.\n\n strategy \"isolated\" (predeterminado) o \"shared\"\n service Nombre del servicio de Compose que posee este volumen.\n mount Ruta de montaje dentro del contenedor del servicio.\n snapshot_source (solo isolated) Semilla desde un nombre de volumen existente.\n\n Ejemplo:\n [volumes.postgres_data]\n strategy = \"isolated\"\n service = \"db\"\n mount = \"/var/lib/postgresql/data\"\n\n[secrets.*] — Opcional. Extracción e inyección de secretos.\n\n extractor \"file\", \"env\", \"command\" o \"macos-keychain\"\n inject \"env:VAR_NAME\" o \"file:/path/in/container\"\n ttl Caducidad opcional (p. ej. \"1h\", \"30m\").\n\n Parámetros específicos del extractor:\n file: path = \"./path/to/secret\"\n env: var = \"HOST_ENV_VAR\"\n command: run = \"echo secret-value\"\n macos-keychain: item = \"keychain-item-name\"\n\n Ejemplo:\n [secrets.db_password]\n extractor = \"env\"\n var = \"DB_PASSWORD\"\n inject = \"env:DATABASE_PASSWORD\"\n\n[inject] — Opcional. Inyección de archivos/env del host no secretos.\n\n env Array de nombres de variables de entorno del host a reenviar.\n files Array de rutas de archivos del host a montar.\n\n Ejemplo:\n [inject]\n env = [\"NODE_ENV\", \"DEBUG\"]\n files = [\"~/.ssh/id_ed25519\", \"~/.gitconfig\"]\n\n[shared_services.*] — Opcional. Servicios en el daemon de Docker del host compartidos entre instancias.\n\n image Imagen de Docker.\n ports Array de números de puerto.\n volumes Array de montajes de volumen.\n env Tabla inline de variables de entorno.\n auto_create_db (bool) Crea automáticamente una base de datos por instancia.\n inject Inyecta la cadena de conexión en los contenedores de coast.\n\n Ejemplo:\n [shared_services.postgres]\n image = \"postgres:16-alpine\"\n ports = [5432]\n volumes = [\"postgres_data:/var/lib/postgresql/data\"]\n env = { POSTGRES_USER = \"dev\", POSTGRES_PASSWORD = \"dev\", POSTGRES_DB = \"app\" }\n auto_create_db = true\n inject = \"env:DATABASE_URL\"\n\n[assign] — Opcional. Controla lo que ocurre al cambiar de rama (coast assign).\n\n default \"none\", \"restart\" o \"rebuild\"\n [assign.services] Anulaciones por servicio.\n [assign.rebuild_triggers] Globs de archivos por servicio que disparan rebuild.\n\n Ejemplo:\n [assign]\n default = \"none\"\n [assign.services]\n api = \"restart\"\n worker = \"rebuild\"\n [assign.rebuild_triggers]\n worker = [\"Dockerfile\", \"package.json\"]\n\n[services.*] — Opcional. Servicios de proceso “bare” (no se necesita docker-compose).\n\n command Comando de shell a ejecutar.\n port Número de puerto.\n restart \"on-failure\" o \"always\".\n\n Ejemplo:\n [services.web]\n command = \"node server.js\"\n port = 3000\n restart = \"on-failure\"\n\n=== EJEMPLO: Mínimo (sin compose) ===\n\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[ports]\napp = 3000\n\n=== EJEMPLO: Con docker-compose ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\npostgres = 5432\nredis = 6379\n\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n\n=== EJEMPLO: Con secretos ===\n\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nruntime = \"dind\"\n\n[ports]\napp = 3000\n\n[secrets.api_key]\nextractor = \"env\"\nvar = \"API_KEY\"\ninject = \"env:API_KEY\"\n\n[secrets.ssh_key]\nextractor = \"file\"\npath = \"~/.ssh/id_ed25519\"\ninject = \"file:/run/secrets/ssh_key\"\n\n=== PUNTOS CLAVE A DISCUTIR CON EL USUARIO ===\n\nAntes de generar el Coastfile, pregunta al usuario sobre cualquier elección de configuración ambigua. Estas son las principales:\n\nEstrategia de base de datos e infraestructura — hay tres opciones para servicios como postgres y redis:\n - Volúmenes aislados (predeterminado): cada instancia de Coast obtiene su propia copia de los datos dentro de su contenedor DinD. Las instancias no pueden interferir entre sí. Lo mejor cuando quieres estado de base de datos por rama.\n - Volúmenes compartidos: todas las instancias leen y escriben el mismo volumen dentro de sus contenedores DinD. Ahorra espacio en disco, pero escrituras concurrentes desde múltiples instancias pueden corromper los datos.\n - Servicios compartidos: ejecuta la base de datos en el daemon de Docker del host en lugar de dentro de cada Coast. Todas las instancias se conectan a un servidor compartido. Usa la menor memoria, admite auto_create_db para bases de datos por instancia en un único postgres, y los datos sobreviven a la eliminación de instancias. Lo mejor para equipos grandes o máquinas con memoria limitada.\n - Si el proyecto tiene una base de datos, pregunta al usuario qué enfoque quiere. Explica los tradeoffs — aislado es lo más seguro, servicios compartidos es lo más eficiente en memoria.\n\nEstrategia de assign — qué ocurre al cambiar un Coast entre worktrees:\n - \"none\": no hacer nada (para servicios como postgres/redis que no cambian entre ramas).\n - \"restart\": reiniciar el contenedor (para servicios interpretados que solo necesitan reinicio del proceso).\n - \"rebuild\": reconstruir la imagen de Docker y reiniciar (para servicios donde el cambio de rama afecta al Dockerfile o a dependencias de build).\n - Si el proyecto tiene múltiples servicios, pregunta cuáles necesitan rebuild vs restart al cambiar de rama.\n\n=== INSTRUCCIONES ===\n\n1. Mira la estructura de este proyecto. Si hay un docker-compose.yml, léelo para identificar servicios, puertos y volúmenes.\n2. Detecta el directorio de git worktree existente. Ejecuta `git worktree list` para comprobar si el proyecto ya tiene git worktrees configurados.\n - Si existen worktrees, examina sus rutas para determinar el directorio padre común (p. ej., si los worktrees están en `../.worktrees/feat-a` y `../.worktrees/feat-b`, el worktree_dir es `\"../.worktrees\"`).\n - Establece `worktree_dir` en el Coastfile para que coincida con el directorio detectado.\n - Si no existen worktrees, omite `worktree_dir` (Coast usa por defecto \".worktrees\"). NO uses \".coasts\" — eso contamina el proyecto con un directorio con marca de Coast.\n3. Pregunta al usuario si usa alguno de estos harnesses de programación con este proyecto:\n - **Claude Code** — worktrees en `.claude/worktrees`\n - **OpenAI Codex** — worktrees en `~/.codex/worktrees`\n - **Cursor** — worktrees en `~/.cursor/worktrees/` (donde `` es el nombre de coast de `[coast] name`)\n - **Conductor** — worktrees en `~/conductor/workspaces/`\n - **T3 Code** — worktrees en `~/.t3/worktrees/`\n Para cada harness que el usuario seleccione, incluye su directorio de worktrees en el array `worktree_dir`. Combínalos con cualquier directorio detectado en el paso 2. Si el usuario no selecciona ninguno y no se detectaron worktrees en el paso 2, omite `worktree_dir` (Coast usa por defecto \".worktrees\").\n4. Lee la documentación relevante de Coast (usa `coast docs` y `coast search-docs`) para entender estrategias de volúmenes, comportamiento de assign y cualquier opción de configuración que aplique al stack de este proyecto.\n5. Pregunta al usuario sobre cualquier elección de configuración ambigua (ver puntos clave arriba). No adivines — explica las opciones y deja que decidan.\n6. Genera un Coastfile en la raíz del proyecto basado en el análisis del proyecto y la entrada del usuario.\n7. Si el proyecto no tiene docker-compose.yml, usa [services.*] para definiciones de procesos “bare” o [coast.setup] para instalar dependencias.\n8. Ejecuta `coast build`. Si falla, revisa el error y consulta la documentación (`coast search-docs \"\"`) para solucionar problemas.\n9. Ejecuta `coast run dev-1`. Si falla, revisa el error y consulta la documentación.\n10. Ejecuta `coast ui` para abrir el panel de Coastguard (esto es para el usuario cuando hayas terminado).\n", + "skills_prompt.txt": "# Coast Runtime\n\nEste proyecto usa Coasts — runtimes en contenedores para ejecutar servicios, pruebas\ny otros comandos de runtime. El sistema de archivos se comparte entre el host y el\ncontenedor, por lo que las ediciones de archivos en cualquiera de los dos lados son visibles\npara ambos de inmediato.\n\n## Discovery\n\nAntes del primer comando de runtime en una sesión, ejecuta:\n\n coast lookup\n\nEsto imprime el nombre de la instancia, los puertos y comandos de ejemplo. Usa el nombre\nde la instancia de la salida para todos los comandos posteriores.\n\n## What runs where\n\nEl sistema de archivos se comparte, así que usa `coast exec` solo para las cosas que necesitan\nel runtime del contenedor (bases de datos, servicios, pruebas de integración). Todo lo demás\nse ejecuta directamente en el host.\n\nUsa `coast exec` para:\n- Pruebas que necesitan servicios en ejecución (pruebas unitarias integradas con servicios o dbs, pruebas de integración, pruebas de API)\n- Reinicios de servicios u operaciones de compose\n- Cualquier cosa que se comunique con bases de datos, cachés u otros servicios del contenedor\n\nEjecuta directamente en el host:\n- Linting, verificación de tipos, formateo\n- Operaciones de Git\n- Playwright y pruebas de navegador\n- Instalar dependencias del lado del host (npm install, pip install)\n- Búsqueda de archivos, generación de código, análisis estático\n\nEjemplo:\n\n coast exec -- sh -c \"cd && npm test\" # needs DB\n coast exec --service # service shell\n npm run lint # host is fine\n npx playwright test # host is fine\n\n## Runtime feedback\n\n coast ps \n coast logs --service \n coast logs --service --tail 50\n\n## Creating and assigning Coasts\n\nSi `coast lookup` no devuelve ninguna coincidencia, ejecuta `coast ls` para ver qué existe.\n\nSi ya hay un Coast sin asignar en ejecución para este proyecto, prefiere asignarle\ntu worktree en lugar de crear uno nuevo:\n\n coast assign -w \n\nUn Coast ya ocupado también puede reasignarse con `coast assign`, pero primero consúltalo\ncon el usuario porque eso interrumpirá el slot actual.\n\nSi no hay ningún Coast en ejecución, pregunta al usuario antes de crear uno — los Coasts\npueden consumir mucha memoria:\n\n coast run -w \n\nUn proyecto debe compilarse antes de que se puedan crear instancias. Si `coast run` falla\nporque no existe ninguna compilación, ejecuta primero `coast build`.\n\n## Coastfile setup\n\nSi el proyecto todavía no tiene un Coastfile, o si necesitas modificar el\nCoastfile, primero lee la documentación del Coastfile:\n\n coast docs --path coastfiles/README.md\n\n## When confused\n\nAntes de hacer suposiciones sobre el comportamiento de Coast, explora la documentación:\n\n coast docs # list all doc pages\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast search-docs \"your question here\" # semantic search\n\n## Rules\n\n- Ejecuta siempre `coast lookup` antes de tu primer comando de runtime en una sesión.\n- Usa `coast exec` solo para las cosas que necesitan el runtime del contenedor.\n- Usa `coast exec --service ` cuando necesites ejecutar algo dentro de un contenedor de app/servicio.\n- Ejecuta linting, verificación de tipos, formateo y git directamente en el host.\n- Usa `coast docs` o `coast search-docs` antes de hacer suposiciones sobre el comportamiento de Coast.\n- No ejecutes servicios directamente en el host cuando el proyecto espera Coast.\n\n---\nname: coasts\ndescription: Inspect and control Coast instances for the current checkout. Use\n when the user says \"/coasts\", asks to assign or reassign a Coast, wants to\n run commands or read logs in the matching Coast, wants to create a new Coast,\n or explicitly asks to open Coast UI.\n---\n\n# Coasts\n\nUsa directamente el CLI de Coast. No añadas wrappers.\n\n## Orient Yourself\n\nEmpieza explorando el CLI y la documentación:\n\n coast # see all available commands\n coast docs # list all doc pages\n coast search-docs \"your question\" # semantic search\n\nCuando algo sobre el comportamiento de Coast no esté claro, lee la documentación antes de hacer suposiciones:\n\n coast docs --path concepts_and_terminology/RUN.md\n coast docs --path concepts_and_terminology/BUILDS.md\n coast docs --path concepts_and_terminology/ASSIGN.md\n coast docs --path concepts_and_terminology/PORTS.md\n coast docs --path coastfiles/README.md\n\n## Quick Start\n\nEnruta las solicitudes a uno de estos modos:\n\n1. **Usar Coast** — ejecuta `coast lookup`, luego usa `coast exec`, `coast ps`,\n o `coast logs` con la instancia correspondiente.\n2. **Crear o asignar** — ejecuta `coast ls`, luego `coast run` para crear un nuevo\n Coast o `coast assign` para reapuntar uno existente.\n3. **Abrir UI** — ejecuta `coast ui`.\n\n## What Runs Where\n\nEl host y el Coast comparten el sistema de archivos. Usa `coast exec` solo para las cosas\nque necesitan servicios en ejecución dentro del contenedor.\n\n**Usa `coast exec` para:**\n- Pruebas de integración, pruebas de API, cualquier cosa que necesite bases de datos o servicios\n- Reinicios de servicios, operaciones de compose\n- Comandos que se comuniquen con procesos solo disponibles en el contenedor\n\n**Ejecuta en el host:**\n- Linting (`eslint`, `rubocop`, `golangci-lint`)\n- Verificación de tipos (`tsc --noEmit`, `go vet`)\n- Formateo (`prettier`, `gofmt`)\n- Operaciones de Git\n- Playwright y pruebas de navegador\n- Análisis estático, generación de código\n- Instalación de paquetes (`npm install`, `pip install`)\n\n## Create and Assign\n\nCuando `coast lookup` no devuelve ninguna coincidencia:\n\n1. Ejecuta `coast ls` para ver los slots disponibles.\n2. Prefiere `coast run -w ` para crear y asignar en un solo paso.\n3. Si todavía no existe ninguna compilación, ejecuta primero `coast build`.\n4. Después de crear, vuelve a ejecutar `coast lookup` para confirmar.\n\nCuando quieras cambiar un Coast existente a un worktree diferente:\n\n coast assign -w \n\nEso también funciona para un Coast ya asignado o ya checked-out, pero consulta primero\ncon el usuario antes de reasignar un slot ocupado.\n\n## Coastfile Setup\n\nSi el proyecto necesita un Coastfile nuevo o modificado, primero lee la documentación:\n\n coast docs --path coastfiles/README.md\n\nLa documentación del Coastfile cubre la configuración de compose, puertos, volúmenes, secretos,\nservicios compartidos, servicios sin contenedor auxiliar y herencia.\n\n## Safety Rules\n\n- Ejecuta `coast lookup` antes de actuar y de nuevo después de cualquier cambio de topología.\n- Pregunta antes de `coast assign`, `coast unassign` o `coast checkout` si eso fuera a\n interrumpir un slot existente.\n- Prefiere crear un nuevo Coast en lugar de reutilizar uno ya checked-out o ya asignado,\n a menos que el usuario quiera explícitamente que se reasigne el slot existente.\n- Usa `coast docs` o `coast search-docs` antes de hacer suposiciones.\n", "coastfiles/README.md": "# Coastfiles\n\nUn Coastfile es un archivo de configuración TOML que vive en la raíz de tu proyecto. Le indica a Coast todo lo que necesita saber para construir y ejecutar entornos de desarrollo aislados para ese proyecto: qué servicios ejecutar, qué puertos reenviar, cómo manejar los datos y cómo administrar los secretos.\n\nCada proyecto de Coast necesita al menos un Coastfile. El archivo siempre se llama `Coastfile` (C mayúscula, sin extensión). Si necesitas variantes para diferentes flujos de trabajo, creas Coastfiles tipados como `Coastfile.light` o `Coastfile.snap` que [heredan del base](INHERITANCE.md).\n\nPara una comprensión más profunda de cómo se relacionan los Coastfiles con el resto de Coast, consulta [Coasts](../concepts_and_terminology/COASTS.md) y [Builds](../concepts_and_terminology/BUILDS.md).\n\n## Quickstart\n\nEl Coastfile más pequeño posible:\n\n```toml\n[coast]\nname = \"my-app\"\n```\n\nEsto te da un contenedor DinD al que puedes entrar con `coast exec`. La mayoría de los proyectos querrán ya sea una referencia `compose` o [servicios bare](SERVICES.md):\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[ports]\nweb = 3000\napi = 8080\n```\n\nO sin compose, usando servicios bare:\n\n```toml\n[coast]\nname = \"my-app\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\nrestart = \"on-failure\"\n\n[ports]\nweb = 3000\n```\n\nEjecuta `coast build` y luego `coast run dev-1` y tendrás un entorno aislado.\n\n## Example Coastfiles\n\n### Proyecto simple con servicios bare\n\nUna app de Next.js sin archivo compose. Coast instala Node, ejecuta `npm install` e inicia el servidor de desarrollo directamente.\n\n```toml\n[coast]\nname = \"my-crm\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --turbopack --port 3002 --hostname 0.0.0.0\"\nport = 3002\nrestart = \"on-failure\"\n\n[ports]\nweb = 3002\n```\n\n### Proyecto full-stack con compose\n\nUn proyecto multiservicio con bases de datos compartidas, secretos, estrategias de volúmenes y configuración personalizada.\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./infra/docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"python3\", \"curl\", \"git\", \"bash\", \"ca-certificates\", \"wget\"]\nrun = [\n \"ARCH=$(uname -m | sed 's/aarch64/arm64/' | sed 's/x86_64/amd64/') && wget -qO /tmp/go.tar.gz https://go.dev/dl/go1.24.1.linux-${ARCH}.tar.gz && tar -C /usr/local -xzf /tmp/go.tar.gz && rm /tmp/go.tar.gz\",\n \"GOBIN=/usr/local/bin go install github.com/air-verse/air@v1.61.7\",\n]\n\n[ports]\nweb = 3000\nbackend = 8080\npostgres = 5432\nredis = 6379\n\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\" }\n\n[shared_services.redis]\nimage = \"redis:7\"\nports = [6379]\n\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n\n[secrets.db_password]\nextractor = \"env\"\nvar = \"DB_PASSWORD\"\ninject = \"env:DB_PASSWORD\"\n\n[omit]\nservices = [\"monitoring\", \"admin-panel\", \"nginx-proxy\"]\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### Variante ligera para pruebas (herencia)\n\nExtiende el Coastfile base, pero lo reduce a solo lo necesario para ejecutar pruebas del backend. Sin puertos, sin servicios compartidos, bases de datos aisladas.\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n\n[unset]\nports = [\"web\", \"backend\", \"postgres\", \"redis\"]\nshared_services = [\"postgres\", \"redis\"]\n\n[omit]\nservices = [\"redis\", \"backend\", \"web\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[assign]\ndefault = \"none\"\n[assign.services]\nbackend-test = \"rebuild\"\n```\n\n### Variante inicializada con snapshot\n\nCada instancia de coast comienza con una copia de los volúmenes de base de datos existentes del host y luego diverge de forma independiente.\n\n```toml\n[coast]\nextends = \"Coastfile\"\n\n[unset]\nshared_services = [\"postgres\", \"redis\", \"mongodb\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_mongodb_data\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n\n## Conventions\n\n- El archivo debe llamarse `Coastfile` (C mayúscula, sin extensión) y vivir en la raíz del proyecto.\n- Las variantes tipadas usan el patrón `Coastfile.{type}` — por ejemplo `Coastfile.light`, `Coastfile.snap`. Consulta [Inheritance and Types](INHERITANCE.md).\n- El nombre reservado `Coastfile.default` no está permitido.\n- Se usa sintaxis TOML en todo el documento. Todos los encabezados de sección usan `[brackets]` y las entradas con nombre usan `[section.name]` (no array-of-tables).\n- No puedes usar tanto `compose` como `[services]` en el mismo Coastfile — elige uno.\n- Las rutas relativas (para `compose`, `root`, etc.) se resuelven contra el directorio padre del Coastfile.\n\n## Reference\n\n| Page | Sections | What it covers |\n|------|----------|----------------|\n| [Project and Setup](PROJECT.md) | `[coast]`, `[coast.setup]` | Nombre, ruta de compose, runtime, worktree dir, configuración del contenedor |\n| [Worktree Directories](WORKTREE_DIR.md) | `worktree_dir`, `default_worktree_dir` | Directorios worktree locales y externos, rutas con tilde, integración con Codex/Claude |\n| [Ports](PORTS.md) | `[ports]`, `[egress]` | Reenvío de puertos, declaraciones de egress, puerto primario |\n| [Volumes](VOLUMES.md) | `[volumes.*]` | Estrategias de volúmenes aislados, compartidos e inicializados con snapshot |\n| [Shared Services](SHARED_SERVICES.md) | `[shared_services.*]` | Bases de datos a nivel de host y servicios de infraestructura |\n| [Secrets](SECRETS.md) | `[secrets.*]`, `[inject]` | Extracción, inyección y reenvío de secretos desde env/archivo del host |\n| [Bare Services](SERVICES.md) | `[services.*]` | Ejecutar procesos directamente sin Docker Compose |\n| [Agent Shell](AGENT_SHELL.md) | `[agent_shell]` | Entornos TUI de agente en contenedores |\n| [MCP Servers](MCP.md) | `[mcp.*]`, `[mcp_clients.*]` | Servidores MCP internos y proxyados desde el host, conectores de cliente |\n| [Assign](ASSIGN.md) | `[assign]` | Comportamiento al cambiar de rama por servicio |\n| [Inheritance and Types](INHERITANCE.md) | `extends`, `includes`, `[unset]`, `[omit]` | Coastfiles tipados, composición y sobrescrituras |\n", "coastfiles/AGENT_SHELL.md": "# Shell del agente\n\n> **En la mayoría de los flujos de trabajo, no necesitas contenerizar tu agente de codificación.** Dado que Coast comparte el [sistema de archivos](../concepts_and_terminology/FILESYSTEM.md) con tu máquina host, el enfoque más simple es ejecutar el agente en tu host y usar [`coast exec`](../concepts_and_terminology/EXEC_AND_DOCKER.md) para tareas pesadas en tiempo de ejecución como pruebas de integración. Los shells de agente son para casos en los que específicamente quieres que el agente se ejecute dentro del contenedor — por ejemplo, para darle acceso directo al daemon interno de Docker o para aislar completamente su entorno.\n\nLa sección `[agent_shell]` configura una TUI de agente — como Claude Code o Codex — para ejecutarse dentro del contenedor de Coast. Cuando está presente, Coast inicia automáticamente una sesión PTY persistente ejecutando el comando configurado cuando se inicia una instancia.\n\nPara ver el panorama completo de cómo funcionan los shells de agente — el modelo de agente activo, el envío de entrada, el ciclo de vida y la recuperación — consulta [Agent Shells](../concepts_and_terminology/AGENT_SHELLS.md).\n\n## Configuración\n\nLa sección tiene un único campo obligatorio: `command`.\n\n```toml\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\n### `command` (obligatorio)\n\nEl comando de shell que se ejecutará en el PTY del agente. Esto suele ser un CLI de agente de codificación que has instalado mediante `[coast.setup]`.\n\nEl comando se ejecuta dentro del contenedor DinD en `/workspace` (la raíz del proyecto). No es un servicio de compose — se ejecuta junto a tu stack de compose o servicios sin compose, no dentro de ellos.\n\n## Ciclo de vida\n\n- El shell del agente se inicia automáticamente con `coast run`.\n- En [Coastguard](../concepts_and_terminology/COASTGUARD.md), aparece como una pestaña persistente \"Agent\" que no se puede cerrar.\n- Si el proceso del agente termina, Coast puede reiniciarlo.\n- Puedes enviar entrada a un shell de agente en ejecución mediante `coast agent-shell input`.\n\n## Ejemplos\n\n### Claude Code\n\nInstala Claude Code en `[coast.setup]`, configura las credenciales mediante [secrets](SECRETS.md), luego configura el shell del agente:\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\", \"git\", \"bash\"]\nrun = [\n \"npm install -g @anthropic-ai/claude-code\",\n \"mkdir -p /root/.claude\",\n]\n\n[secrets.claude_credentials]\nextractor = \"keychain\"\nservice = \"Claude Code-credentials\"\ninject = \"file:/root/.claude/.credentials.json\"\n\n[agent_shell]\ncommand = \"cd /workspace; exec claude --dangerously-skip-permissions --effort high\"\n```\n\n### Shell de agente simple\n\nUn shell de agente mínimo para probar que la funcionalidad funciona:\n\n```toml\n[coast]\nname = \"test-agent\"\n\n[coast.setup]\npackages = [\"bash\"]\n\n[agent_shell]\ncommand = \"exec sh -c 'while true; do echo agent-heartbeat; sleep 5; done'\"\n```\n", "coastfiles/ASSIGN.md": "# Asignar\n\nLa sección `[assign]` controla lo que sucede con los servicios dentro de una instancia de Coast cuando cambias de rama con `coast assign`. Cada servicio puede configurarse con una estrategia diferente según si necesita una reconstrucción completa, un reinicio, una recarga en caliente o nada en absoluto.\n\nPara saber cómo funcionan `coast assign` y `coast unassign` en tiempo de ejecución, consulta [Assign](../concepts_and_terminology/ASSIGN.md).\n\n## `[assign]`\n\n### `default`\n\nLa acción predeterminada aplicada a todos los servicios al cambiar de rama. El valor predeterminado es `\"restart\"` si se omite por completo toda la sección `[assign]`.\n\n- **`\"none\"`** — no hacer nada. El servicio sigue ejecutándose tal cual. Útil para bases de datos y cachés que no dependen del código.\n- **`\"hot\"`** — el código ya está montado en vivo mediante el [filesystem](../concepts_and_terminology/FILESYSTEM.md), por lo que el servicio incorpora los cambios automáticamente (p. ej., mediante un observador de archivos o recarga en caliente). No se necesita reiniciar el contenedor.\n- **`\"restart\"`** — reiniciar el contenedor del servicio. Úsalo cuando el servicio lee el código al inicio pero no necesita una reconstrucción completa de la imagen.\n- **`\"rebuild\"`** — reconstruir la imagen de Docker del servicio y reiniciar. Es necesario cuando el código está integrado en la imagen mediante `COPY` o `ADD` en el Dockerfile.\n\n```toml\n[assign]\ndefault = \"none\"\n```\n\n### `[assign.services]`\n\nAnulaciones por servicio. Cada clave es un nombre de servicio de compose y el valor es una de las cuatro acciones anteriores.\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\nEsto te permite dejar bases de datos y cachés sin cambios (`\"none\"` mediante el valor predeterminado) mientras reconstruyes o reinicias solo los servicios que dependen del código que cambió.\n\n### `[assign.rebuild_triggers]`\n\nPatrones de archivos que fuerzan una reconstrucción para servicios específicos, incluso si su acción predeterminada es algo más liviano. Cada clave es un nombre de servicio y el valor es una lista de rutas o patrones de archivos.\n\n```toml\n[assign]\ndefault = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\", \"package-lock.json\"]\n```\n\n### `exclude_paths`\n\nUna lista de rutas que se excluirán de la sincronización del worktree durante `coast assign`. Es útil en monorepos grandes donde ciertos directorios son irrelevantes para los servicios que se ejecutan en Coast y, de otro modo, ralentizarían la operación de asignación.\n\n```toml\n[assign]\ndefault = \"none\"\nexclude_paths = [\"apps/ide\", \"apps/extension\", \"apps/ide-extension\"]\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n## Ejemplos\n\n### Reconstruir app, dejar todo lo demás intacto\n\nCuando tu servicio de app integra el código en su imagen de Docker pero tus bases de datos son independientes de los cambios de código:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napp = \"rebuild\"\n```\n\n### Recarga en caliente de frontend y backend\n\nCuando ambos servicios usan observadores de archivos (p. ej., servidor dev de Next.js, Go air, nodemon) y el código está montado en vivo:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\nbackend = \"hot\"\nweb = \"hot\"\n```\n\n### Reconstrucción por servicio con triggers\n\nEl servicio API normalmente solo se reinicia, pero si `Dockerfile` o `package.json` cambian, se reconstruye:\n\n```toml\n[assign]\ndefault = \"none\"\n\n[assign.services]\napi = \"restart\"\nworker = \"restart\"\n\n[assign.rebuild_triggers]\napi = [\"Dockerfile\", \"package.json\"]\n```\n\n### Reconstrucción completa para todo\n\nCuando todos los servicios integran el código en sus imágenes:\n\n```toml\n[assign]\ndefault = \"rebuild\"\n```\n", @@ -2828,19 +2893,19 @@ "coastfiles/SERVICES.md": "# Servicios Bare\n\n> **Nota:** Los servicios bare se ejecutan directamente dentro del contenedor de Coast como procesos normales — no están contenerizados. Si tus servicios ya están dockerizados, usa `compose` en su lugar. Los servicios bare son más adecuados para configuraciones simples donde quieres evitar el overhead de escribir un Dockerfile y un docker-compose.yml.\n\nLas secciones `[services.*]` definen procesos que Coast ejecuta directamente dentro del contenedor DinD, sin Docker Compose. Esta es una alternativa a usar un archivo `compose` — no puedes usar ambos en el mismo Coastfile.\n\nLos servicios bare son supervisados por Coast con captura de logs y políticas de reinicio opcionales. Para un contexto más profundo sobre cómo funcionan los servicios bare, sus limitaciones y cuándo migrar a compose, consulta [Servicios Bare](../concepts_and_terminology/BARE_SERVICES.md).\n\n## Definir un servicio\n\nCada servicio es una sección TOML con nombre bajo `[services]`. El campo `command` es obligatorio.\n\n```toml\n[services.web]\ncommand = \"node server.js\"\nport = 3000\n```\n\n### `command` (obligatorio)\n\nEl comando de shell a ejecutar. No debe estar vacío ni contener solo espacios en blanco.\n\n```toml\n[services.web]\ncommand = \"npx next dev --turbopack --port 3000 --hostname 0.0.0.0\"\n```\n\n### `port`\n\nEl puerto en el que el servicio escucha. Se usa para comprobación de salud e integración de reenvío de puertos. Si se especifica, debe ser distinto de cero.\n\n```toml\n[services.web]\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\n```\n\n### `restart`\n\nPolítica de reinicio si el proceso finaliza. Por defecto es `\"no\"`.\n\n- `\"no\"` — no reiniciar\n- `\"on-failure\"` — reiniciar solo si el proceso termina con un código distinto de cero\n- `\"always\"` — reiniciar siempre\n\n```toml\n[services.web]\ncommand = \"node server.js\"\nport = 3000\nrestart = \"on-failure\"\n```\n\n### `install`\n\nComandos a ejecutar antes de iniciar el servicio (p. ej., instalar dependencias). Acepta una única cadena o un array de cadenas.\n\n```toml\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\n```\n\n```toml\n[services.web]\ninstall = [\"npm install\", \"npm run build\"]\ncommand = \"npm start\"\nport = 3000\n```\n\n## Exclusión mutua con compose\n\nUn Coastfile no puede definir tanto `compose` como `[services]`. Si tienes un campo `compose` en `[coast]`, agregar cualquier sección `[services.*]` es un error. Elige un enfoque por Coastfile.\n\nSi necesitas que algunos servicios estén contenerizados mediante compose y otros se ejecuten como bare, usa compose para todos — consulta [la guía de migración en Servicios Bare](../concepts_and_terminology/BARE_SERVICES.md) para saber cómo pasar de servicios bare a compose.\n\n## Ejemplos\n\n### Aplicación Next.js de un solo servicio\n\n```toml\n[coast]\nname = \"my-frontend\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --turbopack --port 3002 --hostname 0.0.0.0\"\nport = 3002\nrestart = \"on-failure\"\n\n[ports]\nweb = 3002\n```\n\n### Servidor web con worker en segundo plano\n\n```toml\n[coast]\nname = \"my-app\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"node server.js\"\nport = 3000\nrestart = \"on-failure\"\n\n[services.worker]\ncommand = \"node worker.js\"\nrestart = \"always\"\n\n[ports]\nweb = 3000\n```\n\n### Servicio Python con instalación de varios pasos\n\n```toml\n[coast]\nname = \"ml-service\"\n\n[coast.setup]\npackages = [\"python3\", \"py3-pip\"]\n\n[services.api]\ninstall = [\"pip install -r requirements.txt\", \"python manage.py migrate\"]\ncommand = \"python manage.py runserver 0.0.0.0:8000\"\nport = 8000\nrestart = \"on-failure\"\n\n[ports]\napi = 8000\n```\n", "coastfiles/SHARED_SERVICES.md": "# Servicios compartidos\n\nLas secciones `[shared_services.*]` definen servicios de infraestructura — bases de datos, cachés, brokers de mensajes — que se ejecutan en el daemon de Docker del host en lugar de dentro de contenedores individuales de Coast. Varias instancias de Coast se conectan al mismo servicio compartido a través de una red bridge.\n\nPara saber cómo funcionan los servicios compartidos en tiempo de ejecución, la gestión del ciclo de vida y la resolución de problemas, consulta [Servicios compartidos](../concepts_and_terminology/SHARED_SERVICES.md).\n\n## Definir un servicio compartido\n\nCada servicio compartido es una sección TOML con nombre bajo `[shared_services]`. El campo `image` es obligatorio; todo lo demás es opcional.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\n```\n\n### `image` (obligatorio)\n\nLa imagen de Docker que se ejecutará en el daemon del host.\n\n### `ports`\n\nLista de puertos que el servicio expone. Coast acepta tanto puertos de contenedor simples como asignaciones de estilo Docker Compose `\"HOST:CONTAINER\"`.\n\n```toml\n[shared_services.redis]\nimage = \"redis:7-alpine\"\nports = [6379]\n```\n\n```toml\n[shared_services.postgis]\nimage = \"ghcr.io/baosystems/postgis:12-3.3\"\nports = [\"5433:5432\"]\n```\n\n- Un entero simple como `6379` es una abreviatura de `\"6379:6379\"`.\n- Una cadena mapeada como `\"5433:5432\"` publica el servicio compartido en el puerto del host\n `5433` mientras sigue siendo accesible dentro de Coast en `service-name:5432`.\n- Tanto el puerto del host como el del contenedor deben ser distintos de cero.\n\n### `volumes`\n\nCadenas de montaje (bind) de volúmenes de Docker para persistir datos. Estos son volúmenes de Docker a nivel del host, no volúmenes gestionados por Coast.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\n```\n\n### `env`\n\nVariables de entorno que se pasan al contenedor del servicio.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\", POSTGRES_DB = \"mydb\" }\n```\n\n### `auto_create_db`\n\nCuando es `true`, Coast crea automáticamente una base de datos por instancia dentro del servicio compartido para cada instancia de Coast. El valor predeterminado es `false`.\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\nauto_create_db = true\n```\n\n### `inject`\n\nInyecta la información de conexión del servicio compartido en las instancias de Coast como una variable de entorno o un archivo. Usa el mismo formato `env:NAME` o `file:/path` que los [secrets](SECRETS.md).\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16\"\nports = [5432]\nenv = { POSTGRES_PASSWORD = \"dev\" }\ninject = \"env:DATABASE_URL\"\n```\n\n## Ciclo de vida\n\nLos servicios compartidos se inician automáticamente cuando se ejecuta la primera instancia de Coast que los referencia. Siguen ejecutándose a través de `coast stop` y `coast rm` — eliminar una instancia no afecta a los datos del servicio compartido. Solo `coast shared rm` detiene y elimina un servicio compartido.\n\nLas bases de datos por instancia creadas por `auto_create_db` también sobreviven a la eliminación de la instancia. Usa `coast shared-services rm` para eliminar el servicio y sus datos por completo.\n\n## Cuándo usar servicios compartidos vs volúmenes\n\nUsa servicios compartidos cuando varias instancias de Coast necesiten hablar con el mismo servidor de base de datos (p. ej., un Postgres compartido donde cada instancia obtiene su propia base de datos). Usa [estrategias de volúmenes](VOLUMES.md) cuando quieras controlar cómo se comparten o aíslan los datos de un servicio interno de compose.\n\n## Ejemplos\n\n### Postgres, Redis y MongoDB\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:15\"\nports = [5432]\nvolumes = [\"infra_postgres_data:/var/lib/postgresql/data\"]\nenv = { POSTGRES_USER = \"myapp\", POSTGRES_PASSWORD = \"myapp_pass\", POSTGRES_MULTIPLE_DATABASES = \"dev_db,test_db\" }\n\n[shared_services.redis]\nimage = \"redis:7\"\nports = [6379]\nvolumes = [\"infra_redis_data:/data\"]\n\n[shared_services.mongodb]\nimage = \"mongo:latest\"\nports = [27017]\nvolumes = [\"infra_mongodb_data:/data/db\"]\nenv = { MONGO_INITDB_ROOT_USERNAME = \"myapp\", MONGO_INITDB_ROOT_PASSWORD = \"myapp_pass\" }\n```\n\n### Postgres compartido mínimo\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16-alpine\"\nports = [5432]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\", POSTGRES_DB = \"coast_demo\" }\n```\n\n### Postgres compartido con asignación host/contenedor\n\n```toml\n[shared_services.postgres]\nimage = \"postgres:16-alpine\"\nports = [\"5433:5432\"]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\", POSTGRES_DB = \"coast_demo\" }\n```\n\n### Servicios compartidos con bases de datos creadas automáticamente\n\n```toml\n[shared_services.db]\nimage = \"postgres:16-alpine\"\nports = [5432]\nenv = { POSTGRES_USER = \"coast\", POSTGRES_PASSWORD = \"coast\" }\nauto_create_db = true\n```\n", "coastfiles/VOLUMES.md": "# Volúmenes\n\nLas secciones `[volumes.*]` controlan cómo se manejan los volúmenes de Docker con nombre en las instancias de Coast. Cada volumen se configura con una estrategia que determina si las instancias comparten datos o tienen su propia copia independiente.\n\nPara una visión más amplia del aislamiento de datos en Coast —incluidos los servicios compartidos como alternativa— consulta [Volumes](../concepts_and_terminology/VOLUMES.md).\n\n## Definir un volumen\n\nCada volumen es una sección TOML con nombre bajo `[volumes]`. Se requieren tres campos:\n\n- **`strategy`** — `\"isolated\"` o `\"shared\"`\n- **`service`** — el nombre del servicio de compose que usa este volumen\n- **`mount`** — la ruta de montaje del volumen en el contenedor\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## Estrategias\n\n### `isolated`\n\nCada instancia de Coast obtiene su propio volumen independiente. Los datos no se comparten entre instancias. Los volúmenes se crean con `coast run` y se eliminan con `coast rm`.\n\n```toml\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n```\n\nEsta es la opción correcta para la mayoría de los volúmenes de bases de datos: cada instancia empieza desde cero y puede modificar los datos libremente sin afectar a otras instancias.\n\n### `shared`\n\nTodas las instancias de Coast usan un único volumen de Docker. Cualquier dato escrito por una instancia es visible para todas las demás.\n\n```toml\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n```\n\nLos volúmenes compartidos nunca se eliminan con `coast rm`. Persisten hasta que los elimines manualmente.\n\nCoast muestra una advertencia en tiempo de build si usas `shared` en un volumen conectado a un servicio tipo base de datos. Compartir un único volumen de base de datos entre múltiples instancias concurrentes puede causar corrupción. Si necesitas bases de datos compartidas, usa [shared services](SHARED_SERVICES.md) en su lugar.\n\nBuenos usos para volúmenes compartidos: cachés de dependencias (módulos de Go, caché de npm, caché de pip), cachés de artefactos de build y otros datos donde las escrituras concurrentes son seguras o poco probables.\n\n## Siembra desde instantáneas (snapshot)\n\nLos volúmenes aislados pueden sembrarse a partir de un volumen de Docker existente en el momento de creación de la instancia usando `snapshot_source`. Los datos del volumen fuente se copian al nuevo volumen aislado, que luego diverge de forma independiente.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n`snapshot_source` solo es válido con `strategy = \"isolated\"`. Configurarlo en un volumen compartido es un error.\n\nEsto es útil cuando quieres que cada instancia de Coast comience con un conjunto de datos realista copiado desde tu base de datos de desarrollo en el host, pero quieres que las instancias sean libres de modificar esos datos sin afectar a la fuente ni entre sí.\n\n## Ejemplos\n\n### Bases de datos aisladas, caché de dependencias compartida\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"db\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"cache\"\nmount = \"/data\"\n\n[volumes.go_modules_cache]\nstrategy = \"shared\"\nservice = \"backend\"\nmount = \"/go/pkg/mod\"\n```\n\n### Stack completo sembrado desde instantáneas\n\nCada instancia comienza con una copia de los volúmenes de base de datos existentes de tu host y luego diverge de manera independiente.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_mongodb_data\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n\n### Ejecutor de pruebas con bases de datos limpias por instancia\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nservice = \"test-redis\"\nmount = \"/data\"\n\n[volumes.mongodb_data]\nstrategy = \"isolated\"\nservice = \"mongodb\"\nmount = \"/data/db\"\n```\n", - "coastfiles/WORKTREE_DIR.md": "# Directorios de worktree\n\nEl campo `worktree_dir` en `[coast]` controla dónde viven los git worktrees. Coast usa git worktrees para dar a cada instancia su propia copia del código base en una rama diferente, sin duplicar el repositorio completo.\n\n## Sintaxis\n\n`worktree_dir` acepta una sola cadena o un arreglo de cadenas:\n\n```toml\n# Single directory (default)\nworktree_dir = \".worktrees\"\n\n# Multiple directories\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\nCuando se omite, el valor predeterminado es `\".worktrees\"`.\n\n## Tipos de ruta\n\n### Rutas relativas\n\nLas rutas que no comienzan con `~/` o `/` se resuelven en relación con la raíz del proyecto. Estas son las más comunes y no requieren manejo especial — están dentro del directorio del proyecto y están disponibles automáticamente dentro del contenedor de Coast mediante el bind mount estándar `/host-project`.\n\n```toml\nworktree_dir = \".worktrees\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Rutas con tilde (externas)\n\nLas rutas que comienzan con `~/` se expanden al directorio home del usuario y se tratan como directorios de worktree **externos**. Coast añade un bind mount separado para que el contenedor pueda acceder a ellos.\n\n```toml\nworktree_dir = [\"~/.codex/worktrees\", \".worktrees\"]\n```\n\nAsí es como se integra con herramientas que crean worktrees fuera de la raíz de su proyecto, como OpenAI Codex (que siempre crea worktrees en `$CODEX_HOME/worktrees`).\n\n### Rutas absolutas (externas)\n\nLas rutas que comienzan con `/` también se tratan como externas y reciben su propio bind mount.\n\n```toml\nworktree_dir = [\"/shared/worktrees\", \".worktrees\"]\n```\n\n## Cómo funcionan los directorios externos\n\nCuando Coast encuentra un directorio de worktree externo (ruta con tilde o absoluta), ocurren tres cosas:\n\n1. **Bind mount del contenedor** — En el momento de la creación del contenedor (`coast run`), la ruta resuelta del host se monta mediante bind en el contenedor en `/host-external-wt/{index}`, donde `{index}` es la posición en el arreglo `worktree_dir`. Esto hace que los archivos externos sean accesibles dentro del contenedor.\n\n2. **Filtrado de proyecto** — Los directorios externos pueden contener worktrees de múltiples proyectos. Coast usa `git worktree list --porcelain` (que está inherentemente limitado al repositorio actual) para descubrir solo los worktrees que pertenecen a este proyecto. El watcher de git también verifica la pertenencia leyendo el archivo `.git` de cada worktree y comprobando que su puntero `gitdir:` se resuelva de vuelta al repositorio actual.\n\n3. **Remontaje del workspace** — Cuando hace `coast assign` a un worktree externo, Coast vuelve a montar `/workspace` desde la ruta del bind mount externo en lugar de la ruta habitual `/host-project/{dir}/{name}`.\n\n## Nombres de los worktrees externos\n\nLos worktrees externos con una rama checked out aparecen por el nombre de su rama, igual que los worktrees locales.\n\nLos worktrees externos en un **detached HEAD** (común con Codex) aparecen usando su ruta relativa dentro del directorio externo. Por ejemplo, un worktree de Codex en `~/.codex/worktrees/a0db/coastguard-platform` aparece como `a0db/coastguard-platform` en la UI y la CLI.\n\n## `default_worktree_dir`\n\nControla qué directorio se usa cuando Coast crea un worktree **nuevo** (por ejemplo, cuando asigna una rama que no tiene un worktree existente). El valor predeterminado es la primera entrada en `worktree_dir`.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\ndefault_worktree_dir = \".worktrees\"\n```\n\nLos directorios externos nunca se usan para crear worktrees nuevos — Coast siempre crea worktrees en un directorio local (relativo). El campo `default_worktree_dir` solo es necesario cuando quiere sobrescribir el valor predeterminado (la primera entrada).\n\n## Ejemplos\n\n### Integración con Codex\n\nOpenAI Codex crea worktrees en `~/.codex/worktrees/{hash}/{project-name}`. Para hacer que estos sean visibles y asignables en Coast:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nDespués de agregar esto, los worktrees de Codex aparecen en el modal de checkout y en la salida de `coast ls`. Puede asignar una instancia de Coast a un worktree de Codex para ejecutar su código en un entorno de desarrollo completo.\n\nNota: el contenedor debe recrearse (`coast run`) después de agregar un directorio externo para que el bind mount surta efecto. Reiniciar una instancia existente no es suficiente.\n\n### Integración con Claude Code\n\nClaude Code crea worktrees dentro del proyecto en `.claude/worktrees/`. Como esta es una ruta relativa (dentro de la raíz del proyecto), funciona como cualquier otro directorio de worktree local — no se necesita ningún montaje externo:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Los tres juntos\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\n## Lectura en vivo del Coastfile\n\nLos cambios en `worktree_dir` en su Coastfile surten efecto inmediatamente para el **listado** de worktrees (la API y el watcher de git leen el Coastfile en vivo desde el disco, no solo el artefacto de compilación en caché). Sin embargo, los **bind mounts** externos solo se crean en el momento de la creación del contenedor, por lo que necesita recrear la instancia para que un directorio externo recién agregado pueda montarse.\n", + "coastfiles/WORKTREE_DIR.md": "# Directorios de worktree\n\nEl campo `worktree_dir` en `[coast]` controla dónde viven los git worktrees. Coast usa git worktrees para dar a cada instancia su propia copia del código base en una rama diferente, sin duplicar el repositorio completo.\n\n## Sintaxis\n\n`worktree_dir` acepta una sola cadena o un arreglo de cadenas:\n\n```toml\n# Single directory (default)\nworktree_dir = \".worktrees\"\n\n# Multiple directories\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\n```\n\nCuando se omite, el valor predeterminado es `\".worktrees\"`.\n\n## Tipos de ruta\n\n### Rutas relativas\n\nLas rutas que no comienzan con `~/` o `/` se resuelven en relación con la raíz del proyecto. Estas son las más comunes y no requieren manejo especial — están dentro del directorio del proyecto y están disponibles automáticamente dentro del contenedor de Coast mediante el bind mount estándar `/host-project`.\n\n```toml\nworktree_dir = \".worktrees\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Rutas con tilde (externas)\n\nLas rutas que comienzan con `~/` se expanden al directorio home del usuario y se tratan como directorios de worktree **externos**. Coast añade un bind mount separado para que el contenedor pueda acceder a ellos.\n\n```toml\nworktree_dir = [\"~/.codex/worktrees\", \".worktrees\"]\n```\n\nAsí es como se integra con herramientas que crean worktrees fuera de la raíz del proyecto, como OpenAI Codex (que siempre crea worktrees en `$CODEX_HOME/worktrees`).\n\n### Rutas absolutas (externas)\n\nLas rutas que comienzan con `/` también se tratan como externas y reciben su propio bind mount.\n\n```toml\nworktree_dir = [\"/shared/worktrees\", \".worktrees\"]\n```\n\n### Patrones glob (externos)\n\nLas rutas externas pueden contener metacaracteres glob (`*`, `?`, `[...]`). Coast los expande en tiempo de ejecución contra el sistema de archivos del host, creando un bind mount para cada directorio coincidente.\n\n```toml\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\nEsto es útil cuando una herramienta genera worktrees bajo un componente de ruta que varía según el proyecto (como un hash). El `*` coincide con cualquier nombre de directorio único, por lo que `~/.shep/repos/*/wt` coincide con `~/.shep/repos/a21f0cda9ab9d456/wt` y con cualquier otro directorio hash que contenga un subdirectorio `wt`.\n\nSintaxis glob compatible:\n\n- `*` — coincide con cualquier secuencia de caracteres dentro de un único componente de ruta\n- `?` — coincide con cualquier carácter único\n- `[abc]` — coincide con cualquier carácter del conjunto\n- `[!abc]` — coincide con cualquier carácter que no esté en el conjunto\n\nLa expansión glob ocurre en todos los lugares donde se resuelven los directorios de worktree: creación del contenedor, assign, start, lookup y el watcher de git. Las coincidencias se ordenan para un orden determinista. Si un glob no coincide con ningún directorio, se omite silenciosamente.\n\nComo ocurre con otras rutas externas, el contenedor debe recrearse (`coast run`) después de agregar un patrón glob para que el bind mount surta efecto.\n\n## Cómo funcionan los directorios externos\n\nCuando Coast encuentra un directorio de worktree externo (ruta con tilde o absoluta), ocurren tres cosas:\n\n1. **Bind mount del contenedor** — En el momento de la creación del contenedor (`coast run`), la ruta resuelta del host se monta mediante bind en el contenedor en `/host-external-wt/{index}`, donde `{index}` es la posición en el arreglo `worktree_dir`. Esto hace que los archivos externos sean accesibles dentro del contenedor.\n\n2. **Filtrado de proyecto** — Los directorios externos pueden contener worktrees de múltiples proyectos. Coast usa `git worktree list --porcelain` (que está inherentemente limitado al repositorio actual) para descubrir solo los worktrees que pertenecen a este proyecto. El watcher de git también verifica la pertenencia leyendo el archivo `.git` de cada worktree y comprobando que su puntero `gitdir:` se resuelva de vuelta al repositorio actual.\n\n3. **Remontaje del workspace** — Cuando hace `coast assign` a un worktree externo, Coast vuelve a montar `/workspace` desde la ruta del bind mount externo en lugar de la ruta habitual `/host-project/{dir}/{name}`.\n\n## Nombres de los worktrees externos\n\nLos worktrees externos con una rama checked out aparecen por el nombre de su rama, igual que los worktrees locales.\n\nLos worktrees externos en un **detached HEAD** (común con Codex) aparecen usando su ruta relativa dentro del directorio externo. Por ejemplo, un worktree de Codex en `~/.codex/worktrees/a0db/coastguard-platform` aparece como `a0db/coastguard-platform` en la UI y la CLI.\n\n## `default_worktree_dir`\n\nControla qué directorio se usa cuando Coast crea un worktree **nuevo** (por ejemplo, cuando asigna una rama que no tiene un worktree existente). El valor predeterminado es la primera entrada en `worktree_dir`.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\ndefault_worktree_dir = \".worktrees\"\n```\n\nLos directorios externos nunca se usan para crear worktrees nuevos — Coast siempre crea worktrees en un directorio local (relativo). El campo `default_worktree_dir` solo es necesario cuando quiere sobrescribir el valor predeterminado (la primera entrada).\n\n## Ejemplos\n\n### Integración con Codex\n\nOpenAI Codex crea worktrees en `~/.codex/worktrees/{hash}/{project-name}`. Para hacer que estos sean visibles y asignables en Coast:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nDespués de agregar esto, los worktrees de Codex aparecen en el modal de checkout y en la salida de `coast ls`. Puede asignar una instancia de Coast a un worktree de Codex para ejecutar su código en un entorno de desarrollo completo.\n\nNota: el contenedor debe recrearse (`coast run`) después de agregar un directorio externo para que el bind mount surta efecto. Reiniciar una instancia existente no es suficiente.\n\n### Integración con Claude Code\n\nClaude Code crea worktrees dentro del proyecto en `.claude/worktrees/`. Como esta es una ruta relativa (dentro de la raíz del proyecto), funciona como cualquier otro directorio de worktree local — no se necesita ningún montaje externo:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\n### Integración con Shep\n\nShep crea worktrees en `~/.shep/repos/{hash}/wt/{branch-slug}` donde el hash es por repositorio. Use un patrón glob para coincidir con el directorio hash:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n### Todos los harnesses juntos\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\n## Lectura en vivo del Coastfile\n\nLos cambios en `worktree_dir` en su Coastfile surten efecto inmediatamente para el **listado** de worktrees (la API y el watcher de git leen el Coastfile en vivo desde el disco, no solo el artefacto de compilación en caché). Sin embargo, los **bind mounts** externos solo se crean en el momento de la creación del contenedor, por lo que necesita recrear la instancia para que un directorio externo recién agregado pueda montarse.\n", "concepts_and_terminology/README.md": "# Conceptos y Terminología\n\nEsta sección cubre los conceptos centrales y el vocabulario utilizados en todo Coasts. Si eres nuevo en Coasts, empieza aquí antes de profundizar en la configuración o el uso avanzado.\n\n- [Coasts](COASTS.md) — runtimes autocontenidos de tu proyecto, cada uno con sus propios puertos, volúmenes y asignación de worktree.\n- [Run](RUN.md) — crear una nueva instancia de Coast a partir de la build más reciente, asignando opcionalmente un worktree.\n- [Remove](REMOVE.md) — desmantelar una instancia de Coast y su estado de runtime aislado cuando necesitas una recreación limpia o quieres apagar Coasts.\n- [Sistema de archivos](FILESYSTEM.md) — el montaje compartido entre el host y un Coast, agentes del lado del host y cambio de worktree.\n- [Daemon de Coast](DAEMON.md) — el plano de control local `coastd` que ejecuta operaciones del ciclo de vida.\n- [CLI de Coast](CLI.md) — la interfaz de terminal para comandos, scripts y flujos de trabajo de agentes.\n- [Coastguard](COASTGUARD.md) — la UI web lanzada con `coast ui` para observabilidad y control.\n- [Puertos](PORTS.md) — puertos canónicos vs puertos dinámicos y cómo checkout intercambia entre ellos.\n- [Puerto Primario y DNS](PRIMARY_PORT_AND_DNS.md) — enlaces rápidos a tu servicio primario, enrutamiento por subdominios para aislamiento de cookies y plantillas de URL.\n- [Asignar y Desasignar](ASSIGN.md) — cambiar un Coast entre worktrees y las estrategias de asignación disponibles.\n- [Checkout](CHECKOUT.md) — mapear puertos canónicos a una instancia de Coast y cuándo lo necesitas.\n- [Lookup](LOOKUP.md) — descubrir qué instancias de Coast coinciden con el worktree actual del agente.\n- [Topología de Volúmenes](VOLUMES.md) — servicios compartidos, volúmenes compartidos, volúmenes aislados y creación de instantáneas.\n- [Servicios Compartidos](SHARED_SERVICES.md) — servicios de infraestructura gestionados por el host y desambiguación de volúmenes.\n- [Secretos y Extractores](SECRETS.md) — extraer secretos del host e inyectarlos en contenedores de Coast.\n- [Builds](BUILDS.md) — la anatomía de una build de coast, dónde viven los artefactos, auto-purga y builds tipadas.\n- [Tipos de Coastfile](COASTFILE_TYPES.md) — variantes composables de Coastfile con extends, unset, omit y autostart.\n- [Runtimes y Servicios](RUNTIMES_AND_SERVICES.md) — el runtime DinD, la arquitectura Docker-in-Docker y cómo se ejecutan los servicios dentro de un Coast.\n- [Servicios Bare](BARE_SERVICES.md) — ejecutar procesos no contenerizados dentro de un Coast y por qué deberías contenerizarlos en su lugar.\n- [Logs](LOGS.md) — leer logs de servicios desde dentro de un Coast, el compromiso de MCP y el visor de logs de Coastguard.\n- [Exec y Docker](EXEC_AND_DOCKER.md) — ejecutar comandos dentro de un Coast y hablar con el daemon Docker interno.\n- [Shells de Agentes](AGENT_SHELLS.md) — TUIs de agentes contenerizadas, el compromiso de OAuth y por qué probablemente deberías ejecutar agentes en el host en su lugar.\n- [Servidores MCP](MCP_SERVERS.md) — configurar herramientas MCP dentro de un Coast para agentes contenerizados, servidores internos vs proxificados por el host.\n- [Solución de problemas](TROUBLESHOOTING.md) — doctor, reinicio del daemon, eliminación del proyecto y la opción nuclear de restablecimiento de fábrica.\n", "concepts_and_terminology/AGENT_SHELLS.md": "# Shells de agente\n\nLos shells de agente son shells dentro de un Coast que se abren directamente a un runtime TUI de agente — Claude Code, Codex o cualquier agente CLI. Los configuras con una sección `[agent_shell]` en tu Coastfile y Coast lanza el proceso del agente dentro del contenedor DinD.\n\n**Para la mayoría de los casos de uso, no deberías hacer esto.** En su lugar, ejecuta tus agentes de programación en la máquina host. El [filesystem](FILESYSTEM.md) compartido significa que un agente en el host puede editar código con normalidad mientras llama a [`coast logs`](LOGS.md), [`coast exec`](EXEC_AND_DOCKER.md) y [`coast ps`](RUNTIMES_AND_SERVICES.md) para obtener información del runtime. Los shells de agente añaden montaje de credenciales, complicaciones de OAuth y complejidad del ciclo de vida que no necesitas a menos que tengas una razón específica para contenerizar el propio agente.\n\n## El problema de OAuth\n\nSi estás usando Claude Code, Codex u herramientas similares que autentican mediante OAuth, el token fue emitido para tu máquina host. Cuando ese mismo token se usa desde dentro de un contenedor Linux — un user agent distinto, un entorno distinto — el proveedor puede marcarlo o revocarlo. Obtendrás fallos de autenticación intermitentes que son difíciles de depurar.\n\nPara agentes en contenedores, la autenticación basada en API key es la opción más segura. Establece la clave como un [secret](SECRETS.md) en tu Coastfile e inyéctala en el entorno del contenedor.\n\nSi las API keys no son una opción, puedes montar credenciales OAuth dentro del Coast (consulta la sección Configuración más abajo), pero espera fricción. En macOS, si usas el extractor de secretos `keychain` para obtener tokens OAuth, cada `coast build` te pedirá la contraseña del llavero de macOS. Esto hace que el proceso de build sea tedioso, especialmente cuando reconstruyes con frecuencia. El aviso del Keychain es un requisito de seguridad de macOS y no se puede omitir.\n\n## Configuración\n\nAñade una sección `[agent_shell]` a tu Coastfile con el comando a ejecutar:\n\n```toml\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\nEl comando se ejecuta dentro del contenedor DinD en `/workspace`. Coast crea un usuario `coast` dentro del contenedor, copia credenciales de `/root/.claude/` a `/home/coast/.claude/` y ejecuta el comando como ese usuario. Si tu agente necesita credenciales montadas dentro del contenedor, usa `[secrets]` con inyección de archivos (ver [Secrets and Extractors](SECRETS.md)) y `[coast.setup]` para instalar la CLI del agente:\n\n```toml\n[coast.setup]\nrun = [\"npm install -g @anthropic-ai/claude-code\"]\n\n[secrets.claude_credentials]\nextractor = \"keychain\"\nservice = \"Claude Code-credentials\"\ninject = \"file:/root/.claude/.credentials.json\"\n\n[agent_shell]\ncommand = \"claude --dangerously-skip-permissions\"\n```\n\nSi se configura `[agent_shell]`, Coast lanza automáticamente un shell cuando inicia la instancia. La configuración se hereda mediante `extends` y puede sobrescribirse por [tipo de Coastfile](COASTFILE_TYPES.md).\n\n## El modelo de agente activo\n\nCada instancia de Coast puede tener múltiples shells de agente, pero solo uno está **activo** a la vez. El shell activo es el destino predeterminado para los comandos que no especifican un ID `--shell`.\n\n```bash\ncoast agent-shell dev-1 ls\n\n SHELL STATUS ACTIVE\n 1 running ★\n 2 running\n```\n\nCambiar el shell activo:\n\n```bash\ncoast agent-shell dev-1 activate 2\n```\n\nNo puedes cerrar el shell activo — primero activa uno diferente. Esto evita matar accidentalmente el shell con el que estás interactuando.\n\nEn Coastguard, los shells de agente aparecen como pestañas en el panel Exec con insignias de activo/inactivo. Haz clic en una pestaña para ver su terminal; usa el menú desplegable para activar, lanzar o cerrar shells.\n\n![Agent shell in Coastguard](../../assets/coastguard-agent-shell.png)\n*Un shell de agente ejecutando Claude Code dentro de una instancia de Coast, accesible desde la pestaña Exec en Coastguard.*\n\n## Envío de entrada\n\nLa forma principal de controlar programáticamente un agente contenerizado es `coast agent-shell input`:\n\n```bash\ncoast agent-shell dev-1 input \"fix the failing test in auth.test.ts\"\n```\n\nEsto escribe el texto en el TUI del agente activo y pulsa Enter. El agente lo recibe como si lo hubieras tecleado en el terminal.\n\nOpciones:\n\n- `--no-send` — escribe el texto sin pulsar Enter. Útil para ir construyendo una entrada parcial o navegar menús TUI.\n- `--shell ` — apunta a un shell específico en lugar del activo.\n- `--show-bytes` — imprime los bytes exactos que se envían, para depuración.\n\nBajo el capó, la entrada se escribe directamente en el descriptor de archivo maestro del PTY. El texto y la pulsación de Enter se envían como dos escrituras separadas con una pausa de 25ms para evitar artefactos de modo pegado que algunos frameworks TUI muestran al recibir entrada rápida.\n\n## Otros comandos\n\n```bash\ncoast agent-shell dev-1 spawn # create a new shell\ncoast agent-shell dev-1 spawn --activate # create and immediately activate\ncoast agent-shell dev-1 tty # attach interactive TTY to active shell\ncoast agent-shell dev-1 tty --shell 2 # attach to a specific shell\ncoast agent-shell dev-1 read-output # read full scrollback buffer\ncoast agent-shell dev-1 read-last-lines 50 # read last 50 lines of output\ncoast agent-shell dev-1 session-status # check if the shell process is alive\n```\n\n`tty` te ofrece una sesión interactiva en vivo — puedes escribir directamente en el TUI del agente. Desacopla con la secuencia de escape estándar del terminal. `read-output` y `read-last-lines` son no interactivos y devuelven texto, lo cual es útil para scripting y automatización.\n\n## Ciclo de vida y recuperación\n\nLas sesiones de shell de agente persisten en Coastguard al navegar entre páginas. El búfer de scrollback (hasta 512KB) se reproduce cuando te vuelves a conectar a una pestaña.\n\nCuando detienes una instancia de Coast con `coast stop`, se matan todos los procesos PTY de los shells de agente y se limpian sus registros en la base de datos. `coast start` lanza automáticamente un shell de agente nuevo si `[agent_shell]` está configurado.\n\nTras un reinicio del daemon, los shells de agente que estaban ejecutándose previamente se mostrarán como muertos. El sistema lo detecta automáticamente — si el shell activo está muerto, el primer shell vivo se promociona a activo. Si no hay shells vivos, lanza uno nuevo con `coast agent-shell spawn --activate`.\n\n## Para quién es esto\n\nLos shells de agente están diseñados para **productos que construyen integraciones de primera parte** alrededor de Coasts — plataformas de orquestación, wrappers de agentes y herramientas que quieren gestionar agentes de programación contenerizados de forma programática mediante las APIs `input`, `read-output` y `session-status`.\n\nPara programación general con agentes en paralelo, ejecuta los agentes en el host. Es más simple, evita problemas de OAuth, elude la complejidad del montaje de credenciales y aprovecha al máximo el filesystem compartido. Obtienes todos los beneficios de Coast (runtimes aislados, gestión de puertos, cambio de worktree) sin ninguna de las sobrecargas de contenerización del agente.\n\nEl siguiente nivel de complejidad más allá de los shells de agente es montar [servidores MCP](MCP_SERVERS.md) dentro del Coast para que el agente contenerizado tenga acceso a herramientas. Esto amplía aún más la superficie de integración y se cubre por separado. La capacidad está ahí si la necesitas, pero la mayoría de los usuarios no deberían.\n", "concepts_and_terminology/ASSIGN.md": "# Asignar y Desasignar\n\nAsignar y desasignar controlan a qué worktree está apuntando una instancia de Coast. Consulta [Filesystem](FILESYSTEM.md) para ver cómo funciona el cambio de worktree a nivel de montaje.\n\n## Asignar\n\n`coast assign` cambia una instancia de Coast a un worktree específico. Coast crea el worktree si aún no existe, actualiza el código dentro de Coast y reinicia los servicios según la estrategia de asignación configurada.\n\n```bash\ncoast assign dev-1 --worktree feature/oauth\n```\n\n```text\nBefore:\n┌─── dev-1 ──────────────────┐\n│ branch: main │\n│ worktree: - │\n└────────────────────────────┘\n\ncoast assign dev-1 --worktree feature/oauth\n\nAfter:\n┌─── dev-1 ──────────────────┐\n│ branch: feature/oauth │\n│ worktree: feature/oauth │\n│ │\n│ postgres → skipped (none) │\n│ web → hot swapped │\n│ api → restarted │\n│ worker → rebuilt │\n└────────────────────────────┘\n```\n\nDespués de asignar, `dev-1` está ejecutando la rama `feature/oauth` con todos sus servicios activos.\n\n## Desasignar\n\n`coast unassign` cambia una instancia de Coast de vuelta a la raíz del proyecto (tu rama main/master). Se elimina la asociación con el worktree y Coast vuelve a ejecutarse desde el repositorio principal.\n\n```text\ncoast unassign dev-1\n\n┌─── dev-1 ──────────────────┐\n│ branch: main │\n│ worktree: - │\n└────────────────────────────┘\n```\n\n## Estrategias de asignación\n\nCuando se asigna una instancia de Coast a un nuevo worktree, cada servicio necesita saber cómo manejar el cambio de código. Esto se configura por servicio en tu [Coastfile](COASTFILE_TYPES.md) bajo `[assign]`:\n\n```toml\n[assign]\ndefault = \"restart\"\n\n[assign.services]\npostgres = \"none\"\nredis = \"none\"\nweb = \"hot\"\nworker = \"rebuild\"\n```\n\n```text\ncoast assign dev-1 --worktree feature/billing\n\n postgres (strategy: none) → skipped, unchanged between branches\n redis (strategy: none) → skipped, unchanged between branches\n web (strategy: hot) → filesystem swapped, file watcher picks it up\n api (strategy: restart) → container restarted\n worker (strategy: rebuild) → image rebuilt, container restarted\n```\n\nLas estrategias disponibles son:\n\n- **none** — no hacer nada. Úsalo para servicios que no cambian entre ramas, como Postgres o Redis.\n- **hot** — intercambiar únicamente el sistema de archivos. El servicio sigue ejecutándose y recoge los cambios mediante la propagación de montajes y los observadores de archivos (p. ej., un servidor de desarrollo con recarga en caliente).\n- **restart** — reiniciar el contenedor del servicio. Úsalo para servicios interpretados que solo necesitan un reinicio del proceso. Esta es la opción predeterminada.\n- **rebuild** — reconstruir la imagen del servicio y reiniciar. Úsalo cuando el cambio de rama afecta al `Dockerfile` o a las dependencias de tiempo de compilación.\n\nTambién puedes especificar disparadores de reconstrucción para que un servicio solo se reconstruya cuando cambien archivos específicos:\n\n```toml\n[assign.rebuild_triggers]\nworker = [\"Dockerfile\", \"package.json\"]\n```\n\nSi ninguno de los archivos disparadores cambió entre ramas, el servicio omite la reconstrucción incluso si la estrategia está configurada como `rebuild`.\n\n## Worktrees eliminados\n\nSi se elimina un worktree asignado, el daemon `coastd` desasigna automáticamente esa instancia de vuelta a la raíz del repositorio principal de Git.\n\n---\n\n> **Consejo: Reducir la latencia de asignación en bases de código grandes**\n>\n> Internamente, la primera asignación a un nuevo worktree inicializa determinados archivos ignorados por git en ese worktree, y los servicios con `[assign.rebuild_triggers]` pueden ejecutar `git diff --name-only` para decidir si es necesaria una reconstrucción. En bases de código grandes, ese paso de inicialización y las reconstrucciones innecesarias tienden a dominar el tiempo de asignación.\n>\n> Usa `exclude_paths` en tu Coastfile para reducir la superficie de inicialización de archivos ignorados por git, usa `\"hot\"` para servicios con observadores de archivos y mantén `[assign.rebuild_triggers]` centrado en verdaderas entradas de tiempo de compilación. Si necesitas refrescar manualmente la inicialización de archivos ignorados para un worktree existente, ejecuta `coast assign --force-sync`. Consulta [Performance Optimizations](PERFORMANCE_OPTIMIZATIONS.md) para una guía completa.\n", "concepts_and_terminology/BARE_SERVICES.md": "# Servicios Bare\n\nSi puedes contenerizar tu proyecto, deberías hacerlo. Los servicios bare existen para proyectos que aún no se han contenerizado y en los que añadir un `Dockerfile` y `docker-compose.yml` no es práctico a corto plazo. Son un peldaño, no un destino.\n\nEn lugar de que un `docker-compose.yml` orqueste servicios contenerizados, los servicios bare te permiten definir comandos de shell en tu Coastfile y Coast los ejecuta como procesos normales con un supervisor ligero dentro del contenedor de Coast.\n\n## Por Qué Contenerizar En Su Lugar\n\nLos servicios de [Docker Compose](RUNTIMES_AND_SERVICES.md) te dan:\n\n- Builds reproducibles mediante Dockerfiles\n- Health checks que Coast puede esperar durante el arranque\n- Aislamiento de procesos entre servicios\n- Gestión de volúmenes y red gestionada por Docker\n- Una definición portable que funciona en CI, staging y producción\n\nLos servicios bare no te dan nada de eso. Tus procesos comparten el mismo sistema de archivos, la recuperación ante fallos es un bucle de shell, y \"funciona en mi máquina\" es igual de probable dentro de Coast que fuera. Si tu proyecto ya tiene un `docker-compose.yml`, úsalo.\n\n## Cuándo Tienen Sentido los Servicios Bare\n\n- Estás adoptando Coast para un proyecto que nunca se ha contenerizado y quieres empezar a obtener valor del aislamiento de worktrees y la gestión de puertos inmediatamente\n- Tu proyecto es una herramienta de un solo proceso o un CLI donde un Dockerfile sería excesivo\n- Quieres iterar en la contenerización de forma gradual — empieza con servicios bare y pásate a compose más adelante\n\n## Configuración\n\nLos servicios bare se definen con secciones `[services.]` en tu Coastfile. Un Coastfile puede definir servicios bare por sí solos o junto a `compose` — consulta [Mixed Service Types](MIXED_SERVICE_TYPES.md) para lo segundo.\n\n```toml\n[coast]\nname = \"my-app\"\nruntime = \"dind\"\n\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n\n[services.web]\ninstall = \"npm install\"\ncommand = \"npx next dev --port 3000 --hostname 0.0.0.0\"\nport = 3000\nrestart = \"on-failure\"\n\n[services.worker]\ncommand = \"node worker.js\"\nrestart = \"always\"\n\n[ports]\nweb = 3000\n```\n\nCada servicio tiene cuatro campos:\n\n| Field | Required | Description |\n|---|---|---|\n| `command` | yes | El comando de shell a ejecutar (p. ej. `\"npm run dev\"`) |\n| `port` | no | El puerto en el que escucha el servicio, usado para el mapeo de puertos |\n| `restart` | no | Política de reinicio: `\"no\"` (por defecto), `\"on-failure\"`, o `\"always\"` |\n| `install` | no | Uno o más comandos a ejecutar antes de iniciar (p. ej. `\"npm install\"` o `[\"npm install\", \"npm run build\"]`) |\n\n### Paquetes de Setup\n\nDado que los servicios bare se ejecutan como procesos normales, el contenedor de Coast necesita tener instalados los runtimes correctos. Usa `[coast.setup]` para declarar paquetes del sistema:\n\n```toml\n[coast.setup]\npackages = [\"nodejs\", \"npm\"]\n```\n\nEstos se instalan antes de que se inicie cualquier servicio. Sin esto, tus comandos `npm` o `node` fallarán dentro del contenedor.\n\n### Comandos de Instalación\n\nEl campo `install` se ejecuta antes de que el servicio arranque y nuevamente en cada [`coast assign`](ASSIGN.md) (cambio de rama). Aquí es donde va la instalación de dependencias:\n\n```toml\n[services.api]\ninstall = [\"pip install -r requirements.txt\", \"python manage.py migrate\"]\ncommand = \"python manage.py runserver 0.0.0.0:8000\"\nport = 8000\n```\n\nLos comandos de instalación se ejecutan secuencialmente. Si algún comando de instalación falla, el servicio no se inicia.\n\n### Políticas de Reinicio\n\n- **`no`** — el servicio se ejecuta una vez. Si termina, se queda muerto. Úsalo para tareas de una sola ejecución o servicios que quieras gestionar manualmente.\n- **`on-failure`** — reinicia el servicio si termina con un código distinto de cero. Las salidas exitosas (código 0) se dejan tal cual. Usa backoff exponencial desde 1 segundo hasta 30 segundos, y se rinde tras 10 fallos consecutivos.\n- **`always`** — reinicia ante cualquier salida, incluida la exitosa. Mismo backoff que `on-failure`. Úsalo para servidores de larga ejecución que no deberían detenerse nunca.\n\nSi un servicio se ejecuta durante más de 30 segundos antes de fallar, el contador de reintentos y el backoff se reinician — la suposición es que estuvo sano durante un tiempo y el fallo es un problema nuevo.\n\n## Cómo Funciona Por Debajo\n\n```text\n┌─── Coast: dev-1 ──────────────────────────────────────┐\n│ │\n│ /coast-supervisor/ │\n│ ├── web.sh (runs command, tracks PID) │\n│ ├── worker.sh │\n│ ├── start-all.sh (launches all services) │\n│ ├── stop-all.sh (SIGTERM via PID files) │\n│ └── ps.sh (checks PID liveness) │\n│ │\n│ /var/log/coast-services/ │\n│ ├── web.log │\n│ └── worker.log │\n│ │\n│ No inner Docker daemon images are used. │\n│ Processes run directly on the container OS. │\n└───────────────────────────────────────────────────────┘\n```\n\nCoast genera wrappers en scripts de shell para cada servicio y los coloca en `/coast-supervisor/` dentro del contenedor DinD. Cada wrapper registra su PID, redirige la salida a un archivo de log e implementa la política de reinicio como un bucle de shell. No hay Docker Compose, no hay imágenes de Docker internas y no hay aislamiento a nivel de contenedor entre servicios.\n\n`coast ps` comprueba la vivacidad del PID en lugar de consultar a Docker, y `coast logs` hace tail de los archivos de log en lugar de llamar a `docker compose logs`. El formato de salida de los logs coincide con el formato de compose `service | line`, por lo que la UI de Coastguard funciona sin cambios.\n\n## Puertos\n\nLa configuración de puertos funciona exactamente igual que con Coasts basados en compose. Define los puertos en los que escuchan tus servicios en `[ports]`:\n\n```toml\n[services.web]\ncommand = \"npm start\"\nport = 3000\n\n[ports]\nweb = 3000\n```\n\nLos [puertos dinámicos](PORTS.md) se asignan en `coast run`, y [`coast checkout`](CHECKOUT.md) intercambia los puertos canónicos como de costumbre. La única diferencia es que no hay una red Docker entre servicios — todos se enlazan directamente al loopback del contenedor o a `0.0.0.0`.\n\n## Cambio de Rama\n\nCuando ejecutas `coast assign` en un Coast de servicios bare, ocurre lo siguiente:\n\n1. Todos los servicios en ejecución se detienen vía SIGTERM\n2. El worktree cambia a la nueva rama\n3. Los comandos de instalación se vuelven a ejecutar (p. ej. `npm install` recoge las dependencias de la nueva rama)\n4. Todos los servicios se reinician\n\nEsto es equivalente a lo que ocurre con compose — `docker compose down`, cambio de rama, rebuild, `docker compose up` — pero con procesos de shell en lugar de contenedores.\n\n## Limitaciones\n\n- **Sin health checks.** Coast no puede esperar a que un servicio bare esté \"sano\" de la manera en que puede hacerlo con un servicio compose que define un health check. Inicia el proceso y espera lo mejor.\n- **Sin aislamiento entre servicios.** Todos los procesos comparten el mismo sistema de archivos y el mismo espacio de nombres de procesos dentro del contenedor de Coast. Un servicio que se comporte mal puede afectar a otros.\n- **Sin caché de build.** Los builds de Docker Compose se cachean capa por capa. Los comandos `install` de servicios bare se ejecutan desde cero en cada assign.\n- **Recuperación ante fallos básica.** La política de reinicio usa un bucle de shell con backoff exponencial. No es un supervisor de procesos como systemd o supervisord.\n- **Sin `[omit]` o `[unset]` para servicios.** La composición de tipos de Coastfile funciona con servicios compose, pero los servicios bare no soportan omitir servicios individuales mediante Coastfiles tipados.\n\n## Migrar a Compose\n\nCuando estés listo para contenerizar, la ruta de migración es sencilla:\n\n1. Escribe un `Dockerfile` para cada servicio\n2. Crea un `docker-compose.yml` que los referencie\n3. Sustituye las secciones `[services.*]` en tu Coastfile por un campo `compose` que apunte a tu archivo de compose\n4. Elimina los paquetes de `[coast.setup]` que ahora gestionan tus Dockerfiles\n5. Reconstruye con [`coast build`](BUILDS.md)\n\nTus mapeos de puertos, [volúmenes](VOLUMES.md), [servicios compartidos](SHARED_SERVICES.md) y configuración de [secrets](SECRETS.md) se trasladan sin cambios. Lo único que cambia es cómo se ejecutan los propios servicios.\n", "concepts_and_terminology/BUILDS.md": "# Builds\n\nPiensa en una build de coast como una imagen de Docker con ayuda adicional. Una build es un artefacto basado en directorio que agrupa todo lo necesario para crear instancias de Coast: un [Coastfile](COASTFILE_TYPES.md) resuelto, un archivo compose reescrito, tarballs de imágenes OCI predescargadas y archivos del host inyectados. No es una imagen de Docker en sí, pero contiene imágenes de Docker (como tarballs) además de los metadatos que Coast necesita para conectarlas entre sí.\n\n## Qué hace `coast build`\n\nCuando ejecutas `coast build`, el daemon ejecuta estos pasos en orden:\n\n1. Analiza y valida el Coastfile.\n2. Lee el archivo compose y filtra los servicios omitidos.\n3. Extrae [secretos](SECRETS.md) de los extractores configurados y los almacena cifrados en el keystore.\n4. Construye imágenes de Docker para los servicios compose que tienen directivas `build:` (en el host).\n5. Descarga imágenes de Docker para los servicios compose que tienen directivas `image:`.\n6. Almacena en caché todas las imágenes como tarballs OCI en `~/.coast/image-cache/`.\n7. Si `[coast.setup]` está configurado, construye una imagen base DinD personalizada con los paquetes, comandos y archivos especificados.\n8. Escribe el directorio del artefacto de build con el manifiesto, el coastfile resuelto, el compose reescrito y los archivos inyectados.\n9. Actualiza el enlace simbólico `latest` para que apunte a la nueva build.\n10. Elimina automáticamente las builds antiguas que excedan el límite de conservación.\n\n## Dónde viven las builds\n\n```text\n~/.coast/\n images/\n my-project/\n latest -> a3c7d783_20260227143000 (symlink)\n a3c7d783_20260227143000/ (versioned build)\n manifest.json\n coastfile.toml\n compose.yml\n inject/\n b4d8e894_20260226120000/ (older build)\n ...\n image-cache/ (shared tarball cache)\n postgres_16_a1b2c3d4e5f6.tar\n redis_7_f6e5d4c3b2a1.tar\n coast-built_my-project_web_latest_...tar\n```\n\nCada build obtiene un **ID de build** único con el formato `{coastfile_hash}_{YYYYMMDDHHMMSS}`. El hash incorpora el contenido del Coastfile y la configuración resuelta, por lo que los cambios en el Coastfile producen un nuevo ID de build.\n\nEl enlace simbólico `latest` siempre apunta a la build más reciente para una resolución rápida. Si tu proyecto usa Coastfiles tipados (por ejemplo, `Coastfile.light`), cada tipo obtiene su propio enlace simbólico: `latest-light`.\n\nLa caché de imágenes en `~/.coast/image-cache/` se comparte entre todos los proyectos. Si dos proyectos usan la misma imagen de Postgres, el tarball se almacena una sola vez en caché.\n\n## Qué contiene una build\n\nCada directorio de build contiene:\n\n- **`manifest.json`** -- metadatos completos de la build: nombre del proyecto, marca de tiempo de la build, hash del coastfile, lista de imágenes almacenadas en caché/construidas, nombres de secretos, servicios omitidos, [estrategias de volumen](VOLUMES.md) y más.\n- **`coastfile.toml`** -- el Coastfile resuelto (fusionado con el padre si se usa `extends`).\n- **`compose.yml`** -- una versión reescrita de tu archivo compose donde las directivas `build:` se reemplazan por etiquetas de imagen preconstruidas, y los servicios omitidos se eliminan.\n- **`inject/`** -- copias de archivos del host de `[inject].files` (por ejemplo, `~/.gitconfig`, `~/.npmrc`).\n\n## Las builds no contienen secretos\n\nLos secretos se extraen durante el paso de build, pero se almacenan en un keystore cifrado separado en `~/.coast/keystore.db` -- no dentro del directorio del artefacto de build. El manifiesto solo registra los **nombres** de los secretos que se extrajeron, nunca los valores.\n\nEsto significa que los artefactos de build son seguros de inspeccionar sin exponer datos sensibles. Los secretos se descifran e inyectan después, cuando se crea una instancia de Coast con `coast run`.\n\n## Builds y Docker\n\nUna build involucra tres tipos de imágenes de Docker:\n\n- **Imágenes construidas** -- los servicios compose con directivas `build:` se construyen en el host mediante `docker build`, se etiquetan como `coast-built/{project}/{service}:latest` y se guardan como tarballs en la caché de imágenes.\n- **Imágenes descargadas** -- los servicios compose con directivas `image:` se descargan y se guardan como tarballs.\n- **Imagen de Coast** -- si `[coast.setup]` está configurado, se construye una imagen de Docker personalizada sobre `docker:dind` con los paquetes, comandos y archivos especificados. Se etiqueta como `coast-image/{project}:{build_id}`.\n\nEn tiempo de ejecución ([`coast run`](RUN.md)), estos tarballs se cargan en el [daemon DinD](RUNTIMES_AND_SERVICES.md) interno mediante `docker load`. Esto es lo que permite que las instancias de Coast se inicien rápidamente sin necesidad de descargar imágenes desde un registro.\n\n## Builds e instancias\n\nCuando ejecutas [`coast run`](RUN.md), Coast resuelve la build más reciente (o un `--build-id` específico) y usa sus artefactos para crear la instancia. El ID de build queda registrado en la instancia.\n\nNo necesitas volver a construir para crear más instancias. Una build puede servir a muchas instancias de Coast ejecutándose en paralelo.\n\n## Cuándo reconstruir\n\nSolo vuelve a construir cuando cambien tu Coastfile, `docker-compose.yml` o la configuración de infraestructura. Reconstruir consume muchos recursos -- vuelve a descargar imágenes, vuelve a construir imágenes de Docker y vuelve a extraer secretos.\n\nLos cambios de código no requieren una reconstrucción. Coast monta tu directorio de proyecto directamente en cada instancia, por lo que las actualizaciones de código se reflejan inmediatamente.\n\n## Eliminación automática\n\nCoast conserva hasta 5 builds por tipo de Coastfile. Después de cada `coast build` exitoso, las builds antiguas que excedan el límite se eliminan automáticamente.\n\nLas builds que están en uso por instancias en ejecución nunca se eliminan, independientemente del límite. Si tienes 7 builds pero 3 de ellas respaldan instancias activas, las 3 quedan protegidas.\n\n## Eliminación manual\n\nPuedes eliminar builds manualmente mediante `coast rm-build` o a través de la pestaña Builds de Coastguard.\n\n- **Eliminación completa del proyecto** (`coast rm-build `) requiere que primero todas las instancias se detengan y eliminen. Elimina todo el directorio de builds, las imágenes de Docker asociadas, los volúmenes y los contenedores.\n- **Eliminación selectiva** (por ID de build, disponible en la interfaz de Coastguard) omite las builds que están en uso por instancias en ejecución.\n\n## Builds tipadas\n\nSi tu proyecto usa múltiples Coastfiles (por ejemplo, `Coastfile` para la configuración predeterminada y `Coastfile.snap` para volúmenes inicializados con snapshot), cada tipo mantiene su propio enlace simbólico `latest-{type}` y su propio grupo de eliminación de 5 builds.\n\n```bash\ncoast build # uses Coastfile, updates \"latest\"\ncoast build --type snap # uses Coastfile.snap, updates \"latest-snap\"\n```\n\nEliminar una build `snap` nunca afecta a las builds `default`, y viceversa.\n", - "concepts_and_terminology/CHECKOUT.md": "# Checkout\n\nCheckout controla qué instancia de Coast posee los [puertos canónicos](PORTS.md) de tu proyecto. Cuando haces checkout de un Coast, `localhost:3000`, `localhost:5432` y cualquier otro puerto canónico se asigna directamente a esa instancia.\n\n```bash\ncoast checkout dev-1\n```\n\n```text\nBefore checkout:\n localhost:3000 ──→ (nothing)\n localhost:5432 ──→ (nothing)\n\nAfter checkout:\n localhost:3000 ──→ dev-1 web\n localhost:5432 ──→ dev-1 db\n```\n\nCambiar el checkout es instantáneo: Coast mata y vuelve a iniciar reenviadores `socat` ligeros. No se reinicia ningún contenedor.\n\n```bash\ncoast checkout dev-2 # instant swap\n\n# localhost:3000 ──→ dev-2 web\n# localhost:5432 ──→ dev-2 db\n```\n\n## Nota sobre Linux\n\nLos puertos dinámicos siempre funcionan en Linux sin privilegios especiales.\n\nLos puertos canónicos por debajo de `1024` son diferentes. Si tu Coastfile declara puertos como `80` o `443`, Linux puede impedir que `coast checkout` los asocie hasta que configures el host. Las soluciones habituales son:\n\n- aumentar `net.ipv4.ip_unprivileged_port_start`\n- otorgar capacidad de bind al binario o proceso de reenvío\n\nCoast informa esto explícitamente cuando el host niega la asociación.\n\nEn WSL, Coast usa bridges de checkout publicados por Docker para que los navegadores y herramientas de Windows puedan alcanzar los puertos canónicos seleccionados a través de `127.0.0.1`, de forma similar a flujos de trabajo de Docker Desktop como Sail.\n\n## ¿Necesitas hacer checkout?\n\nNo necesariamente. Cada Coast en ejecución siempre tiene sus propios puertos dinámicos, y puedes acceder a cualquier Coast a través de esos puertos en cualquier momento sin hacer checkout de nada.\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\nPuedes abrir `localhost:62217` en tu navegador para acceder al servidor web de dev-1 sin hacer checkout. Esto está perfectamente bien para muchos flujos de trabajo, y puedes ejecutar tantos Coasts como quieras sin usar nunca `coast checkout`.\n\n## Cuándo es útil Checkout\n\nHay situaciones en las que los puertos dinámicos no son suficientes y necesitas puertos canónicos:\n\n- **Aplicaciones cliente codificadas con puertos canónicos.** Si tienes un cliente ejecutándose fuera del Coast —un servidor de desarrollo frontend en tu host, una aplicación móvil en tu teléfono o una aplicación de escritorio— que espera `localhost:3000` o `localhost:8080`, cambiar los números de puerto en todas partes es poco práctico. Hacer checkout del Coast te da los puertos reales sin cambiar ninguna configuración.\n\n- **Webhooks y URLs de callback.** Servicios como Stripe, GitHub o proveedores de OAuth envían callbacks a una URL que registraste, normalmente algo como `https://your-ngrok-tunnel.io` que reenvía a `localhost:3000`. Si cambias a un puerto dinámico, los callbacks dejan de llegar. Hacer checkout garantiza que el puerto canónico esté activo para el Coast que estás probando.\n\n- **Herramientas de base de datos, depuradores e integraciones de IDE.** Muchos clientes GUI (pgAdmin, DataGrip, TablePlus), depuradores y configuraciones de ejecución de IDE guardan perfiles de conexión con un puerto específico. Checkout te permite mantener tus perfiles guardados y simplemente cambiar qué Coast está detrás de ellos, sin reconfigurar el destino de conexión de tu depurador o la conexión a la base de datos cada vez que cambias de contexto.\n\n## Liberar Checkout\n\nSi quieres liberar los puertos canónicos sin hacer checkout de un Coast diferente:\n\n```bash\ncoast checkout --none\n```\n\nDespués de esto, ningún Coast posee los puertos canónicos. Todos los Coasts siguen siendo accesibles a través de sus puertos dinámicos.\n\n## Solo Uno a la Vez\n\nExactamente un Coast puede estar seleccionado mediante checkout a la vez. Si `dev-1` está seleccionado y ejecutas `coast checkout dev-2`, los puertos canónicos cambian instantáneamente a `dev-2`. No hay ningún intervalo: los reenviadores antiguos se terminan y los nuevos se inician en la misma operación.\n\n```text\n┌──────────────────────────────────────────────────┐\n│ Your machine │\n│ │\n│ Canonical (checked-out Coast only): │\n│ localhost:3000 ──→ dev-2 web │\n│ localhost:5432 ──→ dev-2 db │\n│ │\n│ Dynamic (always available): │\n│ localhost:62217 ──→ dev-1 web │\n│ localhost:55681 ──→ dev-1 db │\n│ localhost:63104 ──→ dev-2 web │\n│ localhost:57220 ──→ dev-2 db │\n└──────────────────────────────────────────────────┘\n```\n\nLos puertos dinámicos no se ven afectados por checkout. Lo único que cambia es a dónde apuntan los puertos canónicos.\n", + "concepts_and_terminology/CHECKOUT.md": "# Checkout\n\nCheckout controla qué instancia de Coast posee los [puertos canónicos](PORTS.md) de tu proyecto. Cuando haces checkout de un Coast, `localhost:3000`, `localhost:5432` y cualquier otro puerto canónico se asigna directamente a esa instancia.\n\n```bash\ncoast checkout dev-1\n```\n\n```text\nBefore checkout:\n localhost:3000 ──→ (nothing)\n localhost:5432 ──→ (nothing)\n\nAfter checkout:\n localhost:3000 ──→ dev-1 web\n localhost:5432 ──→ dev-1 db\n```\n\nCambiar el checkout es instantáneo: Coast mata y vuelve a iniciar reenviadores `socat` ligeros. No se reinicia ningún contenedor.\n\n```bash\ncoast checkout dev-2 # instant swap\n\n# localhost:3000 ──→ dev-2 web\n# localhost:5432 ──→ dev-2 db\n```\n\n## Nota sobre Linux\n\nLos puertos dinámicos siempre funcionan en Linux sin privilegios especiales.\n\nLos puertos canónicos por debajo de `1024` son diferentes. Si tu Coastfile declara puertos como `80` o `443`, Linux puede impedir que `coast checkout` los asocie hasta que configures el host. Las soluciones habituales son:\n\n- aumentar `net.ipv4.ip_unprivileged_port_start`\n- otorgar capacidad de bind al binario o proceso de reenvío\n\nCoast informa esto explícitamente cuando el host niega la asociación.\n\nEn WSL, Coast usa bridges de checkout publicados por Docker para que los navegadores y herramientas de Windows puedan alcanzar los puertos canónicos seleccionados a través de `127.0.0.1`, de forma similar a flujos de trabajo de Docker Desktop como Sail.\n\nPara proyectos HTTPS locales que usan Caddy, Coast reutiliza una CA local de Caddy por instalación de Coast. Después de confiar en esa raíz una vez, los workspaces recreados bajo la misma instalación siguen usándola.\n\nEl certificado raíz se encuentra en:\n\n- `~/.coast/caddy/pki/authorities/local/root.crt` para la instalación normal\n- `~/.coast-dev/caddy/pki/authorities/local/root.crt` para `coast-dev`\n\nEstos están separados intencionalmente, así que confiar en `coast-dev` no implica también confiar en una instalación normal de `coast`, y viceversa.\n\nPara inspeccionar o exportar el certificado raíz de la instalación activa:\n\n```bash\ncoast cert info\ncoast cert path\ncoast cert fingerprint\ncoast cert export --to ~/Downloads/coast-root.crt\n```\n\nCoast deja la instalación de confianza en tus manos. Exporta el certificado y luego impórtalo en el almacén de confianza de tu sistema operativo o navegador según sea necesario.\n\n## ¿Necesitas hacer checkout?\n\nNo necesariamente. Cada Coast en ejecución siempre tiene sus propios puertos dinámicos, y puedes acceder a cualquier Coast a través de esos puertos en cualquier momento sin hacer checkout de nada.\n\n```bash\ncoast ports dev-1\n\n# SERVICE CANONICAL DYNAMIC\n# ★ web 3000 62217\n# db 5432 55681\n```\n\nPuedes abrir `localhost:62217` en tu navegador para acceder al servidor web de dev-1 sin hacer checkout. Esto está perfectamente bien para muchos flujos de trabajo, y puedes ejecutar tantos Coasts como quieras sin usar nunca `coast checkout`.\n\n## Cuándo es útil Checkout\n\nHay situaciones en las que los puertos dinámicos no son suficientes y necesitas puertos canónicos:\n\n- **Aplicaciones cliente codificadas con puertos canónicos.** Si tienes un cliente ejecutándose fuera del Coast —un servidor de desarrollo frontend en tu host, una aplicación móvil en tu teléfono o una aplicación de escritorio— que espera `localhost:3000` o `localhost:8080`, cambiar los números de puerto en todas partes es poco práctico. Hacer checkout del Coast te da los puertos reales sin cambiar ninguna configuración.\n\n- **Webhooks y URLs de callback.** Servicios como Stripe, GitHub o proveedores de OAuth envían callbacks a una URL que registraste, normalmente algo como `https://your-ngrok-tunnel.io` que reenvía a `localhost:3000`. Si cambias a un puerto dinámico, los callbacks dejan de llegar. Hacer checkout garantiza que el puerto canónico esté activo para el Coast que estás probando.\n\n- **Herramientas de base de datos, depuradores e integraciones de IDE.** Muchos clientes GUI (pgAdmin, DataGrip, TablePlus), depuradores y configuraciones de ejecución de IDE guardan perfiles de conexión con un puerto específico. Checkout te permite mantener tus perfiles guardados y simplemente cambiar qué Coast está detrás de ellos, sin reconfigurar el destino de conexión de tu depurador o la conexión a la base de datos cada vez que cambias de contexto.\n\n## Liberar Checkout\n\nSi quieres liberar los puertos canónicos sin hacer checkout de un Coast diferente:\n\n```bash\ncoast checkout --none\n```\n\nDespués de esto, ningún Coast posee los puertos canónicos. Todos los Coasts siguen siendo accesibles a través de sus puertos dinámicos.\n\n## Solo Uno a la Vez\n\nExactamente un Coast puede estar seleccionado mediante checkout a la vez. Si `dev-1` está seleccionado y ejecutas `coast checkout dev-2`, los puertos canónicos cambian instantáneamente a `dev-2`. No hay ningún intervalo: los reenviadores antiguos se terminan y los nuevos se inician en la misma operación.\n\n```text\n┌──────────────────────────────────────────────────┐\n│ Your machine │\n│ │\n│ Canonical (checked-out Coast only): │\n│ localhost:3000 ──→ dev-2 web │\n│ localhost:5432 ──→ dev-2 db │\n│ │\n│ Dynamic (always available): │\n│ localhost:62217 ──→ dev-1 web │\n│ localhost:55681 ──→ dev-1 db │\n│ localhost:63104 ──→ dev-2 web │\n│ localhost:57220 ──→ dev-2 db │\n└──────────────────────────────────────────────────┘\n```\n\nLos puertos dinámicos no se ven afectados por checkout. Lo único que cambia es a dónde apuntan los puertos canónicos.\n", "concepts_and_terminology/CLI.md": "# Coast CLI\n\nLa Coast CLI (`coast`) es la interfaz principal de línea de comandos para operar Coasts. Es intencionalmente ligera: analiza tu comando, envía una solicitud a [`coastd`](DAEMON.md) e imprime una salida estructurada de vuelta a tu terminal.\n\n## Para Qué La Usas\n\nLos flujos de trabajo típicos se controlan todos desde la CLI:\n\n```bash\ncoast build # see Builds\ncoast run dev-1 # see Run\ncoast assign dev-1 --worktree feature/oauth # see Assign\ncoast ports dev-1 # see Ports\ncoast checkout dev-1 # see Checkout\ncoast ui # see Coastguard\n```\n\nLa CLI también incluye comandos de documentación que son útiles para humanos y agentes:\n\n```bash\ncoast docs\ncoast docs --path concepts_and_terminology/CHECKOUT.md\ncoast search-docs \"canonical vs dynamic ports\"\n```\n\n## Por Qué Existe Separadamente del Daemon\n\nSeparar la CLI del daemon te ofrece algunos beneficios importantes:\n\n- El daemon mantiene el estado y los procesos de larga duración.\n- La CLI se mantiene rápida, componible y fácil de automatizar con scripts.\n- Puedes ejecutar comandos puntuales sin mantener vivo el estado de la terminal.\n- Las herramientas para agentes pueden invocar comandos de la CLI de maneras predecibles y adecuadas para la automatización.\n\n## CLI vs Coastguard\n\nUsa la interfaz que mejor se ajuste al momento:\n\n- La CLI está diseñada para ofrecer una cobertura operativa completa: cualquier cosa que puedas hacer en Coastguard también debería ser posible desde la CLI.\n- Considera la CLI como la interfaz de automatización — scripts, flujos de trabajo de agentes, trabajos de CI y herramientas personalizadas para desarrolladores.\n- Considera [Coastguard](COASTGUARD.md) como la interfaz humana — inspección visual, depuración interactiva y visibilidad operativa.\n\nAmbas se comunican con el mismo daemon, por lo que operan sobre el mismo estado subyacente del proyecto.\n", "concepts_and_terminology/COASTFILE_TYPES.md": "# Tipos de Coastfile\n\nUn solo proyecto puede tener múltiples Coastfiles para diferentes casos de uso. Cada variante se llama un \"tipo\". Los tipos te permiten componer configuraciones que comparten una base común pero difieren en qué servicios se ejecutan, cómo se manejan los volúmenes o si los servicios se inician automáticamente.\n\n## Cómo funcionan los tipos\n\nLa convención de nombres es `Coastfile` para el predeterminado y `Coastfile.{type}` para las variantes. El sufijo después del punto se convierte en el nombre del tipo:\n\n- `Coastfile` -- tipo predeterminado\n- `Coastfile.test` -- tipo de pruebas\n- `Coastfile.snap` -- tipo de instantánea\n- `Coastfile.light` -- tipo ligero\n\nConstruyes y ejecutas Coasts tipados con `--type`:\n\n```bash\ncoast build --type test\ncoast run test-1 --type test\ncoast exec test-1 -- go test ./...\n```\n\n## extends\n\nUn Coastfile tipado hereda de un padre mediante `extends`. Todo lo del padre se fusiona. El hijo solo necesita especificar lo que sobrescribe o agrega.\n\n```toml\n[coast]\nextends = \"Coastfile\"\n```\n\nEsto evita duplicar toda tu configuración para cada variante. El hijo hereda todos los [puertos](PORTS.md), [secretos](SECRETS.md), [volúmenes](VOLUMES.md), [servicios compartidos](SHARED_SERVICES.md), [estrategias de asignación](ASSIGN.md), comandos de configuración y configuraciones de [MCP](MCP_SERVERS.md) del padre. Cualquier cosa que el hijo defina tiene prioridad sobre el padre.\n\n## [unset]\n\nElimina elementos específicos heredados del padre por nombre. Puedes hacer unset de `ports`, `shared_services`, `secrets` y `volumes`.\n\n```toml\n[unset]\nports = [\"web\", \"redis\", \"backend\"]\nshared_services = [\"postgres\", \"redis\"]\n```\n\nAsí es como una variante de pruebas elimina servicios compartidos (para que las bases de datos se ejecuten dentro del Coast con volúmenes aislados) y elimina puertos que no necesita.\n\n## [omit]\n\nElimina por completo servicios de compose de la construcción. Los servicios omitidos se eliminan del archivo compose y no se ejecutan dentro del Coast en absoluto.\n\n```toml\n[omit]\nservices = [\"redis\", \"backend\", \"mailhog\", \"web\"]\n```\n\nÚsalo para excluir servicios que son irrelevantes para el propósito de la variante. Una variante de pruebas podría mantener solo la base de datos, las migraciones y el ejecutor de pruebas.\n\n## autostart\n\nControla si `docker compose up` se ejecuta automáticamente cuando inicia el Coast. El valor predeterminado es `true`.\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n```\n\nEstablece `autostart = false` para variantes en las que quieres ejecutar comandos específicos manualmente en lugar de levantar toda la pila. Esto es común para ejecutores de pruebas: creas el Coast y luego usas [`coast exec`](EXEC_AND_DOCKER.md) para ejecutar suites de pruebas individuales.\n\n## Patrones comunes\n\n### Variante de pruebas\n\nUn `Coastfile.test` que mantiene solo lo necesario para ejecutar pruebas:\n\n```toml\n[coast]\nextends = \"Coastfile\"\nautostart = false\n\n[unset]\nports = [\"web\", \"redis\", \"backend\"]\nshared_services = [\"postgres\", \"redis\"]\n\n[omit]\nservices = [\"redis\", \"backend\", \"mailhog\", \"web\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[assign]\ndefault = \"none\"\n[assign.services]\ntest-runner = \"rebuild\"\nmigrations = \"rebuild\"\n```\n\nCada Coast de pruebas obtiene su propia base de datos limpia. No se exponen puertos porque las pruebas se comunican con los servicios a través de la red interna de compose. `autostart = false` significa que disparas las ejecuciones de pruebas manualmente con `coast exec`.\n\n### Variante de instantánea\n\nUn `Coastfile.snap` que inicializa cada Coast con una copia de los volúmenes de base de datos existentes del host:\n\n```toml\n[coast]\nextends = \"Coastfile\"\n\n[unset]\nshared_services = [\"postgres\", \"redis\"]\n\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"my_project_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n\n[volumes.redis_data]\nstrategy = \"isolated\"\nsnapshot_source = \"my_project_redis_data\"\nservice = \"redis\"\nmount = \"/data\"\n```\n\nLos servicios compartidos se eliminan para que las bases de datos se ejecuten dentro de cada Coast. `snapshot_source` inicializa los volúmenes aislados a partir de volúmenes existentes del host en el momento de la construcción. Después de la creación, los datos de cada instancia divergen de forma independiente.\n\n### Variante ligera\n\nUn `Coastfile.light` que reduce el proyecto al mínimo para un flujo de trabajo específico: quizá solo un servicio de backend y su base de datos para iteración rápida.\n\n## Grupos de construcción independientes\n\nCada tipo tiene su propio enlace simbólico `latest-{type}` y su propio grupo de auto-poda de 5 construcciones:\n\n```bash\ncoast build # actualiza latest, poda las construcciones predeterminadas\ncoast build --type test # actualiza latest-test, poda las construcciones de test\ncoast build --type snap # actualiza latest-snap, poda las construcciones de snap\n```\n\nConstruir un tipo `test` no afecta a las construcciones `default` o `snap`. La poda es completamente independiente por tipo.\n\n## Ejecutar Coasts tipados\n\nLas instancias creadas con `--type` se etiquetan con su tipo. Puedes tener instancias de diferentes tipos ejecutándose simultáneamente para el mismo proyecto:\n\n```bash\ncoast run dev-1 # tipo predeterminado\ncoast run test-1 --type test # tipo de pruebas\ncoast run snapshot-1 --type snap # tipo de instantánea\n\ncoast ls\n# Las tres aparecen, cada una con su propio tipo, puertos y estrategia de volúmenes\n```\n\nAsí es como puedes tener un entorno de desarrollo completo ejecutándose junto a ejecutores de pruebas aislados e instancias inicializadas desde instantáneas, todo para el mismo proyecto, todo al mismo tiempo.\n", "concepts_and_terminology/COASTGUARD.md": "# Coastguard\n\nCoastguard es la interfaz web local de Coast (piensa: una interfaz al estilo Docker Desktop de Coast), ejecutándose en el puerto `31415`. Se inicia desde la CLI:\n\n```bash\ncoast ui\n```\n\n![Coastguard project overview](../../assets/coastguard-overview.png)\n*El panel del proyecto que muestra instancias de Coast en ejecución, sus ramas/worktrees y el estado de checkout.*\n\n![Coastguard port mappings](../../assets/coastguard-ports.png)\n*La página de puertos para una instancia específica de Coast, mostrando mapeos de puertos canónicos y dinámicos para cada servicio.*\n\n## Para Qué Es Útil Coastguard\n\nCoastguard te ofrece una superficie visual de control y observabilidad para tu proyecto:\n\n- Ver proyectos, instancias, estados, ramas y estado de checkout.\n- Inspeccionar los [mapeos de puertos](PORTS.md) y saltar directamente a los servicios.\n- Ver [logs](LOGS.md), estadísticas de ejecución e inspeccionar datos.\n- Explorar [builds](BUILDS.md), artefactos de imágenes, metadatos de [volúmenes](VOLUMES.md) y [secrets](SECRETS.md).\n- Navegar la documentación dentro de la app mientras trabajas.\n\n## Relación con la CLI y el Daemon\n\nCoastguard no reemplaza la CLI. La complementa como la interfaz orientada a humanos.\n\n- La [CLI `coast`](CLI.md) es la interfaz de automatización para scripts, flujos de trabajo de agentes e integraciones con herramientas.\n- Coastguard es la interfaz humana para inspección visual, depuración interactiva y visibilidad operativa del día a día.\n- Ambos son clientes de [`coastd`](DAEMON.md), por lo que se mantienen sincronizados.\n", "concepts_and_terminology/COASTS.md": "# Costas\n\nUna Costa es un entorno de ejecución autocontenido de tu proyecto. Se ejecuta dentro de un [contenedor Docker-in-Docker](RUNTIMES_AND_SERVICES.md), y varios servicios (tu servidor web, base de datos, caché, etc.) pueden ejecutarse dentro de una sola instancia de Costa.\n\n```text\n┌─── Coast: dev-1 (branch: feature/oauth) ──────────────┐\n│ │\n│ ┌─────────┐ ┌──────────┐ ┌─────────┐ │\n│ │ web │ │ postgres │ │ redis │ │\n│ │ :3000 │ │ :5432 │ │ :6379 │ │\n│ └─────────┘ └──────────┘ └─────────┘ │\n│ │\n│ dynamic ports: 62217, 55681, 56905 │\n└───────────────────────────────────────────────────────┘\n\n┌─── Coast: dev-2 (branch: feature/billing) ────────────┐\n│ │\n│ ┌─────────┐ ┌──────────┐ ┌─────────┐ │\n│ │ web │ │ postgres │ │ redis │ │\n│ │ :3000 │ │ :5432 │ │ :6379 │ │\n│ └─────────┘ └──────────┘ └─────────┘ │\n│ │\n│ dynamic ports: 63104, 57220, 58412 │\n└───────────────────────────────────────────────────────┘\n```\n\nCada Costa expone su propio conjunto de [puertos dinámicos](PORTS.md) a la máquina host, lo que significa que puedes acceder a cualquier Costa en ejecución en cualquier momento sin importar qué más esté ejecutándose.\n\nCuando [cambias](CHECKOUT.md) a una Costa, los puertos canónicos del proyecto se asignan a ella, por lo que `localhost:3000` apunta a la Costa seleccionada en lugar de a un puerto dinámico.\n\n```text\ncoast checkout dev-1\n\nlocalhost:3000 ──→ dev-1 web\nlocalhost:5432 ──→ dev-1 postgres\nlocalhost:6379 ──→ dev-1 redis\n\ncoast checkout dev-2 (instant swap)\n\nlocalhost:3000 ──→ dev-2 web\nlocalhost:5432 ──→ dev-2 postgres\nlocalhost:6379 ──→ dev-2 redis\n```\n\nNormalmente, una Costa se [asigna a un worktree específico](ASSIGN.md). Así es como ejecutas múltiples worktrees del mismo proyecto en paralelo sin conflictos de puertos ni colisiones de volúmenes.\n\nCreas instancias de Costa con [`coast run`](RUN.md). Depende de ti levantar y bajar Costas como mejor te parezca. Probablemente no querrías tener 20 Costas de un proyecto intensivo en memoria ejecutándose a la vez, pero cada quien con lo suyo.\n", "concepts_and_terminology/DAEMON.md": "# Daemon de Coast\n\nEl daemon de Coast (`coastd`) es el proceso local de larga duración que realiza el trabajo real de orquestación. La [CLI](CLI.md) y [Coastguard](COASTGUARD.md) son clientes; `coastd` es el plano de control detrás de ellos.\n\n## Arquitectura de un Vistazo\n\n```text\ncoast CLI (automation) -----+\n +--> coastd daemon\nCoastguard UI (human) ------+ |\n +--> Coasts\n +--> Ports\n +--> State\n```\n\nLa CLI envía solicitudes a `coastd` a través de un socket Unix local; Coastguard se conecta a través de un WebSocket. El daemon aplica cambios al estado en tiempo de ejecución.\n\n## Qué Hace\n\n`coastd` maneja las operaciones que necesitan estado persistente y coordinación en segundo plano:\n\n- Rastrea instancias de Coast, compilaciones y servicios compartidos.\n- Crea, inicia, detiene y elimina entornos de ejecución de Coast.\n- Aplica operaciones de asignar/desasignar/checkout.\n- Gestiona el [reenvío de puertos](PORTS.md) canónico y dinámico.\n- Transmite [logs](LOGS.md), estado y eventos de ejecución a clientes CLI y UI.\n\nEn resumen: si ejecutas `coast run`, `coast assign`, `coast checkout` o `coast ls`, el daemon es el componente que hace el trabajo.\n\n## Cómo se Ejecuta\n\nPuedes ejecutar el daemon de dos formas comunes:\n\n```bash\n# Register daemon auto-start at login (recommended)\ncoast daemon install\n\n# Manual start mode\ncoast daemon start\n```\n\nSi omites la instalación del daemon, necesitas iniciarlo tú mismo en cada sesión antes de usar comandos de Coast.\n\n## Reportar Errores\n\nSi te encuentras con problemas, incluye los logs del daemon `coastd` al enviar un informe de error. Los logs contienen el contexto necesario para diagnosticar la mayoría de los problemas:\n\n```bash\ncoast daemon logs\n```\n", - "concepts_and_terminology/EXEC_AND_DOCKER.md": "# Exec y Docker\n\n`coast exec` te deja en una shell dentro del contenedor DinD de Coast. Tu directorio de trabajo es `/workspace` — la [raíz del proyecto montada por bind](FILESYSTEM.md) donde vive tu Coastfile. Esta es la forma principal de ejecutar comandos, inspeccionar archivos o depurar servicios dentro de un Coast desde tu máquina host.\n\n`coast docker` es el comando complementario para hablar directamente con el daemon de Docker interno.\n\n## `coast exec`\n\nAbre una shell dentro de una instancia de Coast:\n\n```bash\ncoast exec dev-1\n```\n\nEsto inicia una sesión `sh` en `/workspace`. Los contenedores de Coast están basados en Alpine, por lo que la shell predeterminada es `sh`, no `bash`.\n\nTambién puedes ejecutar un comando específico sin entrar en una shell interactiva:\n\n```bash\ncoast exec dev-1 ls -la\ncoast exec dev-1 -- npm install\ncoast exec dev-1 -- go test ./...\n```\n\nTodo lo que va después del nombre de la instancia se pasa como el comando. Usa `--` para separar las flags que pertenecen a tu comando de las flags que pertenecen a `coast exec`.\n\n### Directorio de trabajo\n\nLa shell inicia en `/workspace`, que es la raíz de tu proyecto en el host montada por bind dentro del contenedor. Esto significa que tu código fuente, Coastfile y todos los archivos del proyecto están ahí mismo:\n\n```text\n/workspace $ ls\nCoastfile README.md apps/ packages/\nCoastfile.light go.work infra/ scripts/\nCoastfile.snap go.work.sum package-lock.json\n```\n\nCualquier cambio que hagas en archivos bajo `/workspace` se refleja en el host inmediatamente — es un montaje por bind, no una copia.\n\n### Interactivo vs No interactivo\n\nCuando stdin es un TTY (estás escribiendo en un terminal), `coast exec` evita el daemon por completo y ejecuta `docker exec -it` directamente para un passthrough completo del TTY. Esto significa que los colores, el movimiento del cursor, el autocompletado con tab y los programas interactivos funcionan como se espera.\n\nCuando stdin está canalizado o en scripts (CI, flujos de trabajo de agentes, `coast exec dev-1 -- some-command | grep foo`), la solicitud pasa por el daemon y devuelve stdout, stderr estructurados y un código de salida.\n\n### Permisos de archivos\n\nEl exec se ejecuta como el UID:GID de tu usuario del host, por lo que los archivos creados dentro del Coast tienen la propiedad correcta en el host. Sin desajustes de permisos entre host y contenedor.\n\n## `coast docker`\n\nMientras que `coast exec` te da una shell en el propio contenedor DinD, `coast docker` te permite ejecutar comandos de la CLI de Docker contra el daemon de Docker **interno** — el que gestiona tus servicios de compose.\n\n```bash\ncoast docker dev-1 # por defecto: docker ps\ncoast docker dev-1 ps # igual que arriba\ncoast docker dev-1 compose ps # docker compose ps (servicios internos)\ncoast docker dev-1 images # lista imágenes en el daemon interno\ncoast docker dev-1 compose logs web # docker compose logs para un servicio\n```\n\nCada comando que pases se prefija con `docker` automáticamente. Así, `coast docker dev-1 compose ps` ejecuta `docker compose ps` dentro del contenedor de Coast, hablando con el daemon interno.\n\n### `coast exec` vs `coast docker`\n\nLa diferencia es a qué estás apuntando:\n\n| Command | Runs as | Target |\n|---|---|---|\n| `coast exec dev-1 ls /workspace` | `sh -c \"ls /workspace\"` en el contenedor DinD | El propio contenedor de Coast (tus archivos del proyecto, herramientas instaladas) |\n| `coast docker dev-1 ps` | `docker ps` en el contenedor DinD | El daemon de Docker interno (tus contenedores de servicios de compose) |\n| `coast docker dev-1 compose logs web` | `docker compose logs web` en el contenedor DinD | Los logs de un servicio específico de compose a través del daemon interno |\n\nUsa `coast exec` para trabajo a nivel de proyecto — ejecutar tests, instalar dependencias, inspeccionar archivos. Usa `coast docker` cuando necesites ver qué está haciendo el daemon de Docker interno — estado de contenedores, imágenes, redes, operaciones de compose.\n\n## Pestaña Exec de Coastguard\n\nLa UI web de Coastguard proporciona un terminal interactivo persistente conectado por WebSocket.\n\n![Exec tab in Coastguard](../../assets/coastguard-exec.png)\n*La pestaña Exec de Coastguard mostrando una sesión de shell en /workspace dentro de una instancia de Coast.*\n\nEl terminal está impulsado por xterm.js y ofrece:\n\n- **Sesiones persistentes** — las sesiones de terminal sobreviven a la navegación por la página y a los refrescos del navegador. Al reconectar se reproduce el buffer de scrollback para que continúes donde lo dejaste.\n- **Múltiples pestañas** — abre varias shells a la vez. Cada pestaña es una sesión independiente.\n- Pestañas de **[shell de agente](AGENT_SHELLS.md)** — genera shells dedicadas para agentes de IA de programación, con seguimiento de estado activo/inactivo.\n- **Modo pantalla completa** — expande el terminal para llenar la pantalla (Escape para salir).\n\nMás allá de la pestaña de exec a nivel de instancia, Coastguard también proporciona acceso a terminal en otros niveles:\n\n- **Exec de servicio** — haz clic en un servicio individual desde la pestaña Services para obtener una shell dentro de ese contenedor interno específico (esto hace un doble `docker exec` — primero dentro del contenedor DinD, y luego dentro del contenedor del servicio).\n- **Exec de [servicio compartido](SHARED_SERVICES.md)** — obtén una shell dentro de un contenedor de servicio compartido a nivel de host.\n- **Terminal del host** — una shell en tu máquina host en la raíz del proyecto, sin entrar en un Coast en absoluto.\n\n## Cuándo usar cada uno\n\n- **`coast exec`** — ejecuta comandos a nivel de proyecto (npm install, go test, inspección de archivos, depuración) dentro del contenedor DinD.\n- **`coast docker`** — inspecciona o administra el daemon de Docker interno (estado de contenedores, imágenes, redes, operaciones de compose).\n- **Pestaña Exec de Coastguard** — depuración interactiva con sesiones persistentes, múltiples pestañas y soporte de shell de agentes. Ideal cuando quieres mantener varios terminales abiertos mientras navegas el resto de la UI.\n- **`coast logs`** — para leer la salida de los servicios, usa `coast logs` en lugar de `coast docker compose logs`. Ver [Logs](LOGS.md).\n- **`coast ps`** — para comprobar el estado de los servicios, usa `coast ps` en lugar de `coast docker compose ps`. Ver [Runtimes and Services](RUNTIMES_AND_SERVICES.md).\n", + "concepts_and_terminology/EXEC_AND_DOCKER.md": "# Exec y Docker\n\n`coast exec` te introduce en un shell dentro del contenedor DinD de Coast. Tu directorio de trabajo es `/workspace` — la [raíz del proyecto montada con bind](FILESYSTEM.md) donde vive tu Coastfile. Esta es la forma principal de ejecutar comandos, inspeccionar archivos o depurar servicios dentro de un Coast desde tu máquina host.\n\n`coast docker` es el comando complementario para hablar directamente con el daemon interno de Docker.\n\n## `coast exec`\n\nAbre un shell dentro de una instancia de Coast:\n\n```bash\ncoast exec dev-1\n```\n\nEsto inicia una sesión `sh` en `/workspace`. Los contenedores de Coast están basados en Alpine, por lo que el shell predeterminado es `sh`, no `bash`.\n\nTambién puedes ejecutar un comando específico sin entrar en un shell interactivo:\n\n```bash\ncoast exec dev-1 ls -la\ncoast exec dev-1 -- npm install\ncoast exec dev-1 -- go test ./...\ncoast exec dev-1 --service web\ncoast exec dev-1 --service web -- php artisan test\n```\n\nTodo lo que viene después del nombre de la instancia se pasa como comando. Usa `--` para separar las flags que pertenecen a tu comando de las flags que pertenecen a `coast exec`.\n\nPasa `--service ` para apuntar a un contenedor de servicio de compose específico en lugar del contenedor externo de Coast. Pasa `--root` cuando necesites acceso root sin procesar al contenedor en lugar del mapeo UID:GID del host predeterminado de Coast.\n\n### Directorio de trabajo\n\nEl shell se inicia en `/workspace`, que es la raíz de tu proyecto host montada con bind dentro del contenedor. Esto significa que tu código fuente, Coastfile y todos los archivos del proyecto están ahí mismo:\n\n```text\n/workspace $ ls\nCoastfile README.md apps/ packages/\nCoastfile.light go.work infra/ scripts/\nCoastfile.snap go.work.sum package-lock.json\n```\n\nCualquier cambio que hagas en archivos bajo `/workspace` se refleja en el host inmediatamente — es un bind mount, no una copia.\n\n### Interactivo vs No interactivo\n\nCuando stdin es un TTY (estás escribiendo en una terminal), `coast exec` omite el daemon por completo y ejecuta `docker exec -it` directamente para un passthrough completo de TTY. Esto significa que los colores, el movimiento del cursor, el autocompletado con tabulador y los programas interactivos funcionan como se espera.\n\nCuando stdin está canalizado o se ejecuta desde scripts (CI, flujos de trabajo de agentes, `coast exec dev-1 -- some-command | grep foo`), la solicitud pasa por el daemon y devuelve stdout, stderr y un código de salida estructurados.\n\n### Permisos de archivos\n\nEl exec se ejecuta con el UID:GID de tu usuario del host, por lo que los archivos creados dentro de Coast tienen la propiedad correcta en el host. No hay desajustes de permisos entre host y contenedor.\n\n## `coast docker`\n\nMientras que `coast exec` te da un shell en el propio contenedor DinD, `coast docker` te permite ejecutar comandos de Docker CLI contra el daemon **interno** de Docker — el que gestiona tus servicios de compose.\n\n```bash\ncoast docker dev-1 # defaults to: docker ps\ncoast docker dev-1 ps # same as above\ncoast docker dev-1 compose ps # docker compose ps for the active Coast-managed stack\ncoast docker dev-1 images # list images in the inner daemon\ncoast docker dev-1 compose logs web # docker compose logs for a service\n```\n\nCada comando que pases recibe automáticamente el prefijo `docker`. Así que `coast docker dev-1 compose ps` ejecuta `docker compose ps` dentro del contenedor de Coast, hablando con el daemon interno.\n\n### `coast exec` vs `coast docker`\n\nLa distinción está en lo que estás apuntando:\n\n| Command | Runs as | Target |\n|---|---|---|\n| `coast exec dev-1 ls /workspace` | `sh -c \"ls /workspace\"` in DinD container | The Coast container itself (your project files, installed tools) |\n| `coast exec dev-1 --service web` | `docker exec ... sh` in the resolved inner service container | A specific compose service container |\n| `coast docker dev-1 ps` | `docker ps` in DinD container | The inner Docker daemon (your compose service containers) |\n| `coast docker dev-1 compose logs web` | `docker compose logs web` in DinD container | A specific compose service's logs via the inner daemon |\n\nUsa `coast exec` para trabajo a nivel de proyecto — ejecutar pruebas, instalar dependencias, inspeccionar archivos. Usa `coast docker` cuando necesites ver qué está haciendo el daemon interno de Docker — estado de contenedores, imágenes, redes, operaciones de compose.\n\n## Pestaña Exec de Coastguard\n\nLa UI web de Coastguard proporciona una terminal interactiva persistente conectada por WebSocket.\n\n![Exec tab in Coastguard](../../assets/coastguard-exec.png)\n*La pestaña Exec de Coastguard mostrando una sesión de shell en /workspace dentro de una instancia de Coast.*\n\nLa terminal está impulsada por xterm.js y ofrece:\n\n- **Sesiones persistentes** — las sesiones de terminal sobreviven a la navegación por páginas y a las actualizaciones del navegador. Al reconectarte se reproduce el búfer de scrollback para que continúes donde lo dejaste.\n- **Múltiples pestañas** — abre varios shells a la vez. Cada pestaña es una sesión independiente.\n- **Pestañas de [shell de agente](AGENT_SHELLS.md)** — genera shells de agente dedicados para agentes de codificación de IA, con seguimiento de estado activo/inactivo.\n- **Modo de pantalla completa** — expande la terminal para llenar la pantalla (Escape para salir).\n\nMás allá de la pestaña exec a nivel de instancia, Coastguard también proporciona acceso a terminal en otros niveles:\n\n- **Exec de servicio** — haz clic en un servicio individual desde la pestaña Services para obtener un shell dentro de ese contenedor interno específico (esto hace un doble `docker exec` — primero dentro del contenedor DinD, luego dentro del contenedor de servicio).\n- **Exec de [servicio compartido](SHARED_SERVICES.md)** — obtén un shell dentro de un contenedor de servicio compartido a nivel host.\n- **Terminal del host** — un shell en tu máquina host en la raíz del proyecto, sin entrar en un Coast en absoluto.\n\n## Cuándo usar cada uno\n\n- **`coast exec`** — ejecuta comandos a nivel de proyecto dentro del contenedor DinD, o pasa `--service` para abrir un shell o ejecutar un comando dentro de un contenedor de servicio de compose específico.\n- **`coast docker`** — inspecciona o gestiona el daemon interno de Docker (estado de contenedores, imágenes, redes, operaciones de compose).\n- **Pestaña Exec de Coastguard** — depuración interactiva con sesiones persistentes, múltiples pestañas y soporte para shells de agente. Es la mejor opción cuando quieres mantener varias terminales abiertas mientras navegas por el resto de la UI.\n- **`coast logs`** — para leer la salida de los servicios, usa `coast logs` en lugar de `coast docker compose logs`. Consulta [Logs](LOGS.md).\n- **`coast ps`** — para comprobar el estado de los servicios, usa `coast ps` en lugar de `coast docker compose ps`. Consulta [Runtimes and Services](RUNTIMES_AND_SERVICES.md).\n", "concepts_and_terminology/FILESYSTEM.md": "# Sistema de archivos\n\nTu máquina anfitriona y cada instancia de Coast comparten los mismos archivos del proyecto. La raíz del proyecto en el host se monta con permisos de lectura-escritura dentro del contenedor DinD en `/host-project`, y Coast hace un bind-mount del árbol de trabajo activo en `/workspace`. Esto es lo que hace posible que un agente ejecutándose en tu máquina anfitriona edite código mientras los servicios dentro de Coast recogen los cambios en tiempo real.\n\n## El montaje compartido\n\n```text\nHost machine\n│\n├── ~/dev/my-app/ (project root)\n│ ├── src/\n│ ├── Coastfile\n│ ├── docker-compose.yml\n│ └── .worktrees/ (worktrees, gitignored)\n│ ├── feature-auth/\n│ └── feature-billing/\n│\n└── Docker daemon (host)\n │\n └── Coast: dev-1 (docker:dind)\n │\n ├── /host-project ← Docker bind mount of project root (RW, fixed)\n │\n ├── /workspace ← mount --bind /host-project (switchable)\n │ ├── src/ same files, same bytes, instant sync\n │ ├── Coastfile\n │ └── docker-compose.yml\n │\n └── Inner Docker daemon\n └── web service\n └── /app ← compose bind mount from /workspace/src\n```\n\nLa raíz del proyecto en el host se monta con permisos de lectura-escritura en `/host-project` dentro del [contenedor DinD](RUNTIMES_AND_SERVICES.md) cuando se crea el contenedor. Después de que el contenedor se inicia, un `mount --bind /host-project /workspace` dentro del contenedor crea la ruta de trabajo `/workspace` con propagación de montaje compartida (`mount --make-rshared`), de modo que los servicios internos de compose que hacen bind-mount de subdirectorios de `/workspace` vean el contenido correcto.\n\nEste enfoque en dos etapas existe por una razón: el bind mount de Docker en `/host-project` queda fijo en la creación del contenedor y no puede cambiarse sin recrear el contenedor. Pero el bind mount de Linux en `/workspace` dentro del contenedor puede desmontarse y volver a enlazarse a un subdirectorio diferente —un worktree— sin tocar el ciclo de vida del contenedor. Esto es lo que hace que `coast assign` sea rápido.\n\n`/workspace` es de lectura-escritura. Los cambios de archivos fluyen en ambas direcciones al instante. Guarda un archivo en el host y un servidor de desarrollo dentro de Coast lo detecta. Crea un archivo dentro de Coast y aparece en el host.\n\n## Agentes en el host y Coast\n\n```text\n┌─── Host machine ──────────────────────────────────────────┐\n│ │\n│ AI Agent (Cursor, Claude Code, etc.) │\n│ │ │\n│ ├── reads/writes files at /src/ │\n│ │ ↕ (instant, same filesystem) │\n│ ├── coast logs dev-1 --service web --tail 50 │\n│ ├── coast ps dev-1 │\n│ └── coast exec dev-1 -- npm test │\n│ │\n├───────────────────────────────────────────────────────────┤\n│ │\n│ Coast: dev-1 │\n│ └── /workspace/src/ ← same bytes as host project/src │\n│ └── web service picks up changes on save │\n│ │\n└───────────────────────────────────────────────────────────┘\n```\n\nDebido a que el sistema de archivos se comparte, un agente de codificación con IA que se ejecuta en el host puede editar archivos libremente y los servicios en ejecución dentro de Coast ven los cambios de inmediato. El agente no necesita ejecutarse dentro del contenedor de Coast —opera desde el host con normalidad.\n\nCuando el agente necesita información de ejecución —logs, estado de servicios, salida de pruebas— llama a comandos del CLI de Coast desde el host:\n\n- `coast logs dev-1 --service web --tail 50` para la salida del servicio (ver [Logs](LOGS.md))\n- `coast ps dev-1` para el estado del servicio (ver [Runtimes and Services](RUNTIMES_AND_SERVICES.md))\n- `coast exec dev-1 -- npm test` para ejecutar comandos dentro de Coast (ver [Exec & Docker](EXEC_AND_DOCKER.md))\n\nEsta es la ventaja arquitectónica fundamental: **la edición de código ocurre en el host, la ejecución ocurre en Coast, y el sistema de archivos compartido los conecta.** El agente en el host nunca necesita estar \"dentro\" de Coast para hacer su trabajo.\n\n## Cambio de worktree\n\nCuando `coast assign` cambia un Coast a un worktree diferente, vuelve a montar `/workspace` para que apunte a ese worktree de git en lugar de la raíz del proyecto:\n\n```text\ncoast assign dev-1 --worktree feature-auth\n\nBefore: /workspace ←──mount── /host-project (project root)\nAfter: /workspace ←──mount── /host-project/.worktrees/feature-auth (worktree)\n```\n\nEl worktree se crea en el host en `{project_root}/.worktrees/{worktree_name}`. El nombre del directorio `.worktrees` es configurable mediante `worktree_dir` en tu Coastfile y debería estar en tu `.gitignore`.\n\nSi el worktree es nuevo, Coast inicializa ciertos archivos ignorados por git desde la raíz del proyecto antes del remount. Enumera los archivos ignorados con `git ls-files --others --ignored --exclude-standard`, filtra directorios pesados comunes más cualquier `exclude_paths` configurado, y luego usa `rsync --files-from` con `--link-dest` para enlazar por hardlink los archivos seleccionados dentro del worktree. Coast registra esa inicialización en metadatos internos del worktree y la omite en asignaciones posteriores al mismo worktree a menos que la refresques explícitamente con `coast assign --force-sync`.\n\nDentro del contenedor, `/workspace` se desmonta de forma perezosa (lazy-unmounted) y se vuelve a enlazar al subdirectorio del worktree en `/host-project/.worktrees/{branch_name}`. Este remount es rápido —no recrea el contenedor DinD ni reinicia el daemon interno de Docker. Los servicios de compose y los servicios bare aún pueden recrearse o reiniciarse después del remount para que sus bind mounts se resuelvan a través del nuevo `/workspace`.\n\nLos directorios grandes de dependencias como `node_modules` no forman parte de esta ruta genérica de bootstrap. Esos normalmente se gestionan mediante cachés o volúmenes específicos del servicio.\n\nSi usas `[assign.rebuild_triggers]`, Coast también ejecuta `git diff --name-only ..` en el host para decidir si un servicio marcado como `rebuild` puede degradarse a `restart`. Consulta [Assign and Unassign](ASSIGN.md) y [Performance Optimizations](PERFORMANCE_OPTIMIZATIONS.md) para los detalles que afectan la latencia de assign.\n\n`coast unassign` revierte `/workspace` a `/host-project` (la raíz del proyecto). `coast start` después de un stop vuelve a aplicar el montaje correcto según si la instancia tiene un worktree asignado.\n\n## Todos los montajes\n\nCada contenedor de Coast tiene estos montajes:\n\n| Path | Type | Access | Purpose |\n|---|---|---|---|\n| `/workspace` | bind mount (in-container) | RW | Raíz del proyecto o worktree. Conmutable al asignar. |\n| `/host-project` | Docker bind mount | RW | Raíz del proyecto sin procesar. Fijo en la creación del contenedor. |\n| `/image-cache` | Docker bind mount | RO | Tarballs OCI predescargados desde `~/.coast/image-cache/`. |\n| `/coast-artifact` | Docker bind mount | RO | Artefacto de build con archivos de compose reescritos. |\n| `/coast-override` | Docker bind mount | RO | Overrides de compose generados para [servicios compartidos](SHARED_SERVICES.md). |\n| `/var/lib/docker` | Named volume | RW | Estado del daemon interno de Docker. Persiste a través de la eliminación del contenedor. |\n\nLos montajes de solo lectura son infraestructura: transportan el artefacto de build, las imágenes en caché y los overrides de compose que Coast genera. Interactúas con ellos indirectamente mediante `coast build` y el Coastfile. Los montajes de lectura-escritura son donde vive tu código y donde el daemon interno almacena su estado.\n", "concepts_and_terminology/LOGS.md": "# Registros\n\nLos servicios dentro de un Coast se ejecutan en contenedores anidados — tus servicios de compose son gestionados por un daemon de Docker interno dentro de un contenedor DinD. Esto significa que las herramientas de registro a nivel de host no pueden verlos. Si tu flujo de trabajo incluye un MCP de registros que lee los logs de Docker en el host, solo verá el contenedor DinD externo, no el servidor web, la base de datos o el worker que se ejecutan dentro de él.\n\nLa solución es `coast logs`. Cualquier agente o herramienta que necesite leer la salida de servicios desde una instancia de Coast debe usar la CLI de Coast en lugar del acceso a logs de Docker a nivel de host.\n\n## La contrapartida del MCP\n\nSi estás usando un agente de IA con un MCP de registros (una herramienta que captura logs de contenedores Docker desde tu host — ver [MCP Servers](MCP_SERVERS.md)), ese MCP no funcionará para servicios que se ejecutan dentro de un Coast. El daemon de Docker del host ve un contenedor por instancia de Coast — el contenedor DinD — y sus logs son solo la salida de arranque del daemon de Docker interno.\n\nPara capturar los logs reales de los servicios, indica a tu agente que use:\n\n```bash\ncoast logs --service --tail \n```\n\nPor ejemplo, si tu agente necesita inspeccionar por qué está fallando un servicio backend:\n\n```bash\ncoast logs dev-1 --service backend --tail 100\n```\n\nEsto es el equivalente de `docker compose logs` pero enrutado a través del daemon de Coast hacia el contenedor DinD interno. Si tienes reglas de agente o prompts del sistema que hagan referencia a un MCP de registros, tendrás que añadir una instrucción que anule este comportamiento cuando trabajes dentro de un Coast.\n\n## `coast logs`\n\nLa CLI proporciona varias formas de leer registros de una instancia de Coast:\n\n```bash\ncoast logs dev-1 # last 200 lines, all services\ncoast logs dev-1 --service web # last 200 lines, web only\ncoast logs dev-1 --tail 50 # last 50 lines, then follow\ncoast logs dev-1 --tail # all lines, then follow\ncoast logs dev-1 --service backend -f # follow mode (stream new entries)\ncoast logs dev-1 --service web --tail 100 # last 100 lines + follow\n```\n\nSin `--tail` o `-f`, el comando devuelve las últimas 200 líneas y sale. Con `--tail`, transmite la cantidad solicitada de líneas y luego continúa siguiendo la nueva salida en tiempo real. `-f` / `--follow` habilita el modo de seguimiento por sí solo.\n\nLa salida usa el formato de logs de compose con un prefijo de servicio en cada línea:\n\n```text\nweb | 2026/02/28 01:49:34 Listening on :3000\nbackend | 2026/02/28 01:49:34 [INFO] Server started on :8080\nbackend | 2026/02/28 01:49:34 [ProcessCreditsJob] starting at 2026-02-28T01:49:34Z\nredis | 1:M 28 Feb 2026 01:49:30.123 * Ready to accept connections\n```\n\nTambién puedes filtrar por servicio con la sintaxis posicional heredada (`coast logs dev-1 web`), pero se prefiere el flag `--service`.\n\n## Pestaña de Registros de Coastguard\n\nLa interfaz web de Coastguard ofrece una experiencia de visualización de logs más rica con transmisión en tiempo real mediante WebSocket.\n\n![Logs tab in Coastguard](../../assets/coastguard-logs.png)\n*La pestaña Logs de Coastguard transmitiendo la salida del servicio backend con filtrado por servicio y búsqueda.*\n\nLa pestaña Logs ofrece:\n\n- **Transmisión en tiempo real** — los logs llegan a través de una conexión WebSocket a medida que se producen, con un indicador de estado que muestra el estado de la conexión.\n- **Filtro de servicio** — un desplegable poblado a partir de los prefijos de servicio del flujo de logs. Selecciona un único servicio para enfocarte en su salida.\n- **Búsqueda** — filtra las líneas mostradas por texto o regex (activa el botón de asterisco para el modo regex). Los términos coincidentes se resaltan.\n- **Recuentos de líneas** — muestra líneas filtradas vs líneas totales (p. ej., \"200 / 971 lines\").\n- **Limpiar** — trunca los archivos de log del contenedor interno y reinicia el visor.\n- **Pantalla completa** — expande el visor de logs para llenar la pantalla.\n\nLas líneas de log se renderizan con soporte de color ANSI, resaltado por nivel de log (ERROR en rojo, WARN en ámbar, INFO en azul, DEBUG en gris), atenuación de marcas de tiempo y distintivos de servicio coloreados para diferenciar visualmente entre servicios.\n\nLos servicios compartidos que se ejecutan en el daemon del host tienen su propio visor de logs accesible desde la pestaña Shared Services. Consulta [Shared Services](SHARED_SERVICES.md) para más detalles.\n\n## Cómo funciona\n\nCuando ejecutas `coast logs`, el daemon ejecuta `docker compose logs` dentro del contenedor DinD vía `docker exec` y transmite la salida de vuelta a tu terminal (o a la UI de Coastguard vía WebSocket).\n\n```text\ncoast logs dev-1 --service web --tail 50\n │\n ├── CLI sends LogsRequest to daemon (Unix socket)\n │\n ├── Daemon resolves instance → container ID\n │\n ├── Daemon exec's into DinD container:\n │ docker compose logs --tail 50 --follow web\n │\n └── Output streams back chunk by chunk\n └── CLI prints to stdout / Coastguard renders in UI\n```\n\nPara [bare services](BARE_SERVICES.md), el daemon sigue (tail) los archivos de log en `/var/log/coast-services/` en lugar de llamar a `docker compose logs`. El formato de salida es el mismo (`service | line`), por lo que el filtrado por servicio funciona de forma idéntica en ambos casos.\n\n## Comandos relacionados\n\n- `coast ps ` — comprueba qué servicios se están ejecutando y su estado. Consulta [Runtimes and Services](RUNTIMES_AND_SERVICES.md).\n- [`coast exec `](EXEC_AND_DOCKER.md) — abre una shell dentro del contenedor de Coast para depuración manual.\n", "concepts_and_terminology/LOOKUP.md": "# Búsqueda\n\n`coast lookup` descubre qué instancias de Coast se están ejecutando para el directorio de trabajo actual del usuario que llama. Es el primer comando que un agente del lado del host debería ejecutar para orientarse: «Estoy editando código aquí, ¿con qué Coast(s) debería interactuar?»\n\n```bash\ncoast lookup\n```\n\nLookup detecta si estás dentro de un [worktree](ASSIGN.md) o en la raíz del proyecto, consulta al daemon por instancias coincidentes e imprime los resultados con puertos, URLs y comandos de ejemplo.\n\n## Por Qué Existe Esto\n\nUn agente de programación con IA que se ejecuta en el host (Cursor, Claude Code, Codex, etc.) edita archivos mediante el [sistema de archivos compartido](FILESYSTEM.md) y llama a comandos de Coast CLI para operaciones en tiempo de ejecución. Pero primero el agente necesita responder una pregunta básica: **¿qué instancia de Coast corresponde al directorio en el que estoy trabajando?**\n\nSin `coast lookup`, el agente tendría que ejecutar `coast ls`, analizar la tabla completa de instancias, averiguar en qué worktree está y hacer una referencia cruzada. `coast lookup` hace todo eso en un solo paso y devuelve una salida estructurada que los agentes pueden consumir directamente.\n\nEste comando debería incluirse en cualquier archivo SKILL.md, AGENTS.md o de reglas de nivel superior para flujos de trabajo de agentes que usen Coast. Es el punto de entrada para que un agente descubra su contexto de ejecución.\n\n## Modos de Salida\n\n### Predeterminado (legible para humanos)\n\n```bash\ncoast lookup\n```\n\n```text\nCoast instances for worktree feature/oauth (my-app):\n\n dev-1 running ★ checked out\n\n Primary URL: http://dev-1.localhost:62217\n\n SERVICE CANONICAL DYNAMIC\n ★ web 3000 62217\n api 8080 63889\n postgres 5432 55681\n\n Examples (exec starts at the workspace root where your Coastfile is, cd to your target directory first):\n coast exec dev-1 -- sh -c \"cd && \"\n coast logs dev-1 --service \n coast ps dev-1\n```\n\nLa sección de ejemplos recuerda a los agentes (y a los humanos) que `coast exec` comienza en la raíz del espacio de trabajo — el directorio donde vive el Coastfile. Para ejecutar un comando en un subdirectorio, haz `cd` hacia él dentro del exec.\n\n### Compacto (`--compact`)\n\nDevuelve un array JSON de nombres de instancias. Diseñado para scripts y herramientas de agentes que solo necesitan saber qué instancias deben tener como objetivo.\n\n```bash\ncoast lookup --compact\n```\n\n```text\n[\"dev-1\"]\n```\n\nMúltiples instancias en el mismo worktree:\n\n```text\n[\"dev-1\",\"dev-2\"]\n```\n\nSin coincidencias:\n\n```text\n[]\n```\n\n### JSON (`--json`)\n\nDevuelve la respuesta estructurada completa como JSON con formato (pretty-printed). Diseñado para agentes que necesitan puertos, URLs y estado en un formato legible por máquina.\n\n```bash\ncoast lookup --json\n```\n\n```json\n{\n \"project\": \"my-app\",\n \"worktree\": \"feature/oauth\",\n \"project_root\": \"/Users/dev/my-app\",\n \"instances\": [\n {\n \"name\": \"dev-1\",\n \"status\": \"Running\",\n \"checked_out\": true,\n \"branch\": \"feature/oauth\",\n \"primary_url\": \"http://dev-1.localhost:62217\",\n \"ports\": [\n { \"logical_name\": \"web\", \"canonical_port\": 3000, \"dynamic_port\": 62217, \"is_primary\": true },\n { \"logical_name\": \"api\", \"canonical_port\": 8080, \"dynamic_port\": 63889, \"is_primary\": false }\n ]\n }\n ]\n}\n```\n\n## Cómo Lo Resuelve\n\nLookup recorre hacia arriba desde el directorio de trabajo actual para encontrar el Coastfile más cercano, y luego determina en qué worktree estás:\n\n1. Si tu cwd está bajo `{project_root}/{worktree_dir}/{name}/...`, lookup encuentra las instancias asignadas a ese worktree.\n2. Si tu cwd es la raíz del proyecto (o cualquier directorio que no esté dentro de un worktree), lookup encuentra instancias **sin worktree asignado** — aquellas que aún apuntan a la raíz del proyecto.\n\nEsto significa que lookup también funciona desde subdirectorios. Si estás en `my-app/.worktrees/feature-oauth/src/api/`, lookup aún resuelve `feature-oauth` como el worktree.\n\n## Códigos de Salida\n\n| Code | Meaning |\n|------|---------|\n| 0 | Una o más instancias coincidentes encontradas |\n| 1 | Ninguna instancia coincidente (resultado vacío) |\n\nEsto hace que lookup sea usable en condicionales de shell:\n\n```bash\nif coast lookup > /dev/null 2>&1; then\n coast exec dev-1 -- sh -c \"cd src && npm test\"\nfi\n```\n\n## Para Flujos de Trabajo de Agentes\n\nEl patrón típico de integración de agentes:\n\n1. El agente empieza a trabajar en un directorio de worktree.\n2. El agente ejecuta `coast lookup` para descubrir nombres de instancias, puertos, URLs y comandos de ejemplo.\n3. El agente usa el nombre de la instancia para todos los comandos de Coast posteriores: `coast exec`, `coast logs`, `coast ps`.\n\n```text\n┌─── Agent (host machine) ────────────────────────────┐\n│ │\n│ 1. coast lookup │\n│ → instance names, ports, URLs, examples │\n│ 2. coast exec dev-1 -- sh -c \"cd src && npm test\" │\n│ 3. coast logs dev-1 --service web --tail 50 │\n│ 4. coast ps dev-1 │\n│ │\n└──────────────────────────────────────────────────────┘\n```\n\nSi el agente está trabajando en múltiples worktrees, ejecuta `coast lookup` desde cada directorio de worktree para resolver la instancia correcta para cada contexto.\n\nVer también [Filesystem](FILESYSTEM.md) para cómo los agentes del host interactúan con Coast, [Assign and Unassign](ASSIGN.md) para conceptos de worktree, y [Exec & Docker](EXEC_AND_DOCKER.md) para ejecutar comandos dentro de un Coast.\n", @@ -2856,13 +2921,20 @@ "concepts_and_terminology/SHARED_SERVICES.md": "# Servicios compartidos\n\nLos servicios compartidos son contenedores de base de datos e infraestructura (Postgres, Redis, MongoDB, etc.) que se ejecutan en tu daemon de Docker del host en lugar de dentro de un Coast. Las instancias de Coast se conectan a ellos a través de una red bridge, por lo que cada Coast se comunica con el mismo servicio en el mismo volumen del host.\n\n![Shared services in Coastguard](../../assets/coastguard-shared-services.png)\n*La pestaña de servicios compartidos de Coastguard que muestra Postgres, Redis y MongoDB administrados por el host.*\n\n## Cómo funcionan\n\nCuando declaras un servicio compartido en tu Coastfile, Coast lo inicia en el daemon del host y lo elimina de la pila de compose que se ejecuta dentro de cada contenedor de Coast. Luego, los Coasts se configuran para enrutar el tráfico del nombre del servicio de vuelta al contenedor compartido mientras se conserva el puerto del lado del contenedor del servicio dentro del Coast.\n\n```text\nHost Docker daemon\n |\n +--> postgres (host volume: infra_postgres_data)\n +--> redis (host volume: infra_redis_data)\n +--> mongodb (host volume: infra_mongodb_data)\n |\n +--> Coast: dev-1 --bridge network--> host postgres, redis, mongodb\n +--> Coast: dev-2 --bridge network--> host postgres, redis, mongodb\n```\n\nDebido a que los servicios compartidos reutilizan tus volúmenes existentes del host, cualquier dato que ya tengas de ejecutar `docker-compose up` localmente está disponible de inmediato para tus Coasts.\n\nEsta distinción importa cuando usas puertos mapeados:\n\n```toml\n[shared_services.postgis]\nimage = \"ghcr.io/baosystems/postgis:12-3.3\"\nports = [\"5433:5432\"]\n```\n\n- En el host, el servicio compartido se publica en `localhost:5433`.\n- Dentro de cada Coast, los contenedores de la aplicación siguen conectándose a `postgis:5432`.\n- Un entero simple como `5432` es una abreviatura del mapeo idéntico `\"5432:5432\"`.\n\n## Cuándo usar servicios compartidos\n\n- Tu proyecto tiene integraciones MCP que se conectan a una base de datos local — los servicios compartidos permiten que estas sigan funcionando sin descubrimiento dinámico de puertos. Si publicas el servicio compartido en el mismo puerto del host que ya usan tus herramientas (por ejemplo `ports = [5432]`), esas herramientas seguirán funcionando sin cambios. Si lo publicas en un puerto distinto del host (por ejemplo `\"5433:5432\"`), las herramientas del lado del host deben usar ese puerto del host mientras que los Coasts siguen usando el puerto del contenedor.\n- Quieres instancias de Coast más ligeras, ya que no necesitan ejecutar sus propios contenedores de base de datos.\n- No necesitas aislamiento de datos entre instancias de Coast (cada instancia ve los mismos datos).\n- Estás ejecutando agentes de programación en el host (consulta [Filesystem](FILESYSTEM.md)) y quieres que accedan al estado de la base de datos sin enrutar a través de [`coast exec`](EXEC_AND_DOCKER.md). Con servicios compartidos, las herramientas de base de datos y los MCP existentes del agente funcionan sin cambios.\n\nConsulta la página de [Topología de volúmenes](VOLUMES.md) para ver alternativas cuando sí necesitas aislamiento.\n\n## Advertencia sobre desambiguación de volúmenes\n\nLos nombres de los volúmenes de Docker no siempre son globalmente únicos. Si ejecutas `docker-compose up` desde varios proyectos diferentes, los volúmenes del host que Coast adjunta a los servicios compartidos pueden no ser los que esperas.\n\nAntes de iniciar Coasts con servicios compartidos, asegúrate de que el último `docker-compose up` que ejecutaste haya sido desde el proyecto que pretendes usar con Coasts. Esto garantiza que los volúmenes del host coincidan con lo que espera tu Coastfile.\n\n## Solución de problemas\n\nSi tus servicios compartidos parecen estar apuntando al volumen incorrecto del host:\n\n1. Abre la interfaz de [Coastguard](COASTGUARD.md) (`coast ui`).\n2. Navega a la pestaña **Shared Services**.\n3. Selecciona los servicios afectados y haz clic en **Remove**.\n4. Haz clic en **Refresh Shared Services** para recrearlos a partir de la configuración actual de tu Coastfile.\n\nEsto desmonta y recrea los contenedores de servicios compartidos, volviendo a adjuntarlos a los volúmenes correctos del host.\n", "concepts_and_terminology/TROUBLESHOOTING.md": "# Solución de problemas\n\nLa mayoría de los problemas con Coasts provienen de estado obsoleto, recursos Docker huérfanos o un daemon que se desincronizó. Esta página cubre la ruta de escalamiento de leve a nuclear.\n\n## Doctor\n\nSi algo se siente raro — las instancias aparecen como en ejecución pero nada responde, los puertos parecen atascados o la UI muestra datos obsoletos — comienza con `coast doctor`:\n\n```bash\ncoast doctor\n```\n\nDoctor analiza la base de datos de estado y Docker en busca de inconsistencias: registros de instancias huérfanos con contenedores faltantes, contenedores colgantes sin registro de estado y servicios compartidos marcados como en ejecución que en realidad están caídos. Arregla automáticamente lo que encuentra.\n\nPara previsualizar lo que haría sin cambiar nada:\n\n```bash\ncoast doctor --dry-run\n```\n\n## Reinicio del daemon\n\nSi el daemon en sí parece no responder o sospechas que está en un mal estado, reinícialo:\n\n```bash\ncoast daemon restart\n```\n\nEsto envía una señal de apagado ordenado, espera a que el daemon termine y arranca un proceso nuevo. Tus instancias y el estado se conservan.\n\n## Eliminar un solo proyecto\n\nSi el problema está aislado a un proyecto, puedes eliminar sus artefactos de build y los recursos Docker asociados sin afectar nada más:\n\n```bash\ncoast rm-build my-project\n```\n\nEsto elimina el directorio de artefactos del proyecto, imágenes Docker, volúmenes y contenedores. Primero pide confirmación. Pasa `--force` para omitir el aviso.\n\n## Imágenes faltantes de servicios compartidos\n\nSi `coast run` falla al crear un servicio compartido con un error como `No such image: postgres:15`, la imagen no está presente en el daemon de Docker de tu host.\n\nEsto ocurre con mayor frecuencia cuando tu `Coastfile` define `shared_services` como Postgres o Redis y Docker aún no ha descargado esas imágenes.\n\nDescarga la imagen faltante y luego ejecuta la instancia de nuevo:\n\n```bash\ndocker pull postgres:15\ndocker pull redis:7\ncoast run my-instance\n```\n\nSi no estás seguro de qué imagen falta, la salida del `coast run` que falla incluirá el nombre de la imagen en el error de Docker. Después de un intento de aprovisionamiento fallido, Coasts limpia automáticamente la instancia parcial, así que es normal ver que la instancia vuelva a `stopped`.\n\n## Restablecimiento de fábrica con Nuke\n\nCuando nada más funciona — o simplemente quieres una pizarra completamente limpia — `coast nuke` realiza un restablecimiento de fábrica completo:\n\n```bash\ncoast nuke\n```\n\nEsto hará lo siguiente:\n\n1. Detener el daemon `coastd`.\n2. Eliminar **todos** los contenedores Docker gestionados por coast.\n3. Eliminar **todos** los volúmenes Docker gestionados por coast.\n4. Eliminar **todas** las redes Docker gestionadas por coast.\n5. Eliminar **todas** las imágenes Docker de coast.\n6. Borrar por completo el directorio `~/.coast/` (base de datos de estado, builds, logs, secretos, caché de imágenes).\n7. Recrear `~/.coast/` y reiniciar el daemon para que coast vuelva a estar utilizable de inmediato.\n\nComo esto destruye todo, debes escribir `nuke` en el indicador de confirmación:\n\n```text\n$ coast nuke\nWARNING: This will permanently destroy ALL coast data:\n\n - Stop the coastd daemon\n - Remove all coast-managed Docker containers\n - Remove all coast-managed Docker volumes\n - Remove all coast-managed Docker networks\n - Remove all coast Docker images\n - Delete ~/.coast/ (state DB, builds, logs, secrets, image cache)\n\nType \"nuke\" to confirm:\n```\n\nPasa `--force` para omitir el aviso (útil en scripts):\n\n```bash\ncoast nuke --force\n```\n\nDespués de un nuke, coast queda listo para usarse — el daemon está ejecutándose y el directorio home existe. Solo necesitas volver a ejecutar `coast build` y `coast run` en tus proyectos.\n\n## Reportar errores\n\nSi encuentras un problema que no se resuelve con nada de lo anterior, incluye los logs del daemon al reportarlo:\n\n```bash\ncoast daemon logs\n```\n", "concepts_and_terminology/VOLUMES.md": "# Topología de volúmenes\n\nCoast ofrece tres estrategias de volúmenes que controlan cómo los servicios con muchos datos (bases de datos, cachés, etc.) almacenan y comparten sus datos entre instancias de Coast. Elegir la estrategia adecuada depende de cuánta aislación necesitas y cuánto overhead puedes tolerar.\n\n## Servicios compartidos\n\nLos [servicios compartidos](SHARED_SERVICES.md) se ejecutan en el daemon de Docker de tu host, fuera de cualquier contenedor de Coast. Servicios como Postgres, MongoDB y Redis permanecen en la máquina host y las instancias de Coast enrutan sus llamadas de vuelta al host a través de una red puente.\n\n```text\nHost machine\n |\n +--> Postgres (host daemon, existing volume)\n +--> Redis (host daemon, existing volume)\n |\n +--> Coast: dev-1 --connects to--> host Postgres, host Redis\n +--> Coast: dev-2 --connects to--> host Postgres, host Redis\n```\n\nNo hay aislación de datos entre instancias — cada Coast habla con la misma base de datos. A cambio obtienes:\n\n- Instancias de Coast más livianas ya que no ejecutan sus propios contenedores de base de datos.\n- Tus volúmenes existentes del host se reutilizan directamente, por lo que cualquier dato que ya tengas está disponible de inmediato.\n- Las integraciones de MCP que se conectan a tu base de datos local siguen funcionando listas para usar.\n\nEsto se configura en tu [Coastfile](COASTFILE_TYPES.md) bajo `[shared_services]`.\n\n## Volúmenes compartidos\n\nLos volúmenes compartidos montan un único volumen de Docker que se comparte entre todas las instancias de Coast. Los servicios en sí (Postgres, Redis, etc.) se ejecutan dentro de cada contenedor de Coast, pero todos leen y escriben en el mismo volumen subyacente.\n\n```text\nCoast: dev-1 --mounts--> shared volume \"my-project-postgres\"\nCoast: dev-2 --mounts--> shared volume \"my-project-postgres\"\n```\n\nEsto aísla tus datos de Coast de lo que haya en tu máquina host, pero las instancias siguen compartiendo datos entre sí. Esto es útil cuando quieres una separación limpia de tu entorno de desarrollo en el host sin el overhead de volúmenes por instancia.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"shared\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## Volúmenes aislados\n\nLos volúmenes aislados le dan a cada instancia de Coast su propio volumen independiente. No se comparte ningún dato entre instancias ni con el host. Cada instancia comienza vacía (o desde una instantánea — ver abajo) y diverge de manera independiente.\n\n```text\nCoast: dev-1 --mounts--> volume \"dev-1-postgres\"\nCoast: dev-2 --mounts--> volume \"dev-2-postgres\"\n```\n\nEsta es la mejor opción para proyectos con muchas pruebas de integración y que necesitan una verdadera aislación de volúmenes entre entornos paralelos. La contrapartida es un inicio más lento y builds de Coast más grandes, ya que cada instancia mantiene su propia copia de los datos.\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\n## Creación de instantáneas\n\nTanto las estrategias compartida como aislada comienzan con volúmenes vacíos de forma predeterminada. Si quieres que las instancias comiencen con una copia de un volumen existente del host, establece `snapshot_source` con el nombre del volumen de Docker desde el cual copiar:\n\n```toml\n[volumes.postgres_data]\nstrategy = \"isolated\"\nsnapshot_source = \"infra_postgres_data\"\nservice = \"postgres\"\nmount = \"/var/lib/postgresql/data\"\n```\n\nLa instantánea se toma en el [momento de build](BUILDS.md). Después de la creación, el volumen de cada instancia diverge de manera independiente — las mutaciones no se propagan de vuelta a la fuente ni a otras instancias.\n\nCoast aún no admite la creación de instantáneas en tiempo de ejecución (p. ej., crear una instantánea de un volumen desde una instancia en ejecución). Esto está planeado para una versión futura.\n", - "harnesses/README.md": "# Arneses\n\nCada arnés crea worktrees de git en una ubicación diferente. En Coasts, el\narreglo [`worktree_dir`](../coastfiles/WORKTREE_DIR.md) le indica dónde buscar --\nincluyendo rutas externas como `~/.codex/worktrees` que requieren montajes\nbind adicionales.\n\nCada arnés también tiene sus propias convenciones para instrucciones a nivel de proyecto, skills y comandos. La matriz a continuación muestra qué admite cada arnés para que sepas dónde poner la guía para Coasts. Cada página cubre la configuración del Coastfile, la estructura de archivos recomendada y cualquier advertencia específica de ese arnés.\n\nSi un repositorio se usa desde varios arneses, consulta [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n\n| Harness | Worktree location | Project instructions | Skills | Commands | Page |\n|---------|-------------------|----------------------|--------|----------|------|\n| OpenAI Codex | `~/.codex/worktrees` | `AGENTS.md` | `.agents/skills/` | Skills surface as `/` commands | [Codex](CODEX.md) |\n| Claude Code | `.claude/worktrees` | `CLAUDE.md` | `.claude/skills/` | `.claude/commands/` | [Claude Code](CLAUDE_CODE.md) |\n| Cursor | `~/.cursor/worktrees/` | `AGENTS.md` or `.cursor/rules/` | `.cursor/skills/` or `.agents/skills/` | `.cursor/commands/` | [Cursor](CURSOR.md) |\n| Conductor | `~/conductor/workspaces/` | `CLAUDE.md` | -- | -- | [Conductor](CONDUCTOR.md) |\n| T3 Code | `~/.t3/worktrees/` | `AGENTS.md` | `.agents/skills/` | -- | [T3 Code](T3_CODE.md) |\n\n## Skills vs Commands\n\nLos skills y los comandos te permiten definir un flujo de trabajo reutilizable de `/coasts`. Puedes usar uno u ambos, según lo que admita el arnés.\n\nSi tu arnés admite comandos y quieres un punto de entrada explícito para `/coasts`,\nuna opción sencilla es agregar un comando que reutilice el skill.\nLos comandos se invocan explícitamente por nombre, así que sabes exactamente cuándo\nse ejecuta el flujo de trabajo `/coasts`. Los skills también pueden cargarse automáticamente por el agente\nsegún el contexto, lo cual es útil pero significa que tienes menos control sobre cuándo\nse incorporan las instrucciones.\n\nPuedes usar ambos. Si lo haces, deja que el comando reutilice el skill en lugar de\nmantener una copia separada del flujo de trabajo.\n\nSi el arnés solo admite skills (T3 Code), usa un skill. Si no admite\nninguno de los dos (Conductor), coloca el flujo de trabajo `/coasts` directamente en el archivo\nde instrucciones del proyecto.\n", - "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) crea\nworktrees dentro del proyecto en `.claude/worktrees/`. Debido a que ese directorio\nvive dentro del repo, Coasts puede descubrir y asignar worktrees de Claude Code\nsin ningún bind mount externo.\n\nClaude Code también es el harness aquí con la división más clara entre tres\ncapas para Coasts:\n\n- `CLAUDE.md` para reglas cortas, siempre activas, para trabajar con Coasts\n- `.claude/skills/coasts/SKILL.md` para el flujo de trabajo reutilizable `/coasts`\n- `.claude/commands/coasts.md` solo cuando quieras un archivo de comando como\n punto de entrada adicional\n\n## Configuración\n\nAgrega `.claude/worktrees` a `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\nDebido a que `.claude/worktrees` es relativo al proyecto, no se necesita\nningún bind mount externo.\n\n## Dónde va la guía de Coasts\n\n### `CLAUDE.md`\n\nPon aquí las reglas para Coasts que deberían aplicarse en cada tarea. Mantén esto corto y\noperativo:\n\n- ejecutar `coast lookup` antes del primer comando de runtime en una sesión\n- usar `coast exec` para pruebas, builds y comandos de servicio\n- usar `coast ps` y `coast logs` para retroalimentación del runtime\n- preguntar antes de crear o reasignar un Coast cuando no exista una coincidencia\n\n### `.claude/skills/coasts/SKILL.md`\n\nPon aquí el flujo de trabajo reutilizable `/coasts`. Este es el lugar correcto para un flujo\nque:\n\n1. ejecuta `coast lookup` y reutiliza el Coast coincidente\n2. recurre a `coast ls` cuando no hay coincidencia\n3. ofrece `coast run`, `coast assign`, `coast unassign`, `coast checkout`, y\n `coast ui`\n4. usa la CLI de Coast directamente como el contrato en lugar de envolverla\n\nSi este repo también usa Codex, T3 Code, o Cursor, consulta\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) y mantén la skill canónica en\n`.agents/skills/coasts/`, luego expónla a Claude Code.\n\n### `.claude/commands/coasts.md`\n\nClaude Code también admite archivos de comandos del proyecto. Para docs sobre Coasts, trata\nesto como opcional:\n\n- úsalo solo cuando específicamente quieras un archivo de comando\n- una opción simple es hacer que el comando reutilice la misma skill\n- si le das al comando sus propias instrucciones separadas, estás asumiendo una\n segunda copia del flujo de trabajo para mantener\n\n## Estructura de ejemplo\n\n### Solo Claude Code\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\nSi este repo también usa Codex, T3 Code, o Cursor, usa el patrón compartido en\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) en lugar de duplicarlo aquí,\nporque la guía específica duplicada por proveedor se vuelve más difícil de mantener sincronizada cada\nvez que agregas otro harness.\n\n## Lo que hace Coasts\n\n- **Ejecutar** — `coast run ` crea una nueva instancia de Coast a partir del último build. Usa `coast run -w ` para crear y asignar un worktree de Claude Code en un solo paso. Consulta [Run](../concepts_and_terminology/RUN.md).\n- **Descubrimiento** — Coasts lee `.claude/worktrees` como cualquier otro directorio\n local de worktree.\n- **Nomenclatura** — Los worktrees de Claude Code siguen el mismo comportamiento\n de nomenclatura de worktrees locales que otros worktrees dentro del repo en la UI y CLI de Coasts.\n- **Asignar** — `coast assign` puede cambiar `/workspace` a un worktree de Claude Code\n sin ninguna indirección de bind-mount externo.\n- **Sincronización de gitignored** — Funciona normalmente porque los worktrees viven dentro del\n árbol del repositorio.\n- **Detección de huérfanos** — Si Claude Code elimina un worktree, Coasts puede detectar\n el gitdir faltante y desasignarlo cuando sea necesario.\n\n## Ejemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — worktrees de Claude Code\n- `~/.codex/worktrees/` — worktrees de Codex si también usas Codex en este repo\n\n## Limitaciones\n\n- Si duplicas el mismo flujo de trabajo `/coasts` entre `CLAUDE.md`,\n `.claude/skills`, y `.claude/commands`, esas copias divergirán. Mantén\n `CLAUDE.md` corto y mantén el flujo de trabajo reutilizable en una sola skill.\n- Si quieres que un repo funcione limpiamente en múltiples harnesses, prefiere el patrón compartido\n en [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", - "harnesses/CODEX.md": "# Codex\n\n[Codex](https://developers.openai.com/codex/app/worktrees/) crea worktrees en `$CODEX_HOME/worktrees` (normalmente `~/.codex/worktrees`). Cada worktree vive bajo un directorio con hash opaco como `~/.codex/worktrees/a0db/project-name`, comienza en un HEAD desacoplado y se limpia automáticamente según la política de retención de Codex.\n\nDe la [documentación de Codex](https://developers.openai.com/codex/app/worktrees/):\n\n> ¿Puedo controlar dónde se crean los worktrees?\n> No por ahora. Codex crea worktrees en `$CODEX_HOME/worktrees` para poder administrarlos de forma consistente.\n\nDebido a que estos worktrees viven fuera de la raíz del proyecto, Coasts necesita una configuración explícita para descubrirlos y montarlos.\n\n## Configuración\n\nAgrega `~/.codex/worktrees` a `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nCoasts expande `~` en tiempo de ejecución y trata cualquier ruta que comience con `~/` o `/` como externa. Consulta [Directorios de Worktree](../coastfiles/WORKTREE_DIR.md) para más detalles.\n\nDespués de cambiar `worktree_dir`, las instancias existentes deben **recrearse** para que el bind mount surta efecto:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nLa lista de worktrees se actualiza de inmediato (Coasts lee el nuevo Coastfile), pero asignar a un worktree de Codex requiere el bind mount dentro del contenedor.\n\n## Dónde va la guía de Coasts\n\nUsa el archivo de instrucciones del proyecto de Codex y la disposición compartida de skills para trabajar con Coasts:\n\n- coloca las reglas cortas de Coast Runtime en `AGENTS.md`\n- coloca el flujo reutilizable de `/coasts` en `.agents/skills/coasts/SKILL.md`\n- Codex expone esa skill como el comando `/coasts`\n- si usas metadatos específicos de Codex, mantenlos junto a la skill en\n `.agents/skills/coasts/agents/openai.yaml`\n- no crees un archivo de comandos del proyecto separado solo para documentación sobre Coasts; la skill es la superficie reutilizable\n- si este repositorio también usa Cursor o Claude Code, mantén la skill canónica en\n `.agents/skills/` y expónla desde allí. Consulta\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) y\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\nPor ejemplo, un `.agents/skills/coasts/agents/openai.yaml` mínimo podría verse\nasí:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\nEso mantiene la skill visible en Codex con una etiqueta más agradable y hace que `/coasts` sea un comando explícito. Solo agrega `dependencies.tools` si la skill también necesita servidores MCP u otra integración de herramientas administrada por OpenAI.\n\n## Qué hace Coasts\n\n- **Run** -- `coast run ` crea una nueva instancia de Coast a partir de la compilación más reciente. Usa `coast run -w ` para crear y asignar un worktree de Codex en un solo paso. Consulta [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** -- Al crear el contenedor, Coasts monta\n `~/.codex/worktrees` dentro del contenedor en `/host-external-wt/{index}`.\n- **Descubrimiento** -- `git worktree list --porcelain` está limitado al repositorio, por lo que solo aparecen los worktrees de Codex que pertenecen al proyecto actual, aunque el directorio contenga worktrees de muchos proyectos.\n- **Nomenclatura** -- Los worktrees con HEAD desacoplado se muestran como su ruta relativa dentro del directorio externo (`a0db/my-app`, `eca7/my-app`). Los worktrees basados en ramas muestran el nombre de la rama.\n- **Asignación** -- `coast assign` vuelve a montar `/workspace` desde la ruta del bind mount externo.\n- **Sincronización de archivos ignorados por Git** -- Se ejecuta en el sistema de archivos del host con rutas absolutas, funciona sin el bind mount.\n- **Detección de huérfanos** -- El watcher de git escanea directorios externos\n recursivamente, filtrando por punteros gitdir de `.git`. Si Codex elimina un\n worktree, Coasts desasigna automáticamente la instancia.\n\n## Ejemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code (local, sin manejo especial)\n- `~/.codex/worktrees/` -- Codex (externo, montado con bind)\n\n## Limitaciones\n\n- Codex puede limpiar worktrees en cualquier momento. La detección de huérfanos en Coasts maneja esto correctamente.\n", - "harnesses/CONDUCTOR.md": "# Conductor\n\n[Conductor](https://conductor.build/) ejecuta agentes paralelos de Claude Code, cada uno en su propio espacio de trabajo aislado. Los espacios de trabajo son `git worktrees` almacenados en `~/conductor/workspaces//`. Cada espacio de trabajo se extrae en una rama con nombre.\n\nDebido a que estos worktrees viven fuera de la raíz del proyecto, Coasts necesita una configuración explícita para descubrirlos y montarlos.\n\n## Configuración\n\nAgrega `~/conductor/workspaces/` a `worktree_dir`. A diferencia de Codex (que almacena todos los proyectos bajo un único directorio plano), Conductor anida los worktrees bajo un subdirectorio por proyecto, por lo que la ruta debe incluir el nombre del proyecto. En el ejemplo de abajo, `my-app` debe coincidir con el nombre real de la carpeta bajo `~/conductor/workspaces/` para tu repositorio.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nConductor te permite configurar la ruta de los espacios de trabajo por repositorio, por lo que el valor predeterminado `~/conductor/workspaces` puede no coincidir con tu configuración. Revisa la configuración de tu repositorio de Conductor para encontrar la ruta real y ajústala en consecuencia — el principio es el mismo sin importar dónde se encuentre el directorio.\n\nCoasts expande `~` en tiempo de ejecución y trata cualquier ruta que comience con `~/` o `/` como externa. Consulta [Directorios de Worktree](../coastfiles/WORKTREE_DIR.md) para\nmás detalles.\n\nDespués de cambiar `worktree_dir`, las instancias existentes deben **recrearse** para que el montaje bind surta efecto:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nLa lista de worktrees se actualiza de inmediato (Coasts lee el nuevo Coastfile), pero\nasignar a un worktree de Conductor requiere el montaje bind dentro del contenedor.\n\n## Dónde va la guía de Coasts\n\nTrata a Conductor como su propio harness para trabajar con Coasts:\n\n- pon las reglas cortas de Coast Runtime en `CLAUDE.md`\n- usa scripts de Configuración del Repositorio de Conductor para comportamiento\n de configuración o ejecución que sea realmente específico de Conductor\n- no asumas aquí el comportamiento completo de comandos de proyecto o skills de\n proyecto de Claude Code\n- si agregas un comando y no aparece, cierra y vuelve a abrir por completo\n Conductor antes de volver a probar\n- si este repositorio también usa otros harnesses, consulta\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) y\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md) para formas de mantener\n el flujo de trabajo compartido de `/coasts` en un solo lugar\n\n## Qué hace Coasts\n\n- **Run** — `coast run ` crea una nueva instancia de Coast a partir de la compilación más reciente. Usa `coast run -w ` para crear y asignar un worktree de Conductor en un solo paso. Consulta [Run](../concepts_and_terminology/RUN.md).\n- **Montaje bind** — Al crear el contenedor, Coasts monta\n `~/conductor/workspaces/` dentro del contenedor en\n `/host-external-wt/{index}`.\n- **Descubrimiento** — `git worktree list --porcelain` tiene alcance de repositorio, por lo que solo aparecen los worktrees que pertenecen al proyecto actual.\n- **Nombres** — Los worktrees de Conductor usan ramas con nombre, por lo que aparecen por nombre de rama en la interfaz y la CLI de Coasts (por ejemplo, `scroll-to-bottom-btn`). Una rama solo puede estar extraída en un espacio de trabajo de Conductor a la vez.\n- **Asignación** — `coast assign` vuelve a montar `/workspace` desde la ruta de montaje bind externa.\n- **Sincronización de gitignored** — Se ejecuta en el sistema de archivos del host con rutas absolutas, funciona sin el montaje bind.\n- **Detección de huérfanos** — El observador de git escanea directorios externos\n de forma recursiva, filtrando por punteros `gitdir` de `.git`. Si Conductor\n archiva o elimina un espacio de trabajo, Coasts desasigna automáticamente la instancia.\n\n## Ejemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor (externo, montado con bind; reemplaza `my-app` por el nombre de la carpeta de tu repositorio)\n\n## Variables de entorno de Conductor\n\n- Evita depender de variables de entorno específicas de Conductor (p. ej.,\n `CONDUCTOR_PORT`, `CONDUCTOR_WORKSPACE_PATH`) para la configuración en tiempo de ejecución\n dentro de Coasts. Coasts administra puertos, rutas de espacios de trabajo y descubrimiento de servicios\n de forma independiente — usa `[ports]` del Coastfile y `coast exec` en su lugar.\n", - "harnesses/CURSOR.md": "# Cursor\n\n[Cursor](https://cursor.com/docs/agent/overview) puede trabajar directamente en tu\ncheckout actual, y su función Parallel Agents también puede crear git\nworktrees bajo `~/.cursor/worktrees//`.\n\nPara la documentación sobre Coasts, eso significa que hay dos casos de configuración:\n\n- si solo estás usando Cursor en el checkout actual, no se requiere ninguna entrada\n `worktree_dir` específica de Cursor\n- si usas Cursor Parallel Agents, añade el directorio de worktrees de Cursor a\n `worktree_dir` para que Coasts pueda descubrir y asignar esos worktrees\n\n## Configuración\n\n### Solo checkout actual\n\nSi Cursor solo está editando el checkout que ya abriste, Coasts no necesita\nninguna ruta de worktree especial específica de Cursor. Coasts tratará ese\ncheckout como cualquier otra raíz de repositorio local.\n\n### Cursor Parallel Agents\n\nSi usas Parallel Agents, añade `~/.cursor/worktrees/` a\n`worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nCursor almacena el worktree de cada agente bajo ese directorio por proyecto. Coasts\nexpande `~` en tiempo de ejecución y trata la ruta como externa, por lo que las\ninstancias existentes deben recrearse para que el bind mount surta efecto:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nLa lista de worktrees se actualiza inmediatamente después del cambio en el Coastfile, pero\nasignar a un worktree de Cursor Parallel Agent requiere el bind mount externo\ndentro del contenedor.\n\n## Dónde va la guía de Coasts\n\n### `AGENTS.md` o `.cursor/rules/coast.md`\n\nPon aquí las reglas breves y siempre activas de Coast Runtime:\n\n- usa `AGENTS.md` si quieres las instrucciones de proyecto más portables\n- usa `.cursor/rules/coast.md` si quieres reglas de proyecto nativas de Cursor y\n compatibilidad con la interfaz de configuración\n- no dupliques el mismo bloque de Coast Runtime en ambos salvo que tengas una\n razón clara\n\n### `.cursor/skills/coasts/SKILL.md` o `.agents/skills/coasts/SKILL.md` compartido\n\nPon aquí el flujo de trabajo reutilizable `/coasts`:\n\n- para un repositorio solo de Cursor, `.cursor/skills/coasts/SKILL.md` es un lugar natural\n- para un repositorio con múltiples harnesses, mantén la skill canónica en\n `.agents/skills/coasts/SKILL.md`; Cursor puede cargarla directamente\n- la skill debe ser dueña del flujo de trabajo real de `/coasts`: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout` y `coast ui`\n\n### `.cursor/commands/coasts.md`\n\nCursor también admite comandos de proyecto. Para la documentación sobre Coasts, trata los comandos como\nopcionales:\n\n- añade un comando solo cuando quieras un punto de entrada explícito `/coasts`\n- una opción sencilla es hacer que el comando reutilice la misma skill\n- si das al comando sus propias instrucciones separadas, estás asumiendo\n una segunda copia del flujo de trabajo para mantener\n\n### `.cursor/worktrees.json`\n\nUsa `.cursor/worktrees.json` para el bootstrap de worktrees propio de Cursor, no para la\npolítica de Coasts:\n\n- instalar dependencias\n- copiar o enlazar simbólicamente archivos `.env`\n- ejecutar migraciones de base de datos u otros pasos de bootstrap de una sola vez\n\nNo muevas las reglas de Coast Runtime ni el flujo de trabajo del Coast CLI a\n`.cursor/worktrees.json`.\n\n## Ejemplo de estructura\n\n### Solo Cursor\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # opcional\n.cursor/rules/coast.md # alternativa opcional a AGENTS.md\n.cursor/worktrees.json # opcional, para bootstrap de Parallel Agents\n```\n\n### Cursor más otros harnesses\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # opcional\n```\n\n## Qué hace Coasts\n\n- **Run** — `coast run ` crea una nueva instancia de Coast a partir de la compilación más reciente. Usa `coast run -w ` para crear y asignar un worktree de Cursor en un solo paso. Consulta [Run](../concepts_and_terminology/RUN.md).\n- **Checkout actual** — No se requiere ningún manejo especial de Cursor cuando Cursor está\n trabajando directamente en el repositorio que abriste.\n- **Bind mount** — Para Parallel Agents, Coasts monta\n `~/.cursor/worktrees/` en el contenedor en\n `/host-external-wt/{index}`.\n- **Descubrimiento** — `git worktree list --porcelain` sigue teniendo alcance de repositorio, por lo que Coasts\n solo muestra los worktrees de Cursor que pertenecen al proyecto actual.\n- **Nombres** — Los worktrees de Cursor Parallel Agent aparecen por sus nombres de rama en\n la CLI y la UI de Coasts.\n- **Assign** — `coast assign` vuelve a montar `/workspace` desde la ruta del bind mount\n externo cuando se selecciona un worktree de Cursor.\n- **Sincronización de ignorados por Git** — Sigue funcionando en el sistema de archivos del host con rutas\n absolutas.\n- **Detección de huérfanos** — Si Cursor limpia worktrees antiguos, Coasts puede detectar\n el gitdir faltante y desasignarlos cuando sea necesario.\n\n## Ejemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — worktrees de Claude Code\n- `~/.codex/worktrees/` — worktrees de Codex\n- `~/.cursor/worktrees/my-app/` — worktrees de Cursor Parallel Agent\n\n## Limitaciones\n\n- Si no estás usando Cursor Parallel Agents, no añadas\n `~/.cursor/worktrees/` solo porque casualmente estés editando en\n Cursor.\n- Mantén las reglas de Coast Runtime en un único lugar siempre activo: `AGENTS.md` o\n `.cursor/rules/coast.md`. Duplicar ambos invita a la divergencia.\n- Mantén el flujo de trabajo reutilizable `/coasts` en una skill. `.cursor/worktrees.json` es\n para el bootstrap de Cursor, no para la política de Coasts.\n- Si un repositorio se comparte entre Cursor, Codex, Claude Code o T3 Code, prefiere\n la estructura compartida en [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", + "harnesses/README.md": "# Arneses\n\nCada arnés crea worktrees de git en una ubicación diferente. En Coasts, el\narreglo [`worktree_dir`](../coastfiles/WORKTREE_DIR.md) le indica dónde buscar --\nincluyendo rutas externas como `~/.codex/worktrees` que requieren montajes\nbind adicionales.\n\nCada arnés también tiene sus propias convenciones para instrucciones a nivel de proyecto, skills y comandos. La matriz a continuación muestra qué admite cada arnés para que sepas dónde poner la guía para Coasts. Cada página cubre la configuración del Coastfile, la estructura de archivos recomendada y cualquier advertencia específica de ese arnés.\n\nSi un repositorio se usa desde varios arneses, consulta [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n\n| Harness | Worktree location | Project instructions | Skills | Commands | Page |\n|---------|-------------------|----------------------|--------|----------|------|\n| OpenAI Codex | `~/.codex/worktrees` | `AGENTS.md` | `.agents/skills/` | Skills surface as `/` commands | [Codex](CODEX.md) |\n| Claude Code | `.claude/worktrees` | `CLAUDE.md` | `.claude/skills/` | `.claude/commands/` | [Claude Code](CLAUDE_CODE.md) |\n| Cursor | `~/.cursor/worktrees/` | `AGENTS.md` or `.cursor/rules/` | `.cursor/skills/` or `.agents/skills/` | `.cursor/commands/` | [Cursor](CURSOR.md) |\n| Conductor | `~/conductor/workspaces/` | `CLAUDE.md` | -- | -- | [Conductor](CONDUCTOR.md) |\n| T3 Code | `~/.t3/worktrees/` | `AGENTS.md` | `.agents/skills/` | -- | [T3 Code](T3_CODE.md) |\n| Shep | `~/.shep/repos/*/wt` | `CLAUDE.md` | `.agents/skills/` or `.claude/skills/` | -- | [Shep](SHEP.md) |\n\n## Skills vs Commands\n\nLos skills y los comandos te permiten definir un flujo de trabajo reutilizable de `/coasts`. Puedes usar uno u ambos, según lo que admita el arnés.\n\nSi tu arnés admite comandos y quieres un punto de entrada explícito para `/coasts`,\nuna opción sencilla es agregar un comando que reutilice el skill.\nLos comandos se invocan explícitamente por nombre, así que sabes exactamente cuándo\nse ejecuta el flujo de trabajo `/coasts`. Los skills también pueden cargarse automáticamente por el agente\nsegún el contexto, lo cual es útil pero significa que tienes menos control sobre cuándo\nse incorporan las instrucciones.\n\nPuedes usar ambos. Si lo haces, deja que el comando reutilice el skill en lugar de\nmantener una copia separada del flujo de trabajo.\n\nSi el arnés solo admite skills (T3 Code), usa un skill. Si no admite\nninguno de los dos (Conductor), coloca el flujo de trabajo `/coasts` directamente en el archivo\nde instrucciones del proyecto.\n", + "harnesses/CLAUDE_CODE.md": "# Claude Code\n\n## Configuración rápida\n\nRequiere el [Coast CLI](../GETTING_STARTED.md). Copia este prompt en el chat de tu\nagente para configurar Coasts automáticamente:\n\n```prompt-copy\nclaude_code_setup_prompt.txt\n```\n\nTambién puedes obtener el contenido de la skill desde la CLI: `coast skills-prompt`.\n\nDespués de la configuración, **inicia una nueva sesión de Claude Code** — las skills y los cambios en `CLAUDE.md`\nse cargan al iniciar la sesión.\n\n---\n\n[Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) crea\nworktrees dentro del proyecto en `.claude/worktrees/`. Debido a que ese directorio\nvive dentro del repo, Coasts puede descubrir y asignar worktrees de Claude Code\nsin ningún bind mount externo.\n\nClaude Code también es el harness aquí con la división más clara entre tres\ncapas para Coasts:\n\n- `CLAUDE.md` para reglas cortas, siempre activas, para trabajar con Coasts\n- `.claude/skills/coasts/SKILL.md` para el flujo de trabajo reutilizable `/coasts`\n- `.claude/commands/coasts.md` solo cuando quieras un archivo de comando como\n punto de entrada adicional\n\n## Configuración\n\nAgrega `.claude/worktrees` a `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\"]\n```\n\nDebido a que `.claude/worktrees` es relativo al proyecto, no se necesita\nningún bind mount externo.\n\n## Dónde va la guía de Coasts\n\n### `CLAUDE.md`\n\nPon aquí las reglas para Coasts que deberían aplicarse en cada tarea. Mantén esto corto y\noperativo:\n\n- ejecutar `coast lookup` antes del primer comando de runtime en una sesión\n- usar `coast exec` para pruebas, builds y comandos de servicio\n- usar `coast ps` y `coast logs` para retroalimentación del runtime\n- preguntar antes de crear o reasignar un Coast cuando no exista una coincidencia\n\n### `.claude/skills/coasts/SKILL.md`\n\nPon aquí el flujo de trabajo reutilizable `/coasts`. Este es el lugar correcto para un flujo\nque:\n\n1. ejecuta `coast lookup` y reutiliza el Coast coincidente\n2. recurre a `coast ls` cuando no hay coincidencia\n3. ofrece `coast run`, `coast assign`, `coast unassign`, `coast checkout`, y\n `coast ui`\n4. usa la CLI de Coast directamente como el contrato en lugar de envolverla\n\nSi este repo también usa Codex, T3 Code, o Cursor, consulta\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) y mantén la skill canónica en\n`.agents/skills/coasts/`, luego expónla a Claude Code.\n\n### `.claude/commands/coasts.md`\n\nClaude Code también admite archivos de comandos del proyecto. Para docs sobre Coasts, trata\nesto como opcional:\n\n- úsalo solo cuando específicamente quieras un archivo de comando\n- una opción simple es hacer que el comando reutilice la misma skill\n- si le das al comando sus propias instrucciones separadas, estás asumiendo una\n segunda copia del flujo de trabajo para mantener\n\n## Estructura de ejemplo\n\n### Solo Claude Code\n\n```text\nCLAUDE.md\n.claude/worktrees/\n.claude/skills/coasts/SKILL.md\n```\n\nSi este repo también usa Codex, T3 Code, o Cursor, usa el patrón compartido en\n[Multiple Harnesses](MULTIPLE_HARNESSES.md) en lugar de duplicarlo aquí,\nporque la guía específica duplicada por proveedor se vuelve más difícil de mantener sincronizada cada\nvez que agregas otro harness.\n\n## Lo que hace Coasts\n\n- **Ejecutar** — `coast run ` crea una nueva instancia de Coast a partir del último build. Usa `coast run -w ` para crear y asignar un worktree de Claude Code en un solo paso. Consulta [Run](../concepts_and_terminology/RUN.md).\n- **Descubrimiento** — Coasts lee `.claude/worktrees` como cualquier otro directorio\n local de worktree.\n- **Nomenclatura** — Los worktrees de Claude Code siguen el mismo comportamiento\n de nomenclatura de worktrees locales que otros worktrees dentro del repo en la UI y CLI de Coasts.\n- **Asignar** — `coast assign` puede cambiar `/workspace` a un worktree de Claude Code\n sin ninguna indirección de bind-mount externo.\n- **Sincronización de gitignored** — Funciona normalmente porque los worktrees viven dentro del\n árbol del repositorio.\n- **Detección de huérfanos** — Si Claude Code elimina un worktree, Coasts puede detectar\n el gitdir faltante y desasignarlo cuando sea necesario.\n\n## Ejemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — worktrees de Claude Code\n- `~/.codex/worktrees/` — worktrees de Codex si también usas Codex en este repo\n\n## Limitaciones\n\n- Si duplicas el mismo flujo de trabajo `/coasts` entre `CLAUDE.md`,\n `.claude/skills`, y `.claude/commands`, esas copias divergirán. Mantén\n `CLAUDE.md` corto y mantén el flujo de trabajo reutilizable en una sola skill.\n- Si quieres que un repo funcione limpiamente en múltiples harnesses, prefiere el patrón compartido\n en [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", + "harnesses/CODEX.md": "# Codex\n\n## Quick setup\n\nRequiere la [Coast CLI](../GETTING_STARTED.md). Copia este prompt en el chat de tu\nagente para configurar Coasts automáticamente:\n\n```prompt-copy\ncodex_setup_prompt.txt\n```\n\nTambién puedes obtener el contenido de la skill desde la CLI: `coast skills-prompt`.\n\nDespués de la configuración, **cierra y vuelve a abrir Codex** para que la nueva skill y `AGENTS.md` surtan\nefecto.\n\n---\n\n[Codex](https://developers.openai.com/codex/app/worktrees/) crea worktrees en `$CODEX_HOME/worktrees` (normalmente `~/.codex/worktrees`). Cada worktree vive bajo un directorio con hash opaco como `~/.codex/worktrees/a0db/project-name`, comienza en un HEAD desacoplado y se limpia automáticamente según la política de retención de Codex.\n\nDe la [documentación de Codex](https://developers.openai.com/codex/app/worktrees/):\n\n> ¿Puedo controlar dónde se crean los worktrees?\n> No por ahora. Codex crea worktrees en `$CODEX_HOME/worktrees` para poder administrarlos de forma consistente.\n\nDebido a que estos worktrees viven fuera de la raíz del proyecto, Coasts necesita una configuración explícita para descubrirlos y montarlos.\n\n## Setup\n\nAgrega `~/.codex/worktrees` a `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]\n```\n\nCoasts expande `~` en tiempo de ejecución y trata cualquier ruta que comience con `~/` o `/` como externa. Consulta [Directorios de Worktree](../coastfiles/WORKTREE_DIR.md) para más detalles.\n\nDespués de cambiar `worktree_dir`, las instancias existentes deben **recrearse** para que el bind mount surta efecto:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nLa lista de worktrees se actualiza de inmediato (Coasts lee el nuevo Coastfile), pero asignar a un worktree de Codex requiere el bind mount dentro del contenedor.\n\n## Dónde va la guía de Coasts\n\nUsa el archivo de instrucciones del proyecto de Codex y la disposición compartida de skills para trabajar con Coasts:\n\n- coloca las reglas cortas de Coast Runtime en `AGENTS.md`\n- coloca el flujo reutilizable de `/coasts` en `.agents/skills/coasts/SKILL.md`\n- Codex expone esa skill como el comando `/coasts`\n- si usas metadatos específicos de Codex, mantenlos junto a la skill en\n `.agents/skills/coasts/agents/openai.yaml`\n- no crees un archivo de comandos del proyecto separado solo para documentación sobre Coasts; la skill es la superficie reutilizable\n- si este repositorio también usa Cursor o Claude Code, mantén la skill canónica en\n `.agents/skills/` y expónla desde allí. Consulta\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) y\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\nPor ejemplo, un `.agents/skills/coasts/agents/openai.yaml` mínimo podría verse\nasí:\n\n```yaml\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n```\n\nEso mantiene la skill visible en Codex con una etiqueta más agradable y hace que `/coasts` sea un comando explícito. Solo agrega `dependencies.tools` si la skill también necesita servidores MCP u otra integración de herramientas administrada por OpenAI.\n\n## Qué hace Coasts\n\n- **Run** -- `coast run ` crea una nueva instancia de Coast a partir de la compilación más reciente. Usa `coast run -w ` para crear y asignar un worktree de Codex en un solo paso. Consulta [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** -- Al crear el contenedor, Coasts monta\n `~/.codex/worktrees` dentro del contenedor en `/host-external-wt/{index}`.\n- **Descubrimiento** -- `git worktree list --porcelain` está limitado al repositorio, por lo que solo aparecen los worktrees de Codex que pertenecen al proyecto actual, aunque el directorio contenga worktrees de muchos proyectos.\n- **Nomenclatura** -- Los worktrees con HEAD desacoplado se muestran como su ruta relativa dentro del directorio externo (`a0db/my-app`, `eca7/my-app`). Los worktrees basados en ramas muestran el nombre de la rama.\n- **Asignación** -- `coast assign` vuelve a montar `/workspace` desde la ruta del bind mount externo.\n- **Sincronización de archivos ignorados por Git** -- Se ejecuta en el sistema de archivos del host con rutas absolutas, funciona sin el bind mount.\n- **Detección de huérfanos** -- El watcher de git escanea directorios externos\n recursivamente, filtrando por punteros gitdir de `.git`. Si Codex elimina un\n worktree, Coasts desasigna automáticamente la instancia.\n\n## Ejemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` -- Claude Code (local, sin manejo especial)\n- `~/.codex/worktrees/` -- Codex (externo, montado con bind)\n\n## Limitations\n\n- Codex puede limpiar worktrees en cualquier momento. La detección de huérfanos en Coasts maneja esto correctamente.\n", + "harnesses/CONDUCTOR.md": "# Conductor\n\n## Configuración rápida\n\nRequiere la [CLI de Coast](../GETTING_STARTED.md). Copia este prompt en el chat de tu\nagente para configurar Coasts automáticamente:\n\n```prompt-copy\nconductor_setup_prompt.txt\n```\n\nTambién puedes obtener el contenido de la skill desde la CLI: `coast skills-prompt`.\n\n> **Importante:** Conductor ejecuta cada sesión en un `git worktree` aislado. El\n> prompt de configuración crea archivos que solo existen en el espacio de trabajo actual — haz commit\n> y mézclalos en tu rama principal o no estarán disponibles en nuevas\n> sesiones.\n\nDespués de la configuración, **cierra por completo y vuelve a abrir Conductor** para que los cambios surtan efecto. Si\nel comando `/coasts` no aparece, cierra y vuelve a abrir otra vez.\n\n## Configuración\n\nAgrega `~/conductor/workspaces/` a `worktree_dir`. A diferencia de Codex (que almacena todos los proyectos bajo un único directorio plano), Conductor anida los worktrees bajo un subdirectorio por proyecto, por lo que la ruta debe incluir el nombre del proyecto. En el ejemplo de abajo, `my-app` debe coincidir con el nombre real de la carpeta bajo `~/conductor/workspaces/` para tu repositorio.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]\n```\n\nConductor te permite configurar la ruta de los espacios de trabajo por repositorio, por lo que el valor predeterminado `~/conductor/workspaces` puede no coincidir con tu configuración. Revisa la configuración de tu repositorio de Conductor para encontrar la ruta real y ajústala en consecuencia — el principio es el mismo sin importar dónde se encuentre el directorio.\n\nCoasts expande `~` en tiempo de ejecución y trata cualquier ruta que comience con `~/` o `/` como externa. Consulta [Directorios de Worktree](../coastfiles/WORKTREE_DIR.md) para\nmás detalles.\n\nDespués de cambiar `worktree_dir`, las instancias existentes deben **recrearse** para que el montaje bind surta efecto:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nLa lista de worktrees se actualiza de inmediato (Coasts lee el nuevo Coastfile), pero\nasignar a un worktree de Conductor requiere el montaje bind dentro del contenedor.\n\n## Dónde va la guía de Coasts\n\nTrata a Conductor como su propio harness para trabajar con Coasts:\n\n- pon las reglas cortas de Coast Runtime en `CLAUDE.md`\n- usa scripts de Configuración del Repositorio de Conductor para comportamiento\n de configuración o ejecución que sea realmente específico de Conductor\n- no asumas aquí el comportamiento completo de comandos de proyecto o skills de\n proyecto de Claude Code\n- si agregas un comando y no aparece, cierra y vuelve a abrir por completo\n Conductor antes de volver a probar\n- si este repositorio también usa otros harnesses, consulta\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) y\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md) para formas de mantener\n el flujo de trabajo compartido de `/coasts` en un solo lugar\n\n## Qué hace Coasts\n\n- **Run** — `coast run ` crea una nueva instancia de Coast a partir de la compilación más reciente. Usa `coast run -w ` para crear y asignar un worktree de Conductor en un solo paso. Consulta [Run](../concepts_and_terminology/RUN.md).\n- **Montaje bind** — Al crear el contenedor, Coasts monta\n `~/conductor/workspaces/` dentro del contenedor en\n `/host-external-wt/{index}`.\n- **Descubrimiento** — `git worktree list --porcelain` tiene alcance de repositorio, por lo que solo aparecen los worktrees que pertenecen al proyecto actual.\n- **Nombres** — Los worktrees de Conductor usan ramas con nombre, por lo que aparecen por nombre de rama en la interfaz y la CLI de Coasts (por ejemplo, `scroll-to-bottom-btn`). Una rama solo puede estar extraída en un espacio de trabajo de Conductor a la vez.\n- **Asignación** — `coast assign` vuelve a montar `/workspace` desde la ruta de montaje bind externa.\n- **Sincronización de gitignored** — Se ejecuta en el sistema de archivos del host con rutas absolutas, funciona sin el montaje bind.\n- **Detección de huérfanos** — El observador de git escanea directorios externos\n de forma recursiva, filtrando por punteros `gitdir` de `.git`. Si Conductor\n archiva o elimina un espacio de trabajo, Coasts desasigna automáticamente la instancia.\n\n## Ejemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\"~/conductor/workspaces/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/conductor/workspaces/my-app/` — Conductor (externo, montado con bind; reemplaza `my-app` por el nombre de la carpeta de tu repositorio)\n\n## Variables de entorno de Conductor\n\n- Evita depender de variables de entorno específicas de Conductor (p. ej.,\n `CONDUCTOR_PORT`, `CONDUCTOR_WORKSPACE_PATH`) para la configuración en tiempo de ejecución\n dentro de Coasts. Coasts administra puertos, rutas de espacios de trabajo y descubrimiento de servicios\n de forma independiente — usa `[ports]` del Coastfile y `coast exec` en su lugar.\n", + "harnesses/CURSOR.md": "# Cursor\n\n## Configuración rápida\n\nRequiere el [Coast CLI](../GETTING_STARTED.md). Copia este prompt en el chat de tu\nagente para configurar Coasts automáticamente:\n\n```prompt-copy\ncursor_setup_prompt.txt\n```\n\nTambién puedes obtener el contenido de la skill desde la CLI: `coast skills-prompt`.\n\nDespués de la configuración, **reinicia Cursor** para que los cambios en la skill y las reglas surtan efecto.\n\n---\n\n[Cursor](https://cursor.com/docs/agent/overview) puede trabajar directamente en tu\ncheckout actual, y su función Parallel Agents también puede crear git\nworktrees bajo `~/.cursor/worktrees//`.\n\nPara la documentación sobre Coasts, eso significa que hay dos casos de configuración:\n\n- si solo estás usando Cursor en el checkout actual, no se requiere ninguna entrada\n `worktree_dir` específica de Cursor\n- si usas Cursor Parallel Agents, añade el directorio de worktrees de Cursor a\n `worktree_dir` para que Coasts pueda descubrir y asignar esos worktrees\n\n## Configuración\n\n### Solo checkout actual\n\nSi Cursor solo está editando el checkout que ya abriste, Coasts no necesita\nninguna ruta de worktree especial específica de Cursor. Coasts tratará ese\ncheckout como cualquier otra raíz de repositorio local.\n\n### Cursor Parallel Agents\n\nSi usas Parallel Agents, añade `~/.cursor/worktrees/` a\n`worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]\n```\n\nCursor almacena el worktree de cada agente bajo ese directorio por proyecto. Coasts\nexpande `~` en tiempo de ejecución y trata la ruta como externa, por lo que las\ninstancias existentes deben recrearse para que el bind mount surta efecto:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nLa lista de worktrees se actualiza inmediatamente después del cambio en el Coastfile, pero\nasignar a un worktree de Cursor Parallel Agent requiere el bind mount externo\ndentro del contenedor.\n\n## Dónde va la guía de Coasts\n\n### `AGENTS.md` o `.cursor/rules/coast.md`\n\nPon aquí las reglas breves y siempre activas de Coast Runtime:\n\n- usa `AGENTS.md` si quieres las instrucciones de proyecto más portables\n- usa `.cursor/rules/coast.md` si quieres reglas de proyecto nativas de Cursor y\n compatibilidad con la interfaz de configuración\n- no dupliques el mismo bloque de Coast Runtime en ambos salvo que tengas una\n razón clara\n\n### `.cursor/skills/coasts/SKILL.md` o `.agents/skills/coasts/SKILL.md` compartido\n\nPon aquí el flujo de trabajo reutilizable `/coasts`:\n\n- para un repositorio solo de Cursor, `.cursor/skills/coasts/SKILL.md` es un lugar natural\n- para un repositorio con múltiples harnesses, mantén la skill canónica en\n `.agents/skills/coasts/SKILL.md`; Cursor puede cargarla directamente\n- la skill debe ser dueña del flujo de trabajo real de `/coasts`: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout` y `coast ui`\n\n### `.cursor/commands/coasts.md`\n\nCursor también admite comandos de proyecto. Para la documentación sobre Coasts, trata los comandos como\nopcionales:\n\n- añade un comando solo cuando quieras un punto de entrada explícito `/coasts`\n- una opción sencilla es hacer que el comando reutilice la misma skill\n- si das al comando sus propias instrucciones separadas, estás asumiendo\n una segunda copia del flujo de trabajo para mantener\n\n### `.cursor/worktrees.json`\n\nUsa `.cursor/worktrees.json` para el bootstrap de worktrees propio de Cursor, no para la\npolítica de Coasts:\n\n- instalar dependencias\n- copiar o enlazar simbólicamente archivos `.env`\n- ejecutar migraciones de base de datos u otros pasos de bootstrap de una sola vez\n\nNo muevas las reglas de Coast Runtime ni el flujo de trabajo del Coast CLI a\n`.cursor/worktrees.json`.\n\n## Ejemplo de estructura\n\n### Solo Cursor\n\n```text\nAGENTS.md\n.cursor/skills/coasts/SKILL.md\n.cursor/commands/coasts.md # opcional\n.cursor/rules/coast.md # alternativa opcional a AGENTS.md\n.cursor/worktrees.json # opcional, para bootstrap de Parallel Agents\n```\n\n### Cursor más otros harnesses\n\n```text\nAGENTS.md\nCLAUDE.md\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # opcional\n```\n\n## Qué hace Coasts\n\n- **Run** — `coast run ` crea una nueva instancia de Coast a partir de la compilación más reciente. Usa `coast run -w ` para crear y asignar un worktree de Cursor en un solo paso. Consulta [Run](../concepts_and_terminology/RUN.md).\n- **Checkout actual** — No se requiere ningún manejo especial de Cursor cuando Cursor está\n trabajando directamente en el repositorio que abriste.\n- **Bind mount** — Para Parallel Agents, Coasts monta\n `~/.cursor/worktrees/` en el contenedor en\n `/host-external-wt/{index}`.\n- **Descubrimiento** — `git worktree list --porcelain` sigue teniendo alcance de repositorio, por lo que Coasts\n solo muestra los worktrees de Cursor que pertenecen al proyecto actual.\n- **Nombres** — Los worktrees de Cursor Parallel Agent aparecen por sus nombres de rama en\n la CLI y la UI de Coasts.\n- **Assign** — `coast assign` vuelve a montar `/workspace` desde la ruta del bind mount\n externo cuando se selecciona un worktree de Cursor.\n- **Sincronización de ignorados por Git** — Sigue funcionando en el sistema de archivos del host con rutas\n absolutas.\n- **Detección de huérfanos** — Si Cursor limpia worktrees antiguos, Coasts puede detectar\n el gitdir faltante y desasignarlos cuando sea necesario.\n\n## Ejemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.cursor/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — worktrees de Claude Code\n- `~/.codex/worktrees/` — worktrees de Codex\n- `~/.cursor/worktrees/my-app/` — worktrees de Cursor Parallel Agent\n\n## Limitaciones\n\n- Si no estás usando Cursor Parallel Agents, no añadas\n `~/.cursor/worktrees/` solo porque casualmente estés editando en\n Cursor.\n- Mantén las reglas de Coast Runtime en un único lugar siempre activo: `AGENTS.md` o\n `.cursor/rules/coast.md`. Duplicar ambos invita a la divergencia.\n- Mantén el flujo de trabajo reutilizable `/coasts` en una skill. `.cursor/worktrees.json` es\n para el bootstrap de Cursor, no para la política de Coasts.\n- Si un repositorio se comparte entre Cursor, Codex, Claude Code o T3 Code, prefiere\n la estructura compartida en [Multiple Harnesses](MULTIPLE_HARNESSES.md).\n", "harnesses/MULTIPLE_HARNESSES.md": "# Múltiples Harnesses\n\nSi un repositorio se usa desde más de un harness, una forma de consolidar\nla configuración de Coasts es mantener el flujo de trabajo compartido de `/coasts` en un solo lugar y mantener\nlas reglas siempre activas específicas del harness en los archivos de cada harness.\n\n## Disposición recomendada\n\n```text\nAGENTS.md\nCLAUDE.md\n.cursor/rules/coast.md # optional Cursor-native always-on rules\n.agents/skills/coasts/SKILL.md\n.agents/skills/coasts/agents/openai.yaml\n.claude/skills/coasts -> ../../.agents/skills/coasts\n.cursor/commands/coasts.md # optional, thin, harness-specific\n.claude/commands/coasts.md # optional, thin, harness-specific\n```\n\nUsa esta disposición así:\n\n- `AGENTS.md` — reglas cortas, siempre activas para trabajar con Coasts en Codex y T3\n Code\n- `.cursor/rules/coast.md` — reglas opcionales, siempre activas y nativas de Cursor\n- `CLAUDE.md` — reglas cortas, siempre activas para trabajar con Coasts en Claude Code\n y Conductor\n- `.agents/skills/coasts/SKILL.md` — flujo de trabajo canónico reutilizable de `/coasts`\n- `.agents/skills/coasts/agents/openai.yaml` — metadatos opcionales de Codex/OpenAI\n- `.claude/skills/coasts` — espejo o symlink orientado a Claude cuando Claude Code\n también necesita la misma skill\n- `.cursor/commands/coasts.md` — archivo de comando opcional de Cursor; una opción\n simple es hacer que reutilice la misma skill\n- `.claude/commands/coasts.md` — archivo de comando explícito opcional; una opción\n simple es hacer que reutilice la misma skill\n\n## Paso a paso\n\n1. Coloca las reglas de Coast Runtime en los archivos de instrucciones siempre activos.\n - `AGENTS.md`, `CLAUDE.md` o `.cursor/rules/coast.md` deben responder a las\n reglas de \"cada tarea\": ejecutar `coast lookup` primero, usar `coast exec`, leer registros\n con `coast logs`, preguntar antes de `coast assign` o `coast run` cuando no haya\n coincidencia.\n2. Crea una skill canónica para Coasts.\n - Coloca el flujo de trabajo reutilizable de `/coasts` en `.agents/skills/coasts/SKILL.md`.\n - Usa el Coast CLI directamente dentro de esa skill: `coast lookup`,\n `coast ls`, `coast run`, `coast assign`, `coast unassign`,\n `coast checkout` y `coast ui`.\n3. Expón esa skill solo donde un harness necesite una ruta diferente.\n - Codex, T3 Code y Cursor pueden usar `.agents/skills/` directamente.\n - Claude Code necesita `.claude/skills/`, así que refleja o crea un symlink de la\n skill canónica en esa ubicación.\n4. Agrega un archivo de comando solo si quieres un punto de entrada `/coasts` explícito.\n - Si creas `.claude/commands/coasts.md` o\n `.cursor/commands/coasts.md`, una opción simple es hacer que el comando\n reutilice la misma skill.\n - Si le das al comando sus propias instrucciones separadas, estás asumiendo una\n segunda copia del flujo de trabajo que mantener.\n5. Mantén la configuración específica de Conductor en Conductor, no en la skill.\n - Usa scripts de Repository Settings de Conductor para el comportamiento de bootstrap o ejecución\n que pertenece al propio Conductor.\n - Mantén la política de Coasts y el uso del CLI `coast` en `CLAUDE.md` y la\n skill compartida.\n\n## Ejemplo concreto de `/coasts`\n\nUna buena skill compartida `coasts` debe hacer tres trabajos:\n\n1. `Use Existing Coast`\n - ejecutar `coast lookup`\n - si existe una coincidencia, usar `coast exec`, `coast ps` y `coast logs`\n2. `Manage Assignment`\n - ejecutar `coast ls`\n - ofrecer `coast run`, `coast assign`, `coast unassign` o\n `coast checkout`\n - preguntar antes de reutilizar o interrumpir una ranura existente\n3. `Open UI`\n - ejecutar `coast ui`\n\nEse es el lugar correcto para el flujo de trabajo de `/coasts`. Los archivos siempre activos deben\ncontener solo las reglas cortas que deben aplicarse incluso cuando la skill nunca se invoca.\n\n## Patrón de symlink\n\nSi quieres que Claude Code reutilice la misma skill que Codex, T3 Code o Cursor,\nuna opción es un symlink:\n\n```bash\nmkdir -p .claude/skills\nln -s ../../.agents/skills/coasts .claude/skills/coasts\n```\n\nUn espejo versionado también está bien si tu equipo prefiere no usar symlinks. El\nobjetivo principal es simplemente evitar una divergencia innecesaria entre copias.\n\n## Precauciones específicas del harness\n\n- Claude Code: tanto las skills del proyecto como los comandos opcionales del proyecto son válidos, pero\n mantén la lógica en la skill.\n- Cursor: usa `AGENTS.md` o `.cursor/rules/coast.md` para las reglas cortas de Coast\n Runtime, usa una skill para el flujo de trabajo reutilizable y mantén\n `.cursor/commands` como opcional.\n- Conductor: trátalo primero como `CLAUDE.md` más scripts y configuraciones de Conductor.\n Si agregas un comando y no aparece, cierra completamente y vuelve a abrir la app\n antes de comprobar de nuevo.\n- T3 Code: esta es la superficie de harness más delgada aquí. Usa el patrón de estilo Codex\n `AGENTS.md` más `.agents/skills`, y no inventes una disposición de comandos\n separada y específica de T3 para documentación sobre Coasts.\n- Codex: mantén `AGENTS.md` corto y coloca el flujo de trabajo reutilizable en\n `.agents/skills`.\n", - "harnesses/T3_CODE.md": "# T3 Code\n\n[T3 Code](https://github.com/pingdotgg/t3code) crea git worktrees en\n`~/.t3/worktrees//`, extraídos en ramas con nombre.\n\nEn T3 Code, coloca las reglas de Coast Runtime que siempre están activas en `AGENTS.md` y el flujo de trabajo reutilizable `/coasts` en `.agents/skills/coasts/SKILL.md`.\n\nDebido a que estos worktrees viven fuera de la raíz del proyecto, Coasts necesita una configuración explícita para descubrirlos y montarlos.\n\n## Configuración\n\nAgrega `~/.t3/worktrees/` a `worktree_dir`. T3 Code anida los worktrees bajo un subdirectorio por proyecto, por lo que la ruta debe incluir el nombre del proyecto. En el ejemplo a continuación, `my-app` debe coincidir con el nombre real de la carpeta bajo `~/.t3/worktrees/` para tu repositorio.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nCoasts expande `~` en tiempo de ejecución y trata cualquier ruta que comience con `~/` o `/` como externa. Consulta [Worktree Directories](../coastfiles/WORKTREE_DIR.md) para más detalles.\n\nDespués de cambiar `worktree_dir`, las instancias existentes deben **recrearse** para que el bind mount surta efecto:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nLa lista de worktrees se actualiza inmediatamente (Coasts lee el nuevo Coastfile), pero asignar a un worktree de T3 Code requiere el bind mount dentro del contenedor.\n\n## Dónde va la guía de Coasts\n\nUsa esta disposición para T3 Code:\n\n- coloca las reglas breves de Coast Runtime en `AGENTS.md`\n- coloca el flujo de trabajo reutilizable `/coasts` en `.agents/skills/coasts/SKILL.md`\n- no agregues una capa separada de comando de proyecto o slash-command específica de T3 para Coasts\n- si este repositorio usa múltiples harnesses, consulta\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) y\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\n## Qué hace Coasts\n\n- **Run** — `coast run ` crea una nueva instancia de Coast a partir de la compilación más reciente. Usa `coast run -w ` para crear y asignar un worktree de T3 Code en un solo paso. Consulta [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — Al crear el contenedor, Coasts monta\n `~/.t3/worktrees/` dentro del contenedor en\n `/host-external-wt/{index}`.\n- **Discovery** — `git worktree list --porcelain` tiene alcance por repositorio, por lo que solo aparecen los worktrees que pertenecen al proyecto actual.\n- **Naming** — Los worktrees de T3 Code usan ramas con nombre, por lo que aparecen por nombre de rama en la UI y la CLI de Coasts.\n- **Assign** — `coast assign` vuelve a montar `/workspace` desde la ruta externa del bind mount.\n- **Gitignored sync** — Se ejecuta en el sistema de archivos del host con rutas absolutas, funciona sin el bind mount.\n- **Orphan detection** — El watcher de git escanea directorios externos de forma recursiva, filtrando por punteros gitdir de `.git`. Si T3 Code elimina un espacio de trabajo, Coasts desasigna automáticamente la instancia.\n\n## Ejemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code (local, sin manejo especial)\n- `~/.codex/worktrees/` — Codex (externo, con bind mount)\n- `~/.t3/worktrees/my-app/` — T3 Code (externo, con bind mount; reemplaza `my-app` con el nombre de la carpeta de tu repositorio)\n\n## Limitaciones\n\n- Evita depender de variables de entorno específicas de T3 Code para la configuración en tiempo de ejecución dentro de Coasts. Coasts gestiona puertos, rutas de espacio de trabajo y descubrimiento de servicios de forma independiente — usa `[ports]` en Coastfile y `coast exec` en su lugar.\n", + "harnesses/SHEP.md": "# Shep\n\n## Configuración rápida\n\nRequiere el [Coast CLI](../GETTING_STARTED.md). Copia este prompt en el chat de tu\nagente para configurar Coasts automáticamente:\n\n```prompt-copy\nshep_setup_prompt.txt\n```\n\nTambién puedes obtener el contenido de la skill desde el CLI: `coast skills-prompt`.\n\nDespués de la configuración, **cierra y vuelve a abrir tu editor** para que la nueva skill y las\ninstrucciones del proyecto surtan efecto.\n\n---\n\n[Shep](https://shep-ai.github.io/cli/) crea worktrees en `~/.shep/repos/{hash}/wt/{branch-slug}`. El hash son los primeros 16 caracteres hexadecimales del SHA-256 de la ruta absoluta del repositorio, por lo que es determinista por repositorio pero opaco. Todos los worktrees de un repositorio dado comparten el mismo hash y se diferencian por el subdirectorio `wt/{branch-slug}`.\n\nDesde el Shep CLI, `shep feat show ` imprime la ruta del worktree, o\n`ls ~/.shep/repos` lista los directorios hash por repositorio.\n\nDebido a que el hash varía según el repositorio, Coasts usa un **patrón glob** para descubrir\nlos worktrees de shep sin requerir que el usuario codifique el hash manualmente.\n\n## Configuración\n\nAgrega `~/.shep/repos/*/wt` a `worktree_dir`:\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\n```\n\nEl `*` coincide con el directorio hash por repositorio. En tiempo de ejecución Coasts expande el glob,\nencuentra el directorio coincidente (p. ej. `~/.shep/repos/a21f0cda9ab9d456/wt`), y\nlo monta mediante bind mount dentro del contenedor. Consulta\n[Directorios de Worktree](../coastfiles/WORKTREE_DIR.md) para ver todos los detalles sobre los\npatrones glob.\n\nDespués de cambiar `worktree_dir`, las instancias existentes deben **recrearse** para que el bind mount surta efecto:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nLa lista de worktrees se actualiza inmediatamente (Coasts lee el nuevo Coastfile), pero\nasignar a un worktree de Shep requiere el bind mount dentro del contenedor.\n\n## Dónde va la guía de Coasts\n\nShep envuelve Claude Code internamente, así que sigue las convenciones de Claude Code:\n\n- coloca las reglas cortas de Coast Runtime en `CLAUDE.md`\n- coloca el flujo de trabajo reutilizable `/coasts` en `.claude/skills/coasts/SKILL.md` o\n en el compartido `.agents/skills/coasts/SKILL.md`\n- si este repositorio también usa otros harnesses, consulta\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) y\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md)\n\n## Qué hace Coasts\n\n- **Run** -- `coast run ` crea una nueva instancia de Coast a partir de la compilación más reciente. Usa `coast run -w ` para crear y asignar un worktree de Shep en un solo paso. Consulta [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** -- Al crear el contenedor, Coasts resuelve el glob\n `~/.shep/repos/*/wt` y monta cada directorio coincidente dentro del contenedor en\n `/host-external-wt/{index}`.\n- **Discovery** -- `git worktree list --porcelain` tiene alcance de repositorio, por lo que solo\n aparecen los worktrees que pertenecen al proyecto actual.\n- **Naming** -- Los worktrees de Shep usan ramas con nombre, por lo que aparecen por nombre\n de rama en la UI y el CLI de Coasts (p. ej., `feat-green-background`).\n- **Assign** -- `coast assign` vuelve a montar `/workspace` desde la ruta de bind mount externa.\n- **Gitignored sync** -- Se ejecuta en el sistema de archivos del host con rutas absolutas, funciona sin el bind mount.\n- **Orphan detection** -- El observador de git escanea directorios externos\n recursivamente, filtrando por punteros gitdir de `.git`. Si Shep elimina un\n worktree, Coasts desasigna automáticamente la instancia.\n\n## Ejemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `~/.shep/repos/*/wt` -- Shep (externo, montado mediante bind mount vía expansión de glob)\n\n## Estructura de rutas de Shep\n\n```\n~/.shep/repos/\n {sha256-of-repo-path-first-16-chars}/\n wt/\n {branch-slug}/ <-- git worktree\n {branch-slug}/\n```\n\nPuntos clave:\n- Mismo repositorio = mismo hash siempre (determinista, no aleatorio)\n- Repositorios diferentes = hashes diferentes\n- Los separadores de ruta se normalizan a `/` antes de aplicar hash\n- El hash se puede encontrar mediante `shep feat show ` o `ls ~/.shep/repos`\n", + "harnesses/T3_CODE.md": "# T3 Code\n\n## Configuración rápida\n\nRequiere la [Coast CLI](../GETTING_STARTED.md). Copia este prompt en el chat de tu\nagente para configurar Coasts automáticamente:\n\n```prompt-copy\nt3_code_setup_prompt.txt\n```\n\nTambién puedes obtener el contenido de la skill desde la CLI: `coast skills-prompt`.\n\nDespués de la configuración, **reinicia T3 Code** para que los cambios en la skill y las reglas surtan efecto.\n\n**Nota:** Es posible que T3 Code todavía no cargue skills a nivel de proyecto desde `.agents/skills/` o\n`.claude/skills/`. El prompt de configuración también coloca la skill en\n`~/.codex/skills/coasts/` para que esté disponible globalmente para el proveedor Codex.\nLas reglas de Coast Runtime en `AGENTS.md` y `CLAUDE.md` siguen aplicándose en cada\ntarea de todos modos.\n\n---\n\n[T3 Code](https://github.com/pingdotgg/t3code) crea git worktrees en\n`~/.t3/worktrees//`, extraídos en ramas con nombre.\n\nT3 Code envuelve a Codex, por lo que usa `AGENTS.md` para reglas siempre activas y\n`.agents/skills/coasts/SKILL.md` para el flujo de trabajo reutilizable `/coasts`.\n\nDebido a que estos worktrees viven fuera de la raíz del proyecto, Coasts necesita una configuración explícita para descubrirlos y montarlos.\n\n## Setup\n\nAgrega `~/.t3/worktrees/` a `worktree_dir`. T3 Code anida los worktrees bajo un subdirectorio por proyecto, por lo que la ruta debe incluir el nombre del proyecto. En el ejemplo a continuación, `my-app` debe coincidir con el nombre real de la carpeta bajo `~/.t3/worktrees/` para tu repositorio.\n\n```toml\n[coast]\nname = \"my-app\"\nworktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]\n```\n\nCoasts expande `~` en tiempo de ejecución y trata cualquier ruta que comience con `~/` o `/` como externa. Consulta [Worktree Directories](../coastfiles/WORKTREE_DIR.md) para más detalles.\n\nDespués de cambiar `worktree_dir`, las instancias existentes deben **recrearse** para que el bind mount surta efecto:\n\n```bash\ncoast rm my-instance\ncoast build\ncoast run my-instance\n```\n\nLa lista de worktrees se actualiza inmediatamente (Coasts lee el nuevo Coastfile), pero asignar a un worktree de T3 Code requiere el bind mount dentro del contenedor.\n\n## Dónde va la guía de Coasts\n\nUsa esta disposición para T3 Code:\n\n- coloca las reglas breves de Coast Runtime en `AGENTS.md`\n- coloca el flujo de trabajo reutilizable `/coasts` en `.agents/skills/coasts/SKILL.md`\n- no agregues una capa separada de comando de proyecto o slash-command específica de T3 para\n Coasts\n- si este repositorio usa múltiples harnesses, consulta\n [Multiple Harnesses](MULTIPLE_HARNESSES.md) y\n [Skills for Host Agents](../SKILLS_FOR_HOST_AGENTS.md).\n\n## Qué hace Coasts\n\n- **Run** — `coast run ` crea una nueva instancia de Coast a partir de la compilación más reciente. Usa `coast run -w ` para crear y asignar un worktree de T3 Code en un solo paso. Consulta [Run](../concepts_and_terminology/RUN.md).\n- **Bind mount** — Al crear el contenedor, Coasts monta\n `~/.t3/worktrees/` dentro del contenedor en\n `/host-external-wt/{index}`.\n- **Discovery** — `git worktree list --porcelain` tiene alcance por repositorio, por lo que solo aparecen los worktrees que pertenecen al proyecto actual.\n- **Naming** — Los worktrees de T3 Code usan ramas con nombre, por lo que aparecen por nombre de rama en la UI y la CLI de Coasts.\n- **Assign** — `coast assign` vuelve a montar `/workspace` desde la ruta externa del bind mount.\n- **Gitignored sync** — Se ejecuta en el sistema de archivos del host con rutas absolutas, funciona sin el bind mount.\n- **Orphan detection** — El watcher de git escanea directorios externos de forma recursiva, filtrando por punteros gitdir de `.git`. Si T3 Code elimina un espacio de trabajo, Coasts desasigna automáticamente la instancia.\n\n## Ejemplo\n\n```toml\n[coast]\nname = \"my-app\"\ncompose = \"./docker-compose.yml\"\nworktree_dir = [\".worktrees\", \".claude/worktrees\", \"~/.codex/worktrees\", \"~/.t3/worktrees/my-app\"]\nprimary_port = \"web\"\n\n[ports]\nweb = 3000\napi = 8080\n\n[assign]\ndefault = \"none\"\n[assign.services]\nweb = \"hot\"\napi = \"hot\"\n```\n\n- `.claude/worktrees/` — Claude Code (local, sin manejo especial)\n- `~/.codex/worktrees/` — Codex (externo, con bind mount)\n- `~/.t3/worktrees/my-app/` — T3 Code (externo, con bind mount; reemplaza `my-app` con el nombre de la carpeta de tu repositorio)\n\n## Limitaciones\n\n- Evita depender de variables de entorno específicas de T3 Code para la configuración en tiempo de ejecución dentro de Coasts. Coasts gestiona puertos, rutas de espacio de trabajo y descubrimiento de servicios de forma independiente — usa `[ports]` en Coastfile y `coast exec` en su lugar.\n", + "harnesses/claude_code_setup_prompt.txt": "Estás configurando la habilidad Coasts para Claude Code en este proyecto. Ejecuta todos\nlos comandos desde la raíz del proyecto.\n\n## Paso 1: Verificar Coast CLI\n\nEjecuta este comando:\n\n coast --version\n\nSi no se encuentra el comando `coast`, detente aquí y dile al usuario:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nNo continúes hasta que el CLI esté disponible.\n\n## Paso 2: Obtener el contenido de la habilidad\n\nEjecuta este comando:\n\n coast skills-prompt\n\nLa salida tiene dos partes:\n\n- **Reglas de Coast Runtime** — todo desde el inicio hasta (pero sin incluir) la línea que comienza con `---`\n- **Habilidad Coasts** — todo desde el bloque de frontmatter `---` en adelante (incluyendo las líneas `---` y todo lo que viene después)\n\nGuarda ambas partes para los pasos siguientes.\n\n## Paso 3: Preguntar al usuario\n\nPregunta al usuario: ¿debo configurar esto **globalmente** (disponible en todos los proyectos de esta máquina) o **solo para este proyecto**?\n\n## Paso 4: Colocar archivos\n\nSi un archivo de destino ya existe, agrega la sección Coast Runtime en lugar de sobrescribirla, pero primero verifica si ya hay una sección `# Coast Runtime` presente y, de ser así, omítela.\n\n**Configuración global:**\n- Agrega las reglas de Coast Runtime a `~/.claude/CLAUDE.md`\n- Escribe la habilidad Coasts en `~/.claude/skills/coasts/SKILL.md`\n\n**Configuración del proyecto:**\n- Agrega las reglas de Coast Runtime a `CLAUDE.md` en la raíz del proyecto\n- Escribe la habilidad Coasts en `.claude/skills/coasts/SKILL.md`\n\n## Paso 5: Actualizar el Coastfile\n\nLee el `Coastfile` en la raíz del proyecto. Observa el campo `worktree_dir` en la\nsección `[coast]`.\n\nSi `.claude/worktrees` **no** aparece ya en `worktree_dir`:\n\n- Si `worktree_dir` es una sola cadena, conviértela en un arreglo y agrega\n `.claude/worktrees`. Por ejemplo, `worktree_dir = \".worktrees\"` se convierte en\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]`.\n- Si `worktree_dir` ya es un arreglo, agrega `.claude/worktrees` a él.\n- Si `worktree_dir` no está presente en absoluto, agrega\n `worktree_dir = [\".worktrees\", \".claude/worktrees\"]`.\n\nEsta es una ruta relativa (dentro de la raíz del proyecto), por lo que no es\nnecesario recrear el contenedor: los cambios surten efecto inmediatamente para el listado de worktrees.\n\n## Paso 6: Confirmar\n\nDespués de colocar los archivos, muestra al usuario un resumen de lo que se creó y dónde.\n\nDile al usuario: **Inicia una nueva sesión de Claude Code** para que la habilidad y los cambios en CLAUDE.md surtan efecto.\n", + "harnesses/codex_setup_prompt.txt": "Estás configurando la skill Coasts para OpenAI Codex en este proyecto. Ejecuta todos\nlos comandos desde la raíz del proyecto.\n\n## Step 1: Verificar Coast CLI\n\nEjecuta este comando:\n\n coast --version\n\nSi no se encuentra el comando `coast`, detente aquí y dile al usuario:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nNo continúes hasta que el CLI esté disponible.\n\n## Step 2: Obtener el contenido de la skill\n\nEjecuta este comando:\n\n coast skills-prompt\n\nLa salida tiene dos partes:\n\n- **Reglas de Coast Runtime** — todo desde el inicio hasta (pero sin incluir) la línea que comienza con `---`\n- **Skill Coasts** — todo desde el bloque de frontmatter `---` en adelante (incluyendo las líneas `---` y todo lo que sigue después de ellas)\n\nGuarda ambas partes para los pasos siguientes.\n\n## Step 3: Colocar archivos\n\nLa configuración de Codex siempre es a nivel de proyecto. Si un archivo de destino ya existe, agrega la sección de Coast Runtime en lugar de sobrescribirla, pero primero verifica si ya hay una sección `# Coast Runtime` presente y omítela si es así.\n\n- Agrega las reglas de Coast Runtime a `AGENTS.md` en la raíz del proyecto\n- Escribe la skill Coasts en `.agents/skills/coasts/SKILL.md`\n- Crea `.agents/skills/coasts/agents/openai.yaml` con este contenido:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## Step 4: Actualizar el Coastfile\n\nLee el `Coastfile` en la raíz del proyecto. Revisa el campo `worktree_dir` en la\nsección `[coast]`.\n\nSi `~/.codex/worktrees` **aún no** aparece en `worktree_dir`:\n\n- Si `worktree_dir` es una sola cadena, conviértela en un arreglo y agrega\n `~/.codex/worktrees`. Por ejemplo, `worktree_dir = \".worktrees\"` se convierte en\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]`.\n- Si `worktree_dir` ya es un arreglo, agrega `~/.codex/worktrees` a él.\n- Si `worktree_dir` no está presente en absoluto, agrega\n `worktree_dir = [\".worktrees\", \"~/.codex/worktrees\"]`.\n\nEsta es una ruta externa, por lo que si ya hay una instancia de Coast en ejecución para este\nproyecto, debe recrearse con `coast run` para que el nuevo bind mount surta\nefecto. Díselo al usuario.\n\n## Step 5: Confirmar\n\nDespués de colocar los archivos, muestra al usuario un resumen de qué se creó y dónde.\n\nDile al usuario: **Salir y volver a abrir Codex** para que la skill y los cambios en AGENTS.md\nsurtan efecto.\n", + "harnesses/conductor_setup_prompt.txt": "Estás configurando la skill de Coasts para Conductor en este proyecto. Ejecuta todos\nlos comandos desde la raíz del proyecto.\n\n## Paso 1: Comprobar Coast CLI\n\nEjecuta este comando:\n\n coast --version\n\nSi no se encuentra el comando `coast`, detente aquí y dile al usuario:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nNo continúes hasta que el CLI esté disponible.\n\n## Paso 2: Obtener el contenido de la skill\n\nEjecuta este comando:\n\n coast skills-prompt\n\nLa salida tiene dos partes:\n\n- **Reglas de Coast Runtime** — todo desde el inicio hasta (pero sin incluir) la línea que comienza con `---`\n- **Skill de Coasts** — todo desde el bloque de frontmatter `---` en adelante (incluyendo las líneas `---` y todo lo que sigue después de ellas)\n\nGuarda ambas partes para los pasos siguientes.\n\n## Paso 3: Preguntar al usuario\n\nPregúntale al usuario: ¿qué proveedores usas en Conductor?\n\n- **Claude** (Anthropic)\n- **Codex** (OpenAI)\n- **Ambos**\n- **Otro** — si el usuario menciona un proveedor diferente, ejecuta\n `coast docs --path SKILLS_FOR_HOST_AGENTS.md` y\n `coast docs --path harnesses/README.md` para determinar dónde espera ese proveedor\n las instrucciones del proyecto y las skills, luego sigue el mismo patrón\n\n## Paso 4: Colocar archivos\n\nLa configuración de Conductor siempre es a nivel de proyecto. Si un archivo de destino ya existe, agrega\nla sección de Coast Runtime en lugar de sobrescribir — pero primero comprueba si una\nsección `# Coast Runtime` ya está presente y omítela si es así.\n\n**Si el usuario seleccionó Claude (o ambos):**\n- Agrega las reglas de Coast Runtime a `CLAUDE.md` en la raíz del proyecto\n- Escribe la skill de Coasts en `.claude/skills/coasts/SKILL.md`\n\n**Si el usuario seleccionó Codex (o ambos):**\n- Agrega las reglas de Coast Runtime a `AGENTS.md` en la raíz del proyecto\n- Escribe la skill de Coasts en `.agents/skills/coasts/SKILL.md`\n- Crea `.agents/skills/coasts/agents/openai.yaml` con este contenido:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n## Paso 5: Confirmar\n\nDespués de colocar los archivos, muéstrale al usuario un resumen de qué se creó y dónde.\n\nDile al usuario: **Cierra completamente y vuelve a abrir Conductor** para que los cambios surtan efecto.\nSi el comando `/coasts` no aparece de inmediato, cierra y vuelve a abrir otra vez.\n\n## Paso 6: Actualizar el Coastfile\n\nLee el `Coastfile` en la raíz del proyecto. Observa el campo `worktree_dir` en la\nsección `[coast]`. Lee también el campo `name` — lo necesitarás para construir la\nruta del worktree.\n\nEl directorio de worktree de Conductor es `~/conductor/workspaces/`, donde\n`` es el valor del campo `name` en el Coastfile.\n\nSi esa ruta **no** ya está listada en `worktree_dir`:\n\n- Si `worktree_dir` es una sola cadena, conviértela en un arreglo y agrega la\n ruta de Conductor. Por ejemplo, `worktree_dir = \".worktrees\"` se convierte en\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/my-app\"]`.\n- Si `worktree_dir` ya es un arreglo, agrégale la ruta de Conductor.\n- Si `worktree_dir` no está presente en absoluto, agrega\n `worktree_dir = [\".worktrees\", \"~/conductor/workspaces/\"]` usando el\n nombre real del proyecto.\n\nEsta es una ruta externa, así que si ya hay una instancia de Coast en ejecución para este\nproyecto debe recrearse con `coast run` para que el nuevo bind mount surta\nefecto. Díselo al usuario.\n\n## Paso 7: Confirmar los nuevos archivos\n\nConductor ejecuta cada sesión en un git worktree aislado. Los archivos sin confirmar\nno se trasladarán a las nuevas sesiones. Haz commit de los archivos que acabas de crear para que estén\ndisponibles en todos los futuros workspaces:\n\n git add CLAUDE.md .claude/ AGENTS.md .agents/ 2>/dev/null; git status\n\nMuéstrale al usuario qué archivos están en staging y pídele que confirme antes de hacer commit.\nUsa un mensaje de commit como `[dh] feat: add Coasts skill for Conductor`.\n", + "harnesses/cursor_setup_prompt.txt": "Estás configurando la skill Coasts para Cursor en este proyecto. Ejecuta todos\nlos comandos desde la raíz del proyecto.\n\n## Paso 1: Verificar Coast CLI\n\nEjecuta este comando:\n\n coast --version\n\nSi no se encuentra el comando `coast`, detente aquí y dile al usuario:\n\n \"Coast CLI no está instalado. Instálalo primero: https://coasts.dev/docs/getting-started\"\n\nNo continúes hasta que el CLI esté disponible.\n\n## Paso 2: Obtener el contenido de la skill\n\nEjecuta este comando:\n\n coast skills-prompt\n\nLa salida tiene dos partes:\n\n- **Reglas de Coast Runtime** — todo desde el inicio hasta (pero sin incluir) la línea que comienza con `---`\n- **Skill de Coasts** — todo desde el bloque de frontmatter `---` en adelante (incluyendo las líneas `---` y todo lo que sigue después de ellas)\n\nGuarda ambas partes para los pasos siguientes.\n\n## Paso 3: Preguntar al usuario\n\nPregúntale al usuario: ¿debo configurar esto **globalmente** (disponible en todos los proyectos de esta máquina) o **solo para este proyecto**?\n\n## Paso 4: Colocar archivos\n\nSi un archivo de destino ya existe, agrega la sección Coast Runtime en lugar de sobrescribirla — pero primero verifica si ya hay una sección `# Coast Runtime` presente y, si es así, omítela.\n\n**Configuración global:**\n- Agrega las reglas de Coast Runtime a las reglas globales de Cursor del usuario\n- Escribe la skill de Coasts en `~/.cursor/skills/coasts/SKILL.md`\n\n**Configuración del proyecto:**\n- Agrega las reglas de Coast Runtime a `AGENTS.md` en la raíz del proyecto (o a `.cursor/rules/coast.md` si el usuario prefiere reglas nativas de Cursor — pregúntale)\n- Escribe la skill de Coasts en `.cursor/skills/coasts/SKILL.md`\n\n## Paso 5: Actualizar el Coastfile\n\nLee el `Coastfile` en la raíz del proyecto. Observa el campo `worktree_dir` en la\nsección `[coast]`. También lee el campo `name` — lo necesitarás para construir la\nruta del worktree.\n\nEl directorio de worktree de Cursor es `~/.cursor/worktrees/`, donde `` es\nel valor del campo `name` en el Coastfile.\n\nSi esa ruta **todavía no** aparece en `worktree_dir`:\n\n- Si `worktree_dir` es una sola cadena, conviértela en un arreglo y agrega la\n ruta de Cursor. Por ejemplo, `worktree_dir = \".worktrees\"` se convierte en\n `worktree_dir = [\".worktrees\", \"~/.cursor/worktrees/my-app\"]`.\n- Si `worktree_dir` ya es un arreglo, agrega la ruta de Cursor a él.\n- Si `worktree_dir` no está presente en absoluto, agrega\n `worktree_dir = [\".worktrees\", \"~/.cursor/worktrees/\"]` usando el\n nombre real del proyecto.\n\nEsta es una ruta externa, por lo que si ya hay una instancia de Coast ejecutándose para este\nproyecto, debe recrearse con `coast run` para que el nuevo bind mount surta\nefecto. Díselo al usuario.\n\n## Paso 6: Confirmar\n\nDespués de colocar los archivos, muestra al usuario un resumen de qué se creó y dónde.\n\nDile al usuario: **Reinicia Cursor** para que los cambios de la skill y de las reglas\nsurtan efecto.\n", + "harnesses/shep_setup_prompt.txt": "Estás configurando la skill de Coasts para Shep en este proyecto. Ejecuta todos\nlos comandos desde la raíz del proyecto.\n\n## Paso 1: Verificar Coast CLI\n\nEjecuta este comando:\n\n coast --version\n\nSi no se encuentra el comando `coast`, detente aquí y dile al usuario:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nNo continúes hasta que el CLI esté disponible.\n\n## Paso 2: Obtener el contenido de la skill\n\nEjecuta este comando:\n\n coast skills-prompt\n\nLa salida tiene dos partes:\n\n- **Reglas de Coast Runtime** — todo desde el inicio hasta (pero sin incluir) la línea que comienza con `---`\n- **Skill de Coasts** — todo desde el bloque de frontmatter `---` en adelante (incluyendo las líneas `---` y todo lo que sigue después)\n\nGuarda ambas partes para los pasos a continuación.\n\n## Paso 3: Colocar archivos\n\nShep envuelve Claude Code, así que usa la estructura de archivos de Claude Code. Si un archivo de destino\nya existe, agrega la sección de Coast Runtime en lugar de sobrescribirla, pero\nprimero verifica si ya está presente una sección `# Coast Runtime` y omítela si\nes así.\n\n- Agrega las reglas de Coast Runtime a `CLAUDE.md` en la raíz del proyecto\n- Escribe la skill de Coasts en `.agents/skills/coasts/SKILL.md` (o\n `.claude/skills/coasts/SKILL.md` si el proyecto ya usa esa estructura)\n\n## Paso 4: Actualizar el Coastfile\n\nLee el `Coastfile` en la raíz del proyecto. Observa el campo `worktree_dir` en la\nsección `[coast]`.\n\nSi `~/.shep/repos/*/wt` **aún no** está incluido en `worktree_dir`:\n\n- Si `worktree_dir` es una sola cadena, conviértelo en un arreglo y agrega\n `~/.shep/repos/*/wt`. Por ejemplo, `worktree_dir = \".worktrees\"` se convierte en\n `worktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]`.\n- Si `worktree_dir` ya es un arreglo, agrega `~/.shep/repos/*/wt`.\n- Si `worktree_dir` no está presente en absoluto, agrega\n `worktree_dir = [\".worktrees\", \"~/.shep/repos/*/wt\"]`.\n\nEl `*` es un patrón glob que coincide con el directorio hash por repositorio. Coasts\nlo expande en tiempo de ejecución.\n\nEsta es una ruta externa, así que si ya se está ejecutando una instancia de Coast para este\nproyecto, debe recrearse con `coast run` para que el nuevo bind mount surta\nefecto. Díselo al usuario.\n\n## Paso 5: Confirmar\n\nDespués de colocar los archivos, muestra al usuario un resumen de lo que se creó y dónde.\n\nDile al usuario: **Cierra y vuelve a abrir tu editor** para que los cambios de la skill y de CLAUDE.md\nsurtan efecto.\n", + "harnesses/t3_code_setup_prompt.txt": "Estás configurando la habilidad Coasts para T3 Code en este proyecto. Ejecuta todos\nlos comandos desde la raíz del proyecto.\n\n## Paso 1: Verificar Coast CLI\n\nEjecuta este comando:\n\n coast --version\n\nSi no se encuentra el comando `coast`, detente aquí y dile al usuario:\n\n \"The Coast CLI is not installed. Install it first: https://coasts.dev/docs/getting-started\"\n\nNo continúes hasta que el CLI esté disponible.\n\n## Paso 2: Obtener el contenido de la habilidad\n\nEjecuta este comando:\n\n coast skills-prompt\n\nLa salida tiene dos partes:\n\n- **Reglas de Coast Runtime** — todo desde el inicio hasta (pero sin incluir) la línea que comienza con `---`\n- **Habilidad Coasts** — todo desde el bloque de frontmatter `---` en adelante (incluyendo las líneas `---` y todo lo que sigue)\n\nGuarda ambas partes para los pasos siguientes.\n\n## Paso 3: Preguntar al usuario\n\nT3 Code admite múltiples proveedores. Pregunta al usuario: ¿qué proveedores usas\nen T3 Code?\n\n- **Codex** (OpenAI)\n- **Claude** (Anthropic)\n- **Ambos**\n- **Otro** — si el usuario nombra un proveedor diferente, ejecuta\n `coast docs --path SKILLS_FOR_HOST_AGENTS.md` y\n `coast docs --path harnesses/README.md` para determinar dónde ese proveedor\n espera las instrucciones del proyecto y las habilidades, y luego sigue el mismo patrón\n\n## Paso 4: Colocar archivos\n\nLa configuración de T3 Code siempre es a nivel de proyecto. Si un archivo de destino ya existe, añade\nla sección Coast Runtime en lugar de sobrescribirla, pero primero verifica si ya\nhay una sección `# Coast Runtime` y omítela si es así.\n\n**Si el usuario seleccionó Codex (o ambos):**\n- Añade las reglas de Coast Runtime a `AGENTS.md` en la raíz del proyecto\n- Escribe la habilidad Coasts en `.agents/skills/coasts/SKILL.md` (a nivel de proyecto)\n- También escribe la habilidad Coasts en `~/.codex/skills/coasts/SKILL.md` (respaldo\n global — es posible que T3 Code todavía no examine `.agents/skills/` a nivel de proyecto)\n- Crea `.agents/skills/coasts/agents/openai.yaml` con este contenido:\n\ninterface:\n display_name: \"Coasts\"\n short_description: \"Inspect, assign, and open Coasts for this repo\"\n default_prompt: \"Use this skill when the user wants help finding, assigning, or opening a Coast.\"\n\npolicy:\n allow_implicit_invocation: false\n\n**Si el usuario seleccionó Claude (o ambos):**\n- Añade las reglas de Coast Runtime a `CLAUDE.md` en la raíz del proyecto\n- Escribe la habilidad Coasts en `.claude/skills/coasts/SKILL.md` (a nivel de proyecto)\n- También escribe la habilidad Coasts en `~/.claude/skills/coasts/SKILL.md` (respaldo\n global — es posible que T3 Code todavía no examine `.claude/skills/` a nivel de proyecto de forma confiable)\n\n**Nota:** Es posible que T3 Code todavía no cargue habilidades a nivel de proyecto desde `.agents/skills/` o\n`.claude/skills/`. Las reglas de `AGENTS.md` y `CLAUDE.md` siguen aplicándose en\ncada tarea de todos modos. El respaldo global `~/.codex/skills/coasts/` garantiza\nque el proveedor Codex pueda encontrar la habilidad.\n\n## Paso 5: Actualizar el Coastfile\n\nLee el `Coastfile` en la raíz del proyecto. Revisa el campo `worktree_dir` en la\nsección `[coast]`. También lee el campo `name`; lo necesitarás para construir la\nruta del worktree.\n\nEl directorio de worktree de T3 Code es `~/.t3/worktrees/`, donde `` es\nel valor del campo `name` en el Coastfile.\n\nSi esa ruta **aún no** aparece en `worktree_dir`:\n\n- Si `worktree_dir` es una sola cadena, conviértela en un arreglo y añade la\n ruta de T3 Code. Por ejemplo, `worktree_dir = \".worktrees\"` se convierte en\n `worktree_dir = [\".worktrees\", \"~/.t3/worktrees/my-app\"]`.\n- Si `worktree_dir` ya es un arreglo, añade la ruta de T3 Code.\n- Si `worktree_dir` no está presente en absoluto, agrega\n `worktree_dir = [\".worktrees\", \"~/.t3/worktrees/\"]` usando el\n nombre real del proyecto.\n\nEsta es una ruta externa, así que si ya hay una instancia de Coast ejecutándose para este\nproyecto, debe recrearse con `coast run` para que el nuevo bind mount surta\nefecto. Díselo al usuario.\n\n## Paso 6: Confirmar\n\nDespués de colocar los archivos, muestra al usuario un resumen de lo que se creó y dónde.\nExplica que la copia global `~/.codex/skills/coasts/` es una solución temporal para\nque T3 Code aún no cargue habilidades a nivel de proyecto.\n\nDile al usuario: **Reinicia T3 Code** para que los cambios en la habilidad y las reglas surtan\nefecto.\n", "learn-coasts-videos/README.md": "# Curso en video de Coasts\n\nUn curso corto en video que cubre las ideas fundamentales detrás de Coasts. Cada lección dura menos de tres minutos. Míralas en orden para obtener el panorama completo, o ve directamente al tema que necesites.\n\n```youtube\nMBGKSKau4sU\n```\n\n## Lecciones\n\n1. [Coasts](coasts.md) — qué es un Coast y cómo funciona el modelo central.\n2. [Ports](ports.md) — cómo Coasts maneja el aislamiento de puertos y el acceso paralelo en tiempo de ejecución.\n3. [Assign](assign.md) — cambiar un Coast en ejecución entre worktrees.\n4. [Checkout](checkout.md) — llevar un Coast a tus puertos canónicos para uso activo.\n5. [Volumes](volumes.md) — cómo Coasts gestiona los volúmenes y el estado persistente del servicio.\n6. [Secrets](secrets.md) — gestionar secretos dentro de un Coast.\n7. [Getting Started](getting-started.md) — una guía práctica para probar Coasts en un proyecto real.\n8. [Coast UI](coast-ui.md) — la interfaz Coastguard y la información de tiempo de ejecución que expone.\n", "learn-coasts-videos/assign.md": "# Asignar\n\n```youtube\nLYCeequ54nk\n```\n\nAsignar mueve un Coast en ejecución de un worktree a otro sin desmantelar el entorno de ejecución. Este video explica cómo funciona la asignación y cuándo la usarías para entregar un Coast a una rama diferente.\n\nPara la referencia completa, consulta [Assign and Unassign](../concepts_and_terminology/ASSIGN.md).\n", "learn-coasts-videos/checkout.md": "# Checkout\n\n```youtube\nJRAXkM4U1UE\n```\n\nCheckout asigna los puertos canónicos de tu proyecto a una instancia específica de Coast. Este video muestra cómo poner un Coast al frente para que tu navegador, clientes de API y conjuntos de pruebas apunten al entorno correcto sin cambiar ningún número de puerto.\n\nPara la referencia completa, consulta [Checkout](../concepts_and_terminology/CHECKOUT.md).\n", diff --git a/docs/harnesses/CLAUDE_CODE.md b/docs/harnesses/CLAUDE_CODE.md index 2a7ebf5..fa75a26 100644 --- a/docs/harnesses/CLAUDE_CODE.md +++ b/docs/harnesses/CLAUDE_CODE.md @@ -29,6 +29,10 @@ layers for Coasts: - `.claude/commands/coasts.md` only when you want a command file as an extra entrypoint +```youtube +yjMFVoOiAW0 +``` + ## Setup Add `.claude/worktrees` to `worktree_dir`: diff --git a/docs/harnesses/CODEX.md b/docs/harnesses/CODEX.md index cbecb65..90caf6b 100644 --- a/docs/harnesses/CODEX.md +++ b/docs/harnesses/CODEX.md @@ -26,6 +26,10 @@ From the [Codex docs](https://developers.openai.com/codex/app/worktrees/): Because these worktrees live outside the project root, Coasts needs explicit configuration to discover and mount them. +```youtube +MDidmMQtaqU +``` + ## Setup Add `~/.codex/worktrees` to `worktree_dir`: diff --git a/docs/harnesses/CONDUCTOR.md b/docs/harnesses/CONDUCTOR.md index cd407f0..59b49f9 100644 --- a/docs/harnesses/CONDUCTOR.md +++ b/docs/harnesses/CONDUCTOR.md @@ -19,6 +19,10 @@ You can also get the skill content from the CLI: `coast skills-prompt`. After setup, **fully close and reopen Conductor** for changes to take effect. If the `/coasts` command does not appear, close and reopen again. +```youtube +mbwilJHlanQ +``` + ## Setup Add `~/conductor/workspaces/` to `worktree_dir`. Unlike Codex (which stores all projects under one flat directory), Conductor nests worktrees under a per-project subdirectory, so the path must include the project name. In the example below, `my-app` must match the actual folder name under `~/conductor/workspaces/` for your repo.