Skip to content

Development Guide

Agents and quick verify: Agent harness · Do / don’t / pitfalls: Agent golden rules · Root index: AGENTS.md

Install dependencies
cd agent-detective
pnpm install

See configuration-hub.md for load order and top-level keys, then configuration.md for default.json / local.json merge rules, supported environment variables, and generated plugin option schemas.

config/default.json
{
"port": 3001,
"agent": "opencode",
"plugins": [
{
"package": "@agent-detective/local-repos-plugin",
"options": {
"repos": [
{
"name": "my-project",
"path": "/path/to/your/project",
"description": "Your project description"
}
],
"techStackDetection": {
"enabled": true
},
"validation": {
"failOnMissing": false
}
}
},
{
"package": "@agent-detective/jira-adapter",
"options": {
"enabled": true,
"mockMode": true
}
}
]
}
Terminal window
pnpm run dev

Uses tsx watch — auto-restarts on changes.

End-to-end Jira webhook testing (tunnel, labels, smoke script): e2e/jira-manual-e2e.md.

  • Root package.json is the main Fastify app (src/, test/). It is not a separate package under packages/, but it depends on workspace packages via workspace:*.
  • Workspace packages live under packages/* and an optional app package under apps/* (the documentation site is in apps/docs). All are listed in pnpm-workspace.yaml. Shared dependency versions use the catalog: protocol defined in that file.
  • Dependency upgrades: Bump shared tools and runtime libraries in the catalog: section of pnpm-workspace.yaml, then pnpm install, so every package that references "catalog:" for that name updates together. Dependencies that are not in the catalog (for example Astro or Tailwind under apps/, or pino under packages/observability) are upgraded in that package’s own package.json. After any bump, run pnpm run build, pnpm test, and pnpm run lint. Use pnpm outdated -r to see newer versions across the workspace.
  • pnpm run build runs Turborepo (turbo run build) and builds every workspace package’s dist/. It does not bundle the root server by itself.
  • pnpm run build:app runs tsup on the root entrypoint and writes dist/index.js for pnpm start (run pnpm run build first so workspace packages are built).
  • pnpm run typecheck runs turbo run typecheck for packages and tsc --noEmit at the repo root for src/ + test/.
  • pnpm test runs turbo run test (package tests, e.g. @agent-detective/jira-adapter, with ^build deps) then root tests with tsx on test/**/*.test.ts.
  • npm publish is automated by release-please on merge of the Release PR (see publishing.md); do not publish manually from a dirty tree unless debugging.
  • Turborepo cache: stored under .turbo/ at the repo root. To discard local task cache: rm -rf .turbo (or pnpm exec turbo daemon clean if you use the daemon). pnpm run clean runs each package’s clean script (typically rm -rf dist) via turbo run clean.

pnpm-workspace.yaml lists only packages/* (the root app is not a subfolder package; it is the repo root with its own package.json).

turbo.json defines build, typecheck, lint, test, and clean with dependsOn: ["^build"] where needed so dependency packages build first.

tsup is used in packages for fast ESM + dts output; the root app uses tsup for build:app to emit dist/index.js.

CommandDescription
pnpm run buildBuild all workspace packages (Turbo, cached)
pnpm run typecheckturbo run typecheck + root tsc --noEmit
pnpm run testPackage tests + root test/**/*.test.ts
pnpm run cleanEach package’s clean (e.g. rm -rf dist)
Release PR mergerelease-please tags and publishes agent-detective + @agent-detective/* (see publishing.md)

Build order (conceptual): types and process-utils have no workspace deps; core and observability depend on types; plugins depend on types/core/process-utils as declared in their package.json. Turbo resolves the graph via ^build.

New package: create packages/<name>/ with package.json, tsup.config.ts, tsconfig.json extending the repo base, and list workspace deps as workspace:*. See a sibling package (e.g. packages/jira-adapter) as a template.

VS Code: point TypeScript at the workspace SDK:

.vscode/settings.json
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
Build commands
# Build all workspace packages (Turborepo, cached)
pnpm run build
# Bundle the root server to dist/ (production entrypoint)
pnpm run build:app
# TypeScript type checking (packages via Turbo + root tsc)
pnpm run typecheck
# ESLint (all packages that define a lint script)
pnpm run lint
# Remove dist/ in packages (turbo run clean)
pnpm run clean
Test commands
# Run all tests
pnpm test
# Watch mode
pnpm run test:watch
  • Directorysrc/ Main application (TypeScript)
    • Directorycore/
      • types.ts Re-exports from @agent-detective/types
      • agent-runner.ts Executes prompts against AI agents
      • queue.ts Task queuing (prevents parallel execution)
      • process.ts Shell command execution
      • plugin-system.ts Plugin loader & registry
      • schema-validator.ts Plugin schema validation
    • Directoryagents/ AI agent integrations
      • index.ts Agent registry
      • opencode.ts
      • claude.ts
      • cursor.ts
      • utils.ts
    • server.ts Fastify server (+ Core API endpoints)
    • index.ts Bootstrap
  • Directorypackages/ Workspace packages
    • Directorytypes/ @agent-detective/types
      • …
    • Directorysdk/ @agent-detective/sdk
      • …
    • Directoryobservability/ @agent-detective/observability
      • …
    • Directoryprocess-utils/ @agent-detective/process-utils
      • …
    • Directorylocal-repos-plugin/ @agent-detective/local-repos-plugin
      • …
    • Directoryjira-adapter/ @agent-detective/jira-adapter
      • …
  • Directorytest/ Main app tests
    • Directorycore/
      • …
  • Directoryconfig/
    • default.json Server configuration
  • Directorydocs/ Documentation
    • …
Run adapter tests
cd packages/jira-adapter
pnpm test

When mockMode: false, set Jira credentials via config or JIRA_* env (see configuration.md).

Smoke tests: Agent harness — plugin / integration smoke (pnpm run jira:webhook-smoke, pnpm run ci:webhook-smoke). npm operators: agent-detective smoke — get started.

Set log level via observability in config or OBSERVABILITY_LOG_LEVEL / LOG_LEVEL (see observability.md).

For a complete plugin development guide, see plugins.md.

Plugin authors import everything from @agent-detective/sdk (types and runtime helpers). @agent-detective/types is host-internal:

Plugin imports
import type { Plugin, PluginContext } from '@agent-detective/sdk';