diff --git a/AGENTS.md b/AGENTS.md index 2a29f48b..00e8765a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,5 +1,48 @@ # Development Rules +## Build & Test +- `npm run build` - Build (wireit + tsup, ESM) +- `npm run test` - Unit/integration tests (Vitest) +- `npm run test:smoke` - Smoke tests (builds first, serial execution) +- `npm run lint` / `npm run lint:fix` - ESLint +- `npm run format` / `npm run format:check` - Prettier +- `npm run typecheck` - TypeScript type checking (src + test config) +- `npm run docs:check` - Validate docs match CLI surface + +## Architecture +ESM TypeScript project (`type: module`). Key layers: + +- `src/cli/` - CLI entrypoint, yargs wiring, daemon routing +- `src/server/` - MCP stdio server, lifecycle, workflow/resource registration +- `src/runtime/` - Config bootstrap, session state, tool catalog assembly +- `src/core/manifest/` - YAML manifest loading, validation, tool module imports +- `src/mcp/tools/` - Tool implementations grouped by workflow (mirrors `manifests/workflows/`) +- `src/mcp/resources/` - MCP resource implementations +- `src/integrations/` - External integrations (Xcode tools bridge) +- `src/utils/` - Shared helpers (execution, logging, validation, responses) +- `src/visibility/` - Tool/workflow exposure predicates +- `src/daemon/` - Background daemon for persistent sessions +- `src/rendering/` - Output rendering and formatting +- `src/types/` - Shared type definitions + +## Contributing Workflow +1. Create a branch from `main` +2. Make changes following the conventions in this file +3. Run the pre-commit checklist before committing: + ```bash + npm run lint:fix + npm run typecheck + npm run format + npm run build + npm run docs:check + npm test + ``` +4. Update `CHANGELOG.md` under `## [Unreleased]` +5. Update documentation if adding or modifying features +6. Clone and test against example projects (e.g., `XcodeBuildMCP-iOS-Template`) when changes affect runtime behavior +7. Push and create a pull request with a clear description +8. Link any related issues + ## Code Quality - No `any` types unless absolutely necessary - Check node_modules for external API type definitions instead of guessing @@ -8,6 +51,24 @@ - Always ask before removing functionality or code that appears to be intentional - Follow TypeScript best practices +## Import Conventions +- ESM with explicit `.ts` extensions in `src/` (tsup rewrites to `.js` at build) +- No `.js` imports in `src/` (enforced by ESLint) +- No barrel imports from `utils/index` - import from specific submodules (e.g., `src/utils/execution/index.ts`, `src/utils/logging/index.ts`) + +## Test Conventions +- Vitest with colocated `__tests__/` directories using `*.test.ts` +- Smoke tests in `src/smoke-tests/__tests__/` (separate Vitest config, serial execution) +- Use `vi.mock`/`vi.hoisted` for isolation; inject executors and mock file systems +- MCP integration tests use `McpServer`, `InMemoryTransport`, and `Client` +- External dependencies (command execution, file system) must use dependency injection via `createMockExecutor()` / `createMockFileSystemExecutor()` from `src/test-utils/` + +## Tool Development +- Tool manifests in `manifests/tools/*.yaml` define `id`, `module`, `names.mcp` (snake_case), optional `names.cli` (kebab-case), predicates, and annotations +- Workflow manifests in `manifests/workflows/*.yaml` group tools and define exposure rules +- Tool modules export a Zod `schema`, a pure `*Logic` function, and a `handler` built with `createTypedTool` or `createSessionAwareTool` +- Resource modules export a `handler` (and a pure `*Logic` function); `uri`, `name`, `description`, and `mimeType` are declared in `manifests/resources/*.yaml` + ## Commands - NEVER commit unless user asks @@ -48,8 +109,8 @@ Use these sections under `## [Unreleased]`: - NEVER update snapshot fixtures unless asked to do so, these are integration tests, on failure assume code is wrong before questioning the fixture - #### Attribution -- **Internal changes (from issues)**: `Fixed foo bar ([#123](https://github.com/cameroncook/XcodeBuildMCP/issues/123))` -- **External contributions**: `Added feature X ([#456](https://github.com/cameroncook/XcodeBuildMCP/pull/456) by [@username](https://github.com/username))` +- **Internal changes (from issues)**: `Fixed foo bar ([#123](https://github.com/getsentry/XcodeBuildMCP/issues/123))` +- **External contributions**: `Added feature X ([#456](https://github.com/getsentry/XcodeBuildMCP/pull/456) by [@username](https://github.com/username))` ## Test Execution Rules - When running long test suites (snapshot tests, smoke tests), ALWAYS write full output to a log file and read it afterwards. NEVER pipe through `tail` or `grep` directly — that loses output you may need to debug failures.