# Introduction

Prongs is the intent layer between your agents and your codebase: an open spec, a framework that implements it, and presets for UI, errors and logs that you and your agents extend. Code says what something is for; your registry decides what that resolves to; a checker keeps the two honest.

## The problem

Every codebase is full of small decisions that should be made once: how a destructive button looks, which status a taken username gets, what an audit log line holds. Written by hand, each call site makes them again, and they drift. The same caption is styled sixteen ways, a database error reaches the browser as a 400, a failure is caught and never recorded.

Coding agents make this worse, not because they are careless but because they are guessing. Given a blank JSX tag or a failed query, an agent has to judge what the convention is. Conventions written in prose (a style guide, a long AGENTS.md) are advice it may or may not follow, and nothing tells it when it got one wrong.

## The idea

Intents are to your codebase what status codes are to HTTP. A 404 means the same thing in every API, so nobody re-decides it per endpoint. An intent is that kind of agreed word for the rest of your code: the call site says what something is for, and nothing else.

```tsx
<Action intent="action.delete" onClick={removeProject}>Delete project</Action>

return fail('conflict.duplicate', 'That handle is already taken.');

log('audit.created', 'Account created', { userId: user.id });
```

Each of these is defined once, in a registry in your repo, which decides what it resolves to. [`action.delete`](https://www.prongs.dev/docs/intents/action/delete.md) becomes a `<button>` with the destructive look; [`conflict.duplicate`](https://www.prongs.dev/docs/intents/conflict/duplicate.md) a 409 with that message and its code; [`audit.created`](https://www.prongs.dev/docs/intents/audit/created.md) a log line at the right level in one known shape. The agent answers one question it can answer from the code, “what is this for?”, instead of re-deciding colours, status codes and log formats.

## A spec, a framework, and presets

**The spec.** The [Prongs Intent Spec](https://www.prongs.dev/docs/spec.md) is an open format: what an intent is, how a registry resolves one, how it is exported and checked. Any tool or language can read a registry, and anyone can write a profile for it.

**The framework.** `@prongsjs/core` implements the spec for TypeScript: typed registries, where intent ids are literal types so a typo fails `tsc`; the check engine; and the `prongs` CLI that writes PRONGS.md, installs agent hooks and runs `prongs check`.

**The presets.** Three profiles ship with starter intents: **UI** (what is this element for?), **errors** (what went wrong, and what is the caller told?) and **logs** (what happened, and who needs to know?). They are a starting point, copied into your repo, not a fixed library.

## Your intents, your mappings

The registry is your code. Change what an intent maps to, and every call site follows: restyle [`control.primary`](https://www.prongs.dev/docs/intents/ui.md#control-primary) and every action built on it changes; point [`status.internal`](https://www.prongs.dev/docs/intents/errors.md#status-internal) elsewhere and every 500 does. When nothing fits, you or your agent add an intent, with a description and “not for… use instead” links to its neighbours:

```bash
npx prongs add-intent action.archive --refs control.secondary \
  --description "Moves something out of view without deleting it"
```

`prongs check --suggest` finds the intents your code is missing: the same overrides and styled elements repeated across files, grouped and ranked, each with the command to add it. The vocabulary grows from the code instead of from a style guide.

## Named, typed, checked

**Named.** Every intent has a description, the words code uses for it, and its neighbours. `prongs spec` compiles them into PRONGS.md, the index an agent reads before it writes code. It is generated from the registry, so it cannot drift.

**Typed.** An unknown intent, an intent from the wrong domain, or a look intent used at a call site fails `tsc`.

**Checked.** `prongs check` finds code that goes around the registry: styled raw elements, hand-written error responses, a database error sent to the caller, stray `console` calls. Installed as an agent hook, it runs after every edit and tells the agent which intent to use while the code is still in front of it.

## Does it work?

We ran the same agent harness with and without Prongs: fresh agents built two apps from scratch, then worked through a chain of tickets. With Prongs they wrote 92% fewer one-off styles (10 against 133 after 18 tickets), gave every API error the right status (21 of 21, against 17 of 21), and wrote 23% less code. [See how we tested, and run it yourself](https://github.com/drewpoling2/prongs/blob/main/evals/RESULTS.md).

## What it is not

Prongs is not a component library with a fixed look, a CSS framework, or an error or logging library. Tailwind still does the styling and your logger still writes the lines; the components, helpers and registry are copied into your repo and are yours to change. Prongs decides where those choices are made: once, by name, in the registry.
