aidokitwiki

Adapters and Stack Packs

Audience-Adapter Author Status-Shipped v0.5 Spec-Adapter Contract

Purpose #

Explain the cardinal rule "adapters and stack packs are siblings" — why it exists, what each owns, what breaks if violated.

Big Picture #

Adapters target CLI runtimes — they emit engine directories and configure capability profiles. Stack packs target project conventions — they tell the workflow what Django looks like, what React patterns are standard, what testing framework is used.

A Django project on Claude Code uses the Django stack pack + Claude Code adapter. The same Django project could later add the Codex adapter without touching the Django stack pack. This is orthogonal extension.

Source: .docs/ARCHITECTURE.md §4 / §6.3, ADR-0005, ADR-0006.

How It Works #

Division of responsibility #

From .docs/docs/specs/stack-pack-contract.md §4:

Concern Owner
Engine directory layout Adapter
Agent rules file format Adapter
Verb / role / hook file emission Adapter
Capability profile enforcement Adapter
MCP installation mechanism (claude mcp add, …) Adapter
Detecting the stack from project files Stack pack
Stack-specific skill templates (e.g., Zod conventions) Stack pack
Which MCPs are useful for this stack Stack pack
Default validation commands (lint, typecheck, test) Stack pack
Optional architecture pattern hints Stack pack

How they compose #

@aidokit/cli orchestrates:

  1. Each enabled stack pack returns data: SkillTemplate[], MCP ids, validation commands, optional pattern hint.
  2. Outputs are concatenated, de-duplicated, and conflict-resolved by the CLI (not by either extension).
  3. The selected adapter receives the merged data and emits files in its CLI's native format.

This is why stack packs MUST NOT emit files directly (the cardinal rule per ADR-0006 §2). If they did, every stack pack would need to know which adapter is running, and orthogonality would die.

The interfaces #

Adapter (.docs/docs/specs/adapter-contract.md §5): 12 methods plus a static manifest. Split by concern (emitAgentRulesFile, emitEngineConfig, emitVerbs, emitRoles, emitSkills, emitWatchdog, emitOutputStyles, installMCP, removeMCP, listInstalledMCPs, postInstall, preSync, doctor).

StackPack (.docs/docs/specs/stack-pack-contract.md §6): 4 required methods + 1 optional + manifest. detect, suggestSkills, suggestMCPs, suggestValidationCommands, and the Strict-only defaultArchitecturePattern.

Both are TypeScript interfaces exported from @aidokit/core — not YAML, not runtime plugins.

Example: a Next.js project #

The user runs aidokit init. The CLI detects package.json + tsconfig.json + react + next and surfaces three candidate packs:

? Stack packs (multi-select; all suggested defaults shown):
  ◉ node-ts        (high confidence)
  ◉ react          (high confidence)
  ◯ next-js        (not yet shipped) > [!TODO] Confirm with maintainer.

User selects node-ts + react. The selected adapter (e.g. claude-code) calls:

// @aidokit/cli (sketch)
const skills = selectedStackPacks.flatMap(sp => sp.suggestSkills(ctx));
const mcpIds = [...new Set(selectedStackPacks.flatMap(sp => sp.suggestMCPs(ctx)))];
const validations = selectedStackPacks.flatMap(sp => sp.suggestValidationCommands(ctx));

const skillFiles = adapter.emitSkills(ctx, [...CORE_BASE_SKILLS, ...skills]);
// ...

The same selection on the codex adapter would call codexAdapter.emitSkills(ctx, …) with the identical skills array — different output layout, same input.

Diagram #

See diagrams/adapter-composition.md.

Common Mistakes #

Checklist for an adapter author #

Checklist for a stack-pack author #