{"_id":"@andrewhopper/fd","_rev":"5-b285a8b3e1c12902ebcb1c3097441452","name":"@andrewhopper/fd","dist-tags":{"latest":"0.1.6"},"versions":{"0.1.0":{"name":"@andrewhopper/fd","version":"0.1.0","keywords":["ai","agent","state-machine","workflow","monitoring","claude","flight-director"],"license":"MIT","_id":"@andrewhopper/fd@0.1.0","maintainers":[{"name":"andrewhopper","email":"hopperab@gmail.com"}],"homepage":"https://github.com/andrewhopper/flightdirector","bugs":{"url":"https://github.com/andrewhopper/flightdirector/issues"},"bin":{"fd":"bin/fd","asm-cli":"bin/asm-cli"},"dist":{"shasum":"d9156f64c2481dc40571a5715453d098a61accf7","tarball":"https://registry.npmjs.org/@andrewhopper/fd/-/fd-0.1.0.tgz","fileCount":254,"integrity":"sha512-8xtRA2dqVkMkRgEyIaw8hbLdGyYhQvmNBTNsMveisIzNRzTaH/24VOgJzl+jWah6HPNMqJMmhvHVsqdQKOvYMA==","signatures":[{"sig":"MEQCIE4dOSjuXCZsMp1D9q+B2ozMl07ATjN+XthGOgAclc49AiBGAdzO9JeevUz8GiDwALoGgloICd+14OH1yiNWS4ittA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1873863},"engines":{"node":">=18"},"gitHead":"a5efb3d3013987e313fa8ff5ff8f80df3d229104","scripts":{"postinstall":"bash scripts/bootstrap.sh"},"_npmUser":{"name":"andrewhopper","email":"hopperab@gmail.com"},"repository":{"url":"git+https://github.com/andrewhopper/flightdirector.git","type":"git"},"_npmVersion":"10.8.2","description":"Flight Director — visualize and monitor AI agent state machines","directories":{},"_nodeVersion":"20.20.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"optionalDependencies":{"@andrewhopper/fd-darwin-arm64":"0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/fd_0.1.0_1774302922462_0.23357907749221019","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@andrewhopper/fd","version":"0.1.1","keywords":["ai","agent","state-machine","workflow","monitoring","claude","flight-director"],"license":"MIT","_id":"@andrewhopper/fd@0.1.1","maintainers":[{"name":"andrewhopper","email":"hopperab@gmail.com"}],"homepage":"https://github.com/andrewhopper/flightdirector","bugs":{"url":"https://github.com/andrewhopper/flightdirector/issues"},"bin":{"fd":"bin/fd","asm-cli":"bin/asm-cli"},"dist":{"shasum":"8a51172f7e8d38ca63e910ca8002a33b144dc01e","tarball":"https://registry.npmjs.org/@andrewhopper/fd/-/fd-0.1.1.tgz","fileCount":258,"integrity":"sha512-J+pCFbUXSRuPSdjPsfXu5k3HCvIUtwLEM1XFLxgHfONQrCbYs71rpfL6UbKsUNTW2xB6sarj3pblCEjxV2aRIQ==","signatures":[{"sig":"MEQCICQ21V2cVsVf2k9/qApA+stNSDxcdAQVJU30mhm7HVr8AiAFIrQkfQtUCG0PKmaI46/irvtORB/eXrdMFFVM7Cjeng==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1931531},"engines":{"node":">=18"},"gitHead":"4fd1913bff2f0cf79f38f8558482ded95e89e9a8","scripts":{"postinstall":"bash scripts/bootstrap.sh"},"_npmUser":{"name":"andrewhopper","email":"hopperab@gmail.com"},"repository":{"url":"git+https://github.com/andrewhopper/flightdirector.git","type":"git"},"_npmVersion":"10.8.2","description":"Flight Director — visualize and monitor AI agent state machines","directories":{},"_nodeVersion":"20.20.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"optionalDependencies":{"@andrewhopper/fd-darwin-arm64":"0.1.1"},"_npmOperationalInternal":{"tmp":"tmp/fd_0.1.1_1774543892513_0.14950015349588086","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@andrewhopper/fd","version":"0.1.2","keywords":["ai","agent","state-machine","workflow","monitoring","claude","flight-director"],"license":"MIT","_id":"@andrewhopper/fd@0.1.2","maintainers":[{"name":"andrewhopper","email":"hopperab@gmail.com"}],"homepage":"https://github.com/andrewhopper/flightdirector","bugs":{"url":"https://github.com/andrewhopper/flightdirector/issues"},"bin":{"fd":"bin/fd","asm-cli":"bin/asm-cli"},"dist":{"shasum":"97162042fc146e155e7c87253b514f42fd2d8974","tarball":"https://registry.npmjs.org/@andrewhopper/fd/-/fd-0.1.2.tgz","fileCount":258,"integrity":"sha512-eY9PKrRaT+Ct9DB7kgGN1+CbE/v/IKuBXV01a0dBF/lhZp+59z8/6JXvMns+6qaxK3aZ4rhwfq/4hq52yQ4nDA==","signatures":[{"sig":"MEUCICa1BDI6vs/wsYfy+lOq8lT7s5t7f5xa7Eafmxw9/CiWAiEA3r/kO9zrJI4Y55Zp8Z1NM+CyQ5TlaDASz+uNKjz9JmY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1932049},"engines":{"node":">=18"},"gitHead":"2f915c3379de6a3d32ac12dcd5cf2d9031aee1b0","scripts":{"postinstall":"bash scripts/bootstrap.sh"},"_npmUser":{"name":"andrewhopper","email":"hopperab@gmail.com"},"repository":{"url":"git+https://github.com/andrewhopper/flightdirector.git","type":"git"},"_npmVersion":"10.8.2","description":"Flight Director — visualize and monitor AI agent state machines","directories":{},"_nodeVersion":"20.20.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"optionalDependencies":{"@andrewhopper/fd-darwin-arm64":"0.1.2"},"_npmOperationalInternal":{"tmp":"tmp/fd_0.1.2_1774544918636_0.3841864601872167","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@andrewhopper/fd","version":"0.1.3","keywords":["ai","agent","state-machine","workflow","monitoring","claude","flight-director"],"license":"MIT","_id":"@andrewhopper/fd@0.1.3","maintainers":[{"name":"andrewhopper","email":"hopperab@gmail.com"}],"homepage":"https://github.com/andrewhopper/flightdirector","bugs":{"url":"https://github.com/andrewhopper/flightdirector/issues"},"bin":{"fd":"bin/fd","fd-cli":"bin/fd-cli","asm-cli":"bin/asm-cli"},"dist":{"shasum":"f5faf182750247c56808fac546720f13e58ee6e7","tarball":"https://registry.npmjs.org/@andrewhopper/fd/-/fd-0.1.3.tgz","fileCount":270,"integrity":"sha512-L9LBXigixQD57N+ZDtqCRD4fI5shiz9cV0oL3pFXC+wVSl1Bn5FcM4spMwcZZPCLP/6YTchee1pc1MGBXxsygw==","signatures":[{"sig":"MEUCIQDeVW49c+seXNubluqHEN0VBHDhiPHsLmhAvho2hqwnWQIgHQ04p9m3tO5VsQBqshz/PTGBns36gSIv0JkkvFHj0ts=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2067522},"engines":{"node":">=18"},"gitHead":"e7dc6902081db69b79231701550cd06e4800ddde","scripts":{"postinstall":"bash scripts/bootstrap.sh"},"_npmUser":{"name":"andrewhopper","email":"hopperab@gmail.com"},"repository":{"url":"git+https://github.com/andrewhopper/flightdirector.git","type":"git"},"_npmVersion":"10.8.2","description":"Flight Director — visualize and monitor AI agent state machines","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"optionalDependencies":{"@andrewhopper/fd-darwin-arm64":"0.1.3","@andrewhopper/fd-linux-x64-gnu":"0.1.3"},"_npmOperationalInternal":{"tmp":"tmp/fd_0.1.3_1776090346560_0.11315175683190248","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@andrewhopper/fd","version":"0.1.6","description":"Flight Director — visualize and monitor AI agent state machines","license":"MIT","repository":{"type":"git","url":"git+https://github.com/andrewhopper/flightdirector.git"},"homepage":"https://github.com/andrewhopper/flightdirector","bugs":{"url":"https://github.com/andrewhopper/flightdirector/issues"},"keywords":["ai","agent","state-machine","workflow","monitoring","claude","flight-director"],"bin":{"fd-cli":"bin/fd-cli"},"scripts":{"postinstall":"bash scripts/bootstrap.sh"},"optionalDependencies":{"@andrewhopper/fd-darwin-arm64":"0.1.6","@andrewhopper/fd-linux-x64-gnu":"0.1.6"},"publishConfig":{"access":"public"},"engines":{"node":">=18"},"devDependencies":{"@cucumber/cucumber":"^12.8.1","@types/node":"^25.6.0","ts-node":"^10.9.2","typescript":"^6.0.3"},"_id":"@andrewhopper/fd@0.1.6","gitHead":"20b95e202cb0d7459aa01a41b1add7c69baa5733","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-2o8HtQwbLWF6cAnze82n2gNdE8V95/ERtVh/yuWl2nv5pi/0dsbR1eV0PYSxw5LcizuGp6IAzl81gyMRYiFP0g==","shasum":"c91998d41fef4e23b680c556aa37c350c4fa133b","tarball":"https://registry.npmjs.org/@andrewhopper/fd/-/fd-0.1.6.tgz","fileCount":388,"unpackedSize":3862781,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCDT7/dbeemdftzfx7G6INbihn7/VI2y6YmLvUhyNEM2gIhAPuLDUgWnys8RKvnBZCEmNj9HYAGvWp/DbnwUH84fjJ3"}]},"_npmUser":{"name":"andrewhopper","email":"hopperab@gmail.com"},"directories":{},"maintainers":[{"name":"andrewhopper","email":"hopperab@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/fd_0.1.6_1778769633004_0.5393565022569973"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-23T21:55:22.366Z","modified":"2026-05-14T14:40:33.360Z","0.1.0":"2026-03-23T21:55:22.624Z","0.1.1":"2026-03-26T16:51:32.738Z","0.1.2":"2026-03-26T17:08:38.845Z","0.1.3":"2026-04-13T14:25:46.821Z","0.1.6":"2026-05-14T14:40:33.248Z"},"bugs":{"url":"https://github.com/andrewhopper/flightdirector/issues"},"license":"MIT","homepage":"https://github.com/andrewhopper/flightdirector","keywords":["ai","agent","state-machine","workflow","monitoring","claude","flight-director"],"repository":{"type":"git","url":"git+https://github.com/andrewhopper/flightdirector.git"},"description":"Flight Director — visualize and monitor AI agent state machines","maintainers":[{"name":"andrewhopper","email":"hopperab@gmail.com"}],"readme":"# Flight Director\n\nA sidecar supervisor for coding agents — it doesn't run the agent, it watches and constrains one that's already running.\n\nDefine DAG workflows in YAML that constrain AI agent behavior with tool gates, budgets, and transition rules. Unlike agent frameworks that orchestrate execution, Flight Director sits alongside an autonomous agent and enforces what it's allowed to do at each phase.\n\n## Prerequisites\n\n- **Rust 1.70+** — install via [rustup.rs](https://rustup.rs)\n- **Node.js 18+**\n- **jq**\n- **git**\n\n```\n◉ diagnose  ──[found_it]──→  ○ fix  ──[fix_applied]──→  ○ verify  ──[tests_pass]──→  ◎ done\n   Read,Grep,Glob only          no WebSearch/WebFetch       Read,Bash,Grep only\n   500 tokens / 20 calls        500 tokens / 20 calls       300 tokens / 10 calls\n```\n\n## How it works\n\n![Flight Director Data Flow](docs/diagrams/architecture-data-flow.svg)\n\nEvery tool call flows through the gate engine. On **allow**, a hint is injected back into the agent's context with the current state, instructions, available transitions, budget status, and criteria progress. On **block**, the agent gets a rich error explaining why and what to do instead.\n\n![Complex Bugfix Machine](docs/diagrams/example-bugfix-machine.svg)\n\n![UI Page Generation Machine](docs/diagrams/example-ux-machine.svg)\n\n## What it does\n\n1. **Define workflows as YAML state machines** — states, transitions, tool gates, budgets, exit criteria\n2. **Enforce constraints** — each state restricts which tools the agent can use, what files it can touch, and how many tokens/calls it can spend\n3. **Track progress** — session state persists to disk, transitions are recorded, budgets are monitored\n\nTwo ways to use it:\n\n| | **Rust CLI** (recommended) | **Viewer** (full-stack) |\n|---|---|---|\n| What | Compiled binary with Claude Code hook integration | React + Express app with interactive graph visualization |\n| For | Claude Code — enforces constraints via PreToolUse/PostToolUse hooks | Local dev — watch agents traverse the DAG in real-time |\n| Run | `fd-cli init --machine machine.yaml` | `cd viewer && npm run dev` |\n\n## Quick Start\n\n```bash\n./bin/fd-cli\n```\n\nThat's it. On first run, Flight Director walks you through setup — checks prerequisites, builds the Rust CLI, configures hooks for your AI tools, and lets you pick a workflow machine. On subsequent runs it prints session status and starts the viewer.\n\n```bash\n./bin/fd-cli --setup              # Force re-run the config flow\n./bin/fd-cli --no-viewer          # Print status only\n./bin/fd-cli --machine tdd        # Skip the picker, init with a specific machine\n```\n\nTo build from source directly:\n\n```bash\ncargo build --release\n```\n\n### Which path?\n\n| Goal | Section |\n|------|---------|\n| Just trying it? | [Quick Start](#quick-start) |\n| Building from source? | [Rust CLI](#rust-cli-manual-setup) |\n| Web viewer? | [Viewer Setup](#viewer-full-stack) |\n| Embedding in a project? | [Subtree](#project-structure) |\n\n### Rust CLI (manual setup)\n\n```bash\n# Build and configure hooks for your AI tools\nbash scripts/setup-hooks.sh\n\n# Initialize a session\n./target/release/fd-cli init --machine docs/scenarios/simple-bugfix.yaml\n\n# Check status\n./target/release/fd-cli status\n\n# Transition\n./target/release/fd-cli transition found_it\n\n# View log\n./target/release/fd-cli log\n```\n\n`setup-hooks.sh` builds the binary and auto-detects which AI tools you have installed (Claude Code, Gemini CLI, Kiro). See [Hook Setup](#hook-setup) for details.\n\n### Viewer (full-stack)\n\n```bash\n# First-time setup\nbash scripts/bootstrap.sh\n\n# Start dev server\ncd viewer\nnpm run dev\n```\n\nOpens at [localhost:5199](http://localhost:5199) (client) with API at [localhost:3199](http://localhost:3199) (server).\n\n## Hook Setup\n\n`scripts/setup-hooks.sh` auto-detects installed AI tools and configures each to call `fd-cli` via hooks. It builds the Rust binary, runs bootstrap if needed, and writes the appropriate settings file for each tool.\n\n```bash\n# Configure all detected tools\nbash scripts/setup-hooks.sh\n\n# Configure a specific tool only\nbash scripts/setup-hooks.sh --tool claude-code\nbash scripts/setup-hooks.sh --tool gemini-cli\n\n# Remove Flight Director hooks from all tools\nbash scripts/setup-hooks.sh --uninstall\n\n# Skip the cargo build (binary must already exist)\nbash scripts/setup-hooks.sh --skip-build\n```\n\n### Supported tools\n\n| Tool | Status | Settings file | Hook events |\n|------|--------|---------------|-------------|\n| Claude Code | Native | `.claude/settings.json` | PreToolUse, PostToolUse |\n| Gemini CLI | Adapter | `.gemini/settings.json` | BeforeTool, AfterTool |\n| Kiro | Template | `.kiro/settings.json` | PreToolUse, PostToolUse |\n| Codex | Stub | — | Hooks not yet upstream |\n\n**Claude Code** calls `fd-cli` directly (native protocol). **Gemini CLI** and **Kiro** go through a universal shim (`scripts/hooks/fd-shim.sh`) that translates between each tool's stdin/stdout format and `fd-cli`'s `HookInput`/`HookOutput` protocol.\n\nThe script is idempotent — re-running it replaces existing Flight Director hooks without duplicating them, and preserves any non-Flight Director hooks in the settings file.\n\n### Adding a new tool\n\nCreate a single file in `scripts/hooks/adapters/` implementing the adapter interface:\n\n```bash\nadapter_name()           # \"my-tool\"\nadapter_label()          # \"My Tool\" (human-readable)\nadapter_detect()         # exit 0 if tool is installed\nadapter_ready()          # exit 0 if hooks are supported\nadapter_settings_path()  # path to settings file\nadapter_hooks_json()     # JSON fragment with hook entries\nadapter_uninstall_filter()  # jq filter to remove Flight Director hooks\n```\n\nFor tools that need stdin/stdout translation (not native), also implement:\n\n```bash\nadapter_event_to_fd()            # map tool event → fd-cli subcommand\nadapter_translate_input()        # jq filter: tool stdin → HookInput\nadapter_translate_output_allow() # jq filter: fd-cli allow → tool allow\nadapter_translate_output_block() # jq filter: fd-cli block → tool block\n```\n\nNo changes to `setup-hooks.sh` or `fd-shim.sh` are needed. See [docs/hooks.md](docs/hooks.md) for the fd-cli hook protocol.\n\n## Writing Machines\n\nMachines are YAML files. Here's the simplest possible one:\n\n```yaml\nid: yolo\nname: \"YOLO\"\ndescription: \"No guardrails.\"\n\noverride_policy:\n  allow_override: true\n  allow_waiver: true\n  require_reason: false\n  hard_criteria_bypass: true\n\nstates:\n  - id: code\n    description: \"Write code.\"\n    initial: true\n    transitions:\n      - name: ship_it\n        target:\n          state: ship\n\n  - id: ship\n    description: \"Deploy.\"\n    transitions:\n      - name: done\n        target:\n          state: done\n\n  - id: done\n    description: \"In production.\"\n    terminal: true\n```\n\n### Tool Gates\n\nConstrain which tools the agent can use in a state:\n\n```yaml\n# Only allow these tools\ntool_gates:\n  - gate_type: tool_allowlist\n    params:\n      tools: [Read, Grep, Glob]\n    message: \"Read-only — no edits allowed\"\n    hard: true\n\n# Block specific tools\n  - gate_type: tool_denylist\n    params:\n      tools: [WebSearch, WebFetch]\n    message: \"No web access\"\n    hard: false\n\n# Restrict bash commands\n  - gate_type: bash_policy\n    params:\n      allow_commands: [\"npm test\", \"npm run lint\"]\n      deny_commands: [\"rm -rf\", \"git push --force\"]\n    message: \"Safe commands only\"\n    hard: true\n\n# Restrict file paths for Write/Edit\n  - gate_type: path_pattern\n    params:\n      tools: [Write, Edit]\n      allow_patterns: [\"tests/**\", \"**/*.test.*\"]\n      deny_patterns: [\"src/**\"]\n    message: \"Only test files may be edited\"\n    hard: true\n```\n\nGate types: `tool_allowlist`, `tool_denylist`, `bash_policy`, `path_pattern`, `input_pattern`\n\nWhen `hard: true`, the constraint is absolute. When `hard: false`, it's a soft warning.\n\n### Criteria\n\nConditions evaluated during transitions. Eight built-in types: `min_tool_calls`, `max_tool_calls`, `min_tokens`, `max_tokens`, `min_duration`, `max_duration`, `command`, `file_exists`. See [docs/criteria.md](docs/criteria.md) for full reference.\n\n### Budgets\n\nLimit resource consumption per state:\n\n```yaml\nbudget:\n  max_tokens: 5000\n  max_tool_calls: 30\n  max_wall_time_ms: 300000\n  thresholds:\n    - percent: 70\n      action: Notify\n    - percent: 90\n      action: Block\n```\n\n### Exit Criteria\n\nConditions that must be met before leaving a state:\n\n```yaml\nexit_criteria:\n  - criterion_type: command\n    params:\n      command: \"npm test\"\n      expect_exit_code: 0\n    message: \"Tests must pass\"\n    hard: true\n```\n\n### Auto-transitions\n\nTransitions that fire automatically when a condition is met:\n\n```yaml\ntransitions:\n  - name: tests_pass\n    target:\n      state: refactor\n    auto:\n      criterion_type: command\n      params:\n        command: \"npm test\"\n        expect_exit_code: 0\n      message: \"Auto-advance when tests pass\"\n```\n\n### Fork/Join (Concurrency)\n\n```yaml\ntransitions:\n  - name: parallelize\n    target:\n      type: Fork\n      targets: [lint, test, typecheck]\n      join: merge-results\n```\n\n### Data Flow\n\nPass named data between states — upstream states declare outputs, downstream states declare inputs:\n\n```yaml\nstates:\n  - id: triage\n    data_flow:\n      outputs:\n        - key: bug_classification\n          description: \"Severity, component, symptoms\"\n\n  - id: reproduce\n    data_flow:\n      inputs:\n        - key: bug_classification\n          from_state: triage\n      outputs:\n        - key: error_trace\n          description: \"Stack trace and repro steps\"\n```\n\n### Partitions\n\nSplit work across keys (e.g., test files). On re-entry, only failed partitions re-run:\n\n```yaml\npartitions:\n  keys: [\"tests/**/*.test.ts\"]\n  redo_failed_only: true\n```\n\n### Retry Policy\n\nAuto-retry a state on failure with configurable backoff (`None`, `Linear`, `Exponential`):\n\n```yaml\nretry:\n  max_retries: 3\n  backoff: Exponential\n  base_delay_ms: 2000\n  max_delay_ms: 30000\n  retryable: [CriterionNotMet, Timeout]\n```\n\n### Timeout\n\nTime-limit a state with heartbeat monitoring:\n\n```yaml\ntimeout:\n  state_timeout_ms: 600000\n  on_timeout: ForceTransition    # Notify | ForceTransition | Abort | Retry\n  timeout_transition: next-state\n  heartbeat_interval_ms: 30000\n  on_heartbeat_missed: Notify\n```\n\n### Spawn (Multi-Agent)\n\nLaunch concurrent agents with convergence strategies:\n\n```yaml\n# State-level spawn\nspawn:\n  strategy: Race         # Explore | Race | Vote\n  max_agents: 2\n  convergence:\n    min_agree: 1\n    timeout_ms: 600000\n    on_timeout: AbortSlowest\n  on_limit: NotifyCoordinator\n\n# Machine-level spawn with parameter matrix\nspawn:\n  spawn_point: explore\n  count: 3\n  strategy: Explore\n  params_matrix:\n    - { approach: \"top-down\" }\n    - { approach: \"bottom-up\" }\n    - { approach: \"lateral\" }\n  convergence:\n    max_wall_time_ms: 600000\n    on_limit: Abort\n```\n\nSee [docs/advanced-features.md](docs/advanced-features.md) for full reference on all advanced features.\n\n## Example Machines\n\n| Machine | States | Description |\n|---------|--------|-------------|\n| `yolo` | 3 | No constraints, manual transitions |\n| `simple-bugfix` | 4 | diagnose → fix → verify → done |\n| `tdd` | 7 | Red-green-refactor cycle with loops |\n| `complex-bugfix` | 8 | Retry, heartbeat, bash policy, data flow |\n| `bdd` | — | Behavior-driven development |\n| `greenfield-landing-page` | — | Landing page from scratch |\n| `greenfield-mobile-app` | — | Mobile app from scratch |\n\nAll live in `docs/scenarios/`.\n\n## Documentation\n\n| Doc | What it covers |\n|-----|----------------|\n| [docs/rust-cli.md](docs/rust-cli.md) | Rust CLI command reference |\n| [docs/criteria.md](docs/criteria.md) | Criteria system — all 8 types, hard/soft, waivers |\n| [docs/advanced-features.md](docs/advanced-features.md) | Data flow, partitions, retry, timeout, spawn, join |\n| [docs/hooks.md](docs/hooks.md) | Hook protocol (PreToolUse/PostToolUse) and fd-cli integration |\n| [docs/override-policy.md](docs/override-policy.md) | Override policy, waivers, rollback, trigger types |\n| [docs/architecture.md](docs/architecture.md) | Rust crate architecture, data flow, dependencies |\n| [docs/diagrams/](docs/diagrams/) | PlantUML sequence and component diagrams |\n| [docs/types/](docs/types/) | HTML type reference pages |\n\n## Architecture (Viewer)\n\n```\nviewer/src/\n├── shared/          # Types + YAML parser (used by both)\n│   ├── types/       # Branded IDs, MachineDef, gates, budget, runtime\n│   └── yaml-parser  # YAML → MachineDef\n├── server/          # Express + WebSocket\n│   ├── routes/      # /api/machines, /api/sessions, /api/health\n│   ├── data-source/ # FileReader + ZMQ + HybridSource\n│   └── ws/          # WebSocket bridge\n└── client/          # React 19 + Vite\n    ├── components/  # atoms/ molecules/ organisms/ graph/\n    ├── stores/      # Zustand (machine, session, ui, graph, ws)\n    ├── hooks/       # useWebSocket, useSessionData, useBreadcrumbNav\n    └── lib/         # graph-builder, layout (Dagre), colors, format\n```\n\nData flow: files on disk → Express reads → ZMQ triggers re-reads → WebSocket pushes to React → Zustand stores → graph re-renders.\n\n## Environment Variables\n\n| Variable | Default | Purpose |\n|----------|---------|---------|\n| `ASM_PORT` | `3199` | Express server port |\n| `ASM_HOST` | `127.0.0.1` | Express server host |\n| `ASM_DIR` | `$CWD/.claude/asm/` | Data directory |\n| `ZMQ_ENDPOINT` | `ipc:///tmp/asm.sock` | ZMQ socket for live updates |\n\n## Project Structure\n\n```\nflight-director/\n├── Cargo.toml          # Rust workspace root\n├── crates/\n│   ├── fd-core/        # Library — types, engine, storage, display\n│   └── fd-cli/         # Binary — CLI commands\n├── docs/\n│   ├── scenarios/      # Example YAML machines\n│   ├── diagrams/       # PlantUML architecture diagrams\n│   ├── types/          # HTML type reference pages\n│   ├── rust-cli.md     # CLI command reference\n│   ├── criteria.md     # Criteria system reference\n│   ├── hooks.md        # Claude Code hook integration\n│   ├── override-policy.md # Override & waiver system\n│   ├── architecture.md # Rust crate architecture\n│   └── advanced-features.md # Data flow, partitions, retry, timeout, spawn\n├── scripts/\n│   ├── bootstrap.sh    # First-time setup\n│   ├── setup-hooks.sh  # Configure AI tool hooks\n│   └── hooks/\n│       ├── fd-shim.sh  # Universal shim for non-native tools\n│       └── adapters/   # One file per tool (claude-code, gemini-cli, kiro, codex)\n├── viewer/             # Full-stack viewer app (React + Express)\n└── machines/           # Runtime machine instances\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}