Thank you for your interest in contributing to AgentSpec!
Real-time discussion happens on Slack. Channels:
| Channel | For |
|---|---|
#general |
Announcements and general discussion |
#help |
"How do I...?" questions about the CLI, SDK, or manifest |
#show-and-tell |
Agents you've built with AgentSpec |
#contributing |
Design discussions, RFCs, and PR coordination |
#bugs |
Quick triage before opening a GitHub issue |
For deeper async threads, use GitHub Discussions.
- Node.js 20+
- pnpm 9+
git clone https://github.com/agents-oss/agentspec.git
cd agentspec
pnpm install
pnpm build
pnpm testAll tests should pass before you start making changes.
| Pattern | Use for |
|---|---|
feat/<short-description> |
New features |
fix/<short-description> |
Bug fixes |
docs/<short-description> |
Documentation only |
chore/<short-description> |
Tooling, deps, CI |
We use Conventional Commits:
feat: add CrewAI adapter
fix: resolve $secret: references on Azure
docs: update LangGraph adapter guide
chore: bump Zod to 3.24
Before opening a PR, verify:
-
pnpm testpasses (all packages) -
pnpm typecheckpasses (zero errors) -
pnpm lintpasses (zero errors) - PR description explains why the change is needed, not just what changed
- New features have tests written first (TDD — see below)
Write tests before implementation. The order is:
- Write a failing test in
src/__tests__/ - Implement the minimum code to pass it
- Refactor
Run tests for a specific package:
pnpm --filter @agentspec/sdk test
pnpm --filter @agentspec/cli test
pnpm --filter @agentspec/adapter-langgraph testCompliance rules live in packages/sdk/src/audit/rules/. Each rule file maps to a compliance pack:
| File | Pack |
|---|---|
security.rules.ts |
owasp-llm-top10 |
model.rules.ts |
model-resilience |
memory.rules.ts |
memory-hygiene |
evaluation.rules.ts |
evaluation-coverage |
To add a rule:
- Open the relevant rules file
- Implement the
AuditRuleinterface:const myRule: AuditRule = { id: 'SEC-LLM-XX', title: 'Short title', pack: 'owasp-llm-top10', severity: 'high', check(manifest) { // return undefined if passes, or { message, recommendation } if fails }, }
- Add it to the exported rules array in the same file
- Write a test in
packages/sdk/src/__tests__/audit.test.ts
Each framework adapter is a separate package (e.g. @agentspec/adapter-crewai).
- Create
packages/adapter-<framework>/ - Implement the
FrameworkAdapterinterface from@agentspec/sdk:import { registerAdapter, type FrameworkAdapter } from '@agentspec/sdk' const myAdapter: FrameworkAdapter = { framework: 'my-framework', version: '0.1.0', generate(manifest, options) { return { framework: 'my-framework', files: { 'agent.py': '...', 'requirements.txt': '...' }, installCommands: ['pip install -r requirements.txt'], envVars: [], readme: '...', } }, } registerAdapter(myAdapter) export { myAdapter }
- Call
registerAdapter(adapter)at module load (side-effect import pattern) - Follow the same structure as
packages/adapter-langgraph/ - See
packages/sdk/CLAUDE.mdfor detailed field mapping guidance
After modifying packages/sdk/src/schema/manifest.schema.ts, regenerate the IDE autocomplete schema:
pnpm schema:export
# or
make schemaCommit the updated schemas/v1/agent.schema.json.
- 💬 Slack — fastest, best for quick "how do I..." questions
- 🧵 GitHub Discussions — for longer-lived async threads
- 🐞 GitHub Issues — for confirmed bugs and feature requests