aidokitwiki

Three-Layer Architecture

Audience-Contributor Status-Shipped v0.5 Spec-Adapter Contract ADR-0005

Purpose #

Explain the three-layer dependency structure that all aidokit packages obey, and the non-negotiable rules that protect it.

Big Picture #

From .docs/ARCHITECTURE.md §1, §4 and CLAUDE.md §4. The structure is strict-downward: a package may only depend on packages in its own layer (siblings — limited cases) or lower layers.

Layer 3   @aidokit/cli                                     (user-facing shell)
              │
Layer 2   @aidokit/adapter-*       @aidokit/stack-pack-*   (siblings; compose orthogonally)
              │                         │
Layer 1   @aidokit/core   @aidokit/shared-docs   @aidokit/stack-detect
          @aidokit/prereq-check    @aidokit/mcp-catalog    @aidokit/base-skills
%%{init: {
  "theme": "base",
  "themeVariables": {
    "fontFamily": "ui-sans-serif, system-ui, -apple-system, Segoe UI, sans-serif",
    "fontSize": "14px",
    "primaryColor": "#eff6ff",
    "primaryTextColor": "#0f172a",
    "primaryBorderColor": "#2563eb",
    "lineColor": "#475569",
    "secondaryColor": "#f1f5f9",
    "tertiaryColor": "#ffffff",
    "clusterBkg": "#f8fafc",
    "clusterBorder": "#cbd5e1"
  }
}}%%
flowchart TB
  classDef actor    fill:#ede9fe,stroke:#6d28d9,color:#1e1b4b,stroke-width:1.2px;
  classDef cli      fill:#dbeafe,stroke:#1d4ed8,color:#0c1f4a,stroke-width:1.4px;
  classDef adapter  fill:#cffafe,stroke:#0e7490,color:#083344;
  classDef pack     fill:#dcfce7,stroke:#15803d,color:#052e16;
  classDef core     fill:#fef9c3,stroke:#a16207,color:#422006;
  classDef artifact fill:#f1f5f9,stroke:#475569,color:#0f172a;
  classDef stop     fill:#fee2e2,stroke:#b91c1c,color:#7f1d1d,stroke-dasharray:4 3;
  classDef ok       fill:#ecfdf5,stroke:#047857,color:#064e3b;
  classDef external fill:#fff7ed,stroke:#c2410c,color:#431407;

  subgraph L3 ["Layer 3 — user-facing shell"]
    CLI["@aidokit/cli"]:::cli
  end
  subgraph L2 ["Layer 2 — extensions (siblings, never import each other)"]
    direction LR
    AD["@aidokit/adapter-*
claude-code, codex, copilot"]:::adapter SP["@aidokit/stack-pack-*
node-ts, node-js, python, react, go"]:::pack end subgraph L1 ["Layer 1 — core + utilities"] direction LR CORE["@aidokit/core
(zero peer deps)"]:::core SD["@aidokit/shared-docs"]:::core DT["@aidokit/stack-detect"]:::core PR["@aidokit/prereq-check"]:::core MCP["@aidokit/mcp-catalog"]:::core BS["@aidokit/base-skills"]:::core end CLI --> AD CLI --> SP AD --> CORE SP --> CORE SD --> CORE DT --> CORE PR --> CORE MCP --> CORE BS --> CORE

How It Works #

Layer 1 — Core + Utilities #

Package Knows about
@aidokit/core Nothing else — the standalone contract package
@aidokit/shared-docs @aidokit/core types only
@aidokit/stack-detect @aidokit/core types only
@aidokit/prereq-check @aidokit/core types only
@aidokit/mcp-catalog @aidokit/core types only
@aidokit/base-skills @aidokit/core types only

The critical invariant: @aidokit/core has zero runtime dependencies on any other @aidokit/* package. A third-party adapter author installs only @aidokit/core to build against the contract. This is the standalone-SDK contract referenced in CLAUDE.md §4.

Layer 2 — Extensions (siblings) #

Adapters and stack packs are siblings — orthogonal extensions of Layer 1.

Adapters Stack packs
@aidokit/adapter-claude-code @aidokit/stack-pack-node-ts
@aidokit/adapter-codex @aidokit/stack-pack-node-js
@aidokit/adapter-copilot @aidokit/stack-pack-python
@aidokit/stack-pack-react
@aidokit/stack-pack-go

Rules:

Layer 3 — CLI Shell #

Only @aidokit/cli lives here. It is the only package allowed to consume all extensions.

Why this shape #

  1. Adapter portability. A Django stack pack written today must work under tomorrow's Aider adapter without modification — because they never know about each other.
  2. Standalone SDK. Third-party adapter authors install @aidokit/core and build against the interface without dragging in catalogs, prereq checks, or shared docs.
  3. Capability bounding. Layer 1 packages have no IO ambitions; Layer 2 packages declare capabilities in manifests; only Layer 3 (the CLI) performs writes — through a staging directory under user confirmation. See .docs/docs/specs/security-model.md §5.
  4. Conformance harness sanity. Because adapters return data (not perform IO), the harness can test them in a pure-function style — no filesystem mocking required.

Example: where does a new "skill" land? #

A user wants to ship a new built-in skill across all adapters.

That separation is the load-bearing benefit of the layering.

Diagram #

See diagrams/system-overview.md.

Common Mistakes #

Checklist #

When proposing a change: