# Development Guide

## Getting Started

### Prerequisites

- Node.js 20+
- pnpm 9.15+
- Git 2.30+

### First-Time Setup

```bash
# Clone the repository
git clone https://github.com/ComposioHQ/agent-orchestrator.git
cd agent-orchestrator

# Install dependencies
pnpm install

# Build all packages (required before running dev server)
pnpm build

# Copy example config
cp agent-orchestrator.yaml.example agent-orchestrator.yaml

# Configure your settings
$EDITOR agent-orchestrator.yaml
```

### Running the Dev Server

**IMPORTANT**: The web dashboard depends on built packages. Always build before running the dev server:

```bash
# Build all packages
pnpm build

# Start dev server
cd packages/web
pnpm dev

# Open http://localhost:3000 (or your configured port)
```

### Project Structure

```
agent-orchestrator/
├── packages/
│   ├── core/              # Core types, services, config
│   ├── cli/               # CLI tool (ao command)
│   ├── web/               # Next.js dashboard
│   ├── plugins/           # All plugins
│   │   ├── runtime-*/     # Runtime plugins (tmux, docker, k8s)
│   │   ├── agent-*/       # Agent adapters (claude-code, codex, aider)
│   │   ├── workspace-*/   # Workspace providers (worktree, clone)
│   │   ├── tracker-*/     # Issue trackers (github, linear)
│   │   ├── scm-github/    # SCM adapter
│   │   ├── notifier-*/    # Notification channels
│   │   └── terminal-*/    # Terminal UIs
│   └── integration-tests/ # Integration tests
├── agent-orchestrator.yaml.example
├── .gitleaks.toml         # Secret scanning config
├── .husky/                # Git hooks
└── docs/                  # Documentation
```

## Development Workflow

### Making Changes

1. **Create a feature branch**

   ```bash
   git checkout -b feat/your-feature
   ```

2. **Make your changes**
   - Follow [CLAUDE.md](../CLAUDE.md) conventions
   - Add tests for new features
   - Update documentation

3. **Build and test**

   ```bash
   pnpm build
   pnpm test
   pnpm lint
   pnpm typecheck
   ```

4. **Commit**

   ```bash
   git add .
   git commit -m "feat: add your feature"
   ```

   - Pre-commit hook will scan for secrets
   - Use [Conventional Commits](https://www.conventionalcommits.org/)

5. **Push and open PR**
   ```bash
   git push origin feat/your-feature
   ```

### Code Conventions

**TypeScript:**

- ESM modules (`.js` extensions in imports)
- `node:` prefix for builtins
- Strict mode
- `type` imports for type-only
- No `any` (use `unknown` + type guards)
- Semicolons, double quotes, 2-space indent

**Shell Commands:**

- Always use `execFile` (never `exec`)
- Always add timeouts
- Never interpolate user input
- Never use `JSON.stringify` for shell escaping

**Plugin Pattern:**

```typescript
import type { PluginModule, Runtime } from "@composio/ao-core";

export const manifest = {
  name: "my-plugin",
  slot: "runtime" as const,
  description: "My plugin",
  version: "0.1.0",
};

export function create(): Runtime {
  return {
    name: "my-plugin",
    async create(config) {
      /* ... */
    },
    // ... implement interface
  };
}

export default { manifest, create } satisfies PluginModule<Runtime>;
```

See [CLAUDE.md](../CLAUDE.md) for full conventions.

### Testing

```bash
# Run all tests
pnpm test

# Run tests for specific package
pnpm --filter @composio/ao-core test

# Run tests in watch mode
pnpm --filter @composio/ao-core test -- --watch

# Run integration tests
pnpm test:integration
```

### Working with Worktrees

If using git worktrees (common for parallel agent work):

```bash
# Create worktree
git worktree add ../ao-feature-x feat/feature-x
cd ../ao-feature-x

# Install and build
pnpm install
pnpm build

# Copy config
cp ../agent-orchestrator/agent-orchestrator.yaml .

# Start dev server
cd packages/web
pnpm dev
```

## Security During Development

### Secret Scanning

**Pre-commit hook** runs automatically on every commit:

```bash
🔒 Scanning staged files for secrets...
✅ No secrets detected
```

If secrets are detected:

1. Remove the secret from the file
2. Use environment variables: `${SECRET_NAME}`
3. Add to `.env.local` (in `.gitignore`)
4. Update example configs with placeholders

### What Triggers the Scanner

- API keys: `lin_api_*`, `ghp_*`, `gho_*`, `sk-*`, `AKIA*`
- Tokens: `xoxb-*`, `xoxa-*`, etc.
- Webhooks: `https://hooks.slack.com/*`, `https://discord.com/api/webhooks/*`
- Private keys: `-----BEGIN PRIVATE KEY-----`
- Database URLs: `postgres://user:pass@host`
- Generic patterns: `api_key=...`, `token=...`, `password=...`

### False Positives

If you get a false positive:

1. **Verify it's actually a false positive** (not a real secret!)
2. Update `.gitleaks.toml` allowlist:
   ```toml
   [allowlist]
   regexes = [
     '''your-pattern-here''',
   ]
   ```
3. Commit the `.gitleaks.toml` change first
4. Try committing your file again

### Testing Locally

```bash
# Scan current files (no git history)
gitleaks detect --no-git

# Scan staged files (same as pre-commit hook)
gitleaks protect --staged

# Scan full git history
gitleaks detect
```

## Common Tasks

### Adding a New Plugin

1. **Create plugin package**

   ```bash
   mkdir -p packages/plugins/runtime-myplugin
   cd packages/plugins/runtime-myplugin
   ```

2. **Set up package.json**

   ```json
   {
     "name": "@composio/ao-runtime-myplugin",
     "version": "0.1.0",
     "type": "module",
     "main": "dist/index.js",
     "types": "dist/index.d.ts",
     "scripts": {
       "build": "tsc",
       "typecheck": "tsc --noEmit",
       "test": "vitest"
     },
     "dependencies": {
       "@composio/ao-core": "workspace:*"
     }
   }
   ```

3. **Create src/index.ts** (see plugin pattern above)

4. **Register in core** (`packages/core/src/services/plugin-registry.ts`)

5. **Add tests** (`src/index.test.ts`)

6. **Build and test**
   ```bash
   pnpm --filter @composio/ao-runtime-myplugin build
   pnpm --filter @composio/ao-runtime-myplugin test
   ```

### Updating Interfaces

If you change an interface in `packages/core/src/types.ts`:

1. Update the interface
2. Update all implementations (plugins)
3. Update tests
4. Rebuild all packages: `pnpm build`
5. Run all tests: `pnpm test`

### Debugging

**Enable verbose logging:**

```bash
DEBUG=* pnpm dev
```

**Attach to tmux session:**

```bash
tmux attach -t session-name
# Detach: Ctrl-b d
```

**Inspect session metadata:**

```bash
cat ~/.agent-orchestrator/my-app-3
```

**Check session status:**

```bash
curl http://localhost:3000/api/sessions/my-app-3
```

## Environment Variables

### Development

```bash
# Terminal server ports (for web dashboard)
TERMINAL_PORT=14800
DIRECT_TERMINAL_PORT=14801

# Next.js
NEXT_PUBLIC_TERMINAL_PORT=14800
NEXT_PUBLIC_DIRECT_TERMINAL_PORT=14801
```

### User Secrets

```bash
# GitHub
GITHUB_TOKEN=ghp_...

# Linear
LINEAR_API_KEY=lin_api_...

# Slack
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...

# Anthropic (for Claude Code agent)
ANTHROPIC_API_KEY=sk-ant-api03-...
```

**NEVER commit these to git!**

Use `.env.local` (in `.gitignore`):

```bash
echo 'GITHUB_TOKEN=ghp_...' >> .env.local
echo 'LINEAR_API_KEY=lin_api_...' >> .env.local
```

## Troubleshooting

### Build Fails

```bash
# Clean and rebuild
pnpm clean
pnpm install
pnpm build
```

### Web Dashboard 404s

The web app expects `agent-orchestrator.yaml` in working directory:

```bash
cp agent-orchestrator.yaml.example agent-orchestrator.yaml
```

### Permission Errors in Tests

Some tests require `tmux` or other system tools. Install them:

```bash
# macOS
brew install tmux gitleaks

# Ubuntu
apt-get install tmux
```

### ESM Import Errors

Make sure all packages have `"type": "module"` in `package.json`.

All imports from local files must include `.js` extension:

```typescript
// ✅ Good
import { foo } from "./bar.js";

// ❌ Bad
import { foo } from "./bar";
```

## Resources

- [CLAUDE.md](../CLAUDE.md) — Code conventions and architecture
- [SECURITY.md](../SECURITY.md) — Security best practices
- [packages/core/README.md](../packages/core/README.md) — Core architecture
- [agent-orchestrator.yaml.example](../agent-orchestrator.yaml.example) — Config reference
