Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ bun run --filter @getdevintern/pm build
### `@getdevintern/code`

- Entry: `src/index.ts`
- Public plugin API: `@getdevintern/code/pipeline` (implemented under `src/lib/pipeline/`); `src/**/*` is included in the published package for this subpath export
- Tests: `bun test` (Bun native test runner in `tests/`)
- Build: `bun run build.ts`: bundles with `Bun.build`, then replaces shebang from `node` to `bun` in `dist/index.js`
- Run locally: `bun start TASK-123`
Expand Down
71 changes: 70 additions & 1 deletion docs/code/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ sidebarLabel: "Configuration"
description: "Environment variables, settings.json, tracker credentials, and agent harness options for @devintern/code."
section: "Code"
order: 2
dateModified: 2026-08-08
dateModified: 2026-08-12
---

# @devintern/code Configuration
Expand Down Expand Up @@ -209,6 +209,75 @@ The active tracker is read from the `TASK_TRACKER` environment variable (default
}
```

## Pipeline Customization

The task workflow is built from pluggable pipeline steps. By default @devintern/code runs: implement, commit, auto-review (when `--auto-review` is set), and finalize (push, comment, PR, status transition). You can reorder steps, add extra checks, or plug in your own steps via the `pipeline` section of `.devintern-code/settings.json`.

```json
{
"pipeline": {
"steps": [
{ "use": "implement" },
{ "use": "commit" },
{ "use": "verify", "onFail": "loopback", "minSeverity": "high", "maxIterations": 3 },
{ "use": "auto-review" },
{ "use": "finalize" }
]
}
}
```

**Built-in steps:** `clarity`, `implement`, `commit`, `auto-review`, `verify`, `finalize`.

### The verify step

`verify` is an agent-backed requirements checker: it reads the task and the committed diff, asks the agent for a structured verdict, and acts on the result. It is not part of the default pipeline; add it when you want an extra gate. Options:

- `prompt`: custom verification instructions (inline text or a path to a prompt file)
- `onFail`: `"loopback"` (default, feed findings back to the implement step and re-verify), `"halt"` (stop and mark the task incomplete), or `"warn"` (record a warning and continue)
- `minSeverity`: findings at or above this priority fail the verdict (default `"high"`)
- `maxIterations`: bound for the loopback cycle (default `3`)

You can add several `verify` entries with different prompts, for example one for functional requirements and one for security review.

### Custom step plugins

For logic that config alone cannot express, write a step module that default-exports a step definition and list it under `pipeline.plugins`. Entries are file paths (resolved against your project root) or npm package names; no rebuild of @devintern/code is required.

```json
{
"pipeline": {
"plugins": ["./.devintern-code/steps/my-lint.ts"],
"steps": [
{ "use": "implement" },
{ "use": "commit" },
{ "use": "my-lint", "threshold": 0.9 },
{ "use": "finalize" }
]
}
}
```

```ts
// .devintern-code/steps/my-lint.ts
import type { StepDefinition } from "@getdevintern/code/pipeline";

const definition: StepDefinition = {
name: "my-lint",
create: (config) => ({
name: "my-lint",
async run(ctx) {
// run checks against ctx.workingDir ...
return { status: "continue" };
},
}),
};

export default definition;
```

Steps return one of four statuses: `continue`, `warn` (record a warning and continue), `halt` (stop; by default the task is reverted to To Do with an incomplete-implementation comment), or `loopback` (jump back to an earlier step with structured findings). Throw `StepExecutionError` for transient failures you want retried.

## Verbose API Logging

To enable detailed API call logging for debugging, set the `DEVINTERN_VERBOSE` environment variable:
Expand Down
53 changes: 53 additions & 0 deletions packages/code/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,27 @@ This file provides guidance to Claude Code when working with this repository.

## Architecture

### Core Components

- **[src/index.ts](src/index.ts)** - Main entry, CLI parsing, orchestrates workflow: fetch → format → git → claude → commit → PR
- **[src/lib/task-tracker-client.ts](src/lib/task-tracker-client.ts)** - Interface for all task tracker clients (JIRA, Linear, Trello, etc.)
- **[src/lib/task-tracker-manager.ts](src/lib/task-tracker-manager.ts)** - Factory that resolves the concrete tracker from the `TASK_TRACKER` environment variable (defaults to JIRA)
- **[src/lib/trackers/jira/jira-task-tracker-client.ts](src/lib/trackers/jira/jira-task-tracker-client.ts)** - JIRA implementation of `TaskTrackerClient`; delegates HTTP to `JiraClient` and issue parsing to `@devintern/task-trackers`
- **[src/lib/trackers/jira/jira-formatter.ts](src/lib/trackers/jira/jira-formatter.ts)** - JIRA-specific ADF comment formatting for @devintern/code automation
- **[src/lib/task-formatter.ts](src/lib/task-formatter.ts)** - Formats task tracker data (ADF/HTML → Markdown) for LLM prompts
- **[src/lib/utils.ts](src/lib/utils.ts)** - Git operations, file handling utilities
- **[src/lib/github-reviews.ts](src/lib/github-reviews.ts)** - GitHub API client for PR reviews
- **[src/lib/review-formatter.ts](src/lib/review-formatter.ts)** - Formats PR review feedback for Claude
- **[src/lib/address-review.ts](src/lib/address-review.ts)** - Handles PR review responses
- **[src/lib/auto-review-loop.ts](src/lib/auto-review-loop.ts)** - Automatic PR self-review and improvement loop; exports the `runAgentPrompt` / `parseReviewFeedback` / `filterByPriority` / `getPRDiff` primitives reused by pipeline steps
- **[src/lib/pipeline/](src/lib/pipeline/)** - Extensible task pipeline (types, registry, runner, config, built-in steps); public plugin API via the `@getdevintern/code/pipeline` subpath export
- **[src/lib/project-settings.ts](src/lib/project-settings.ts)** - settings.json loading + per-project status resolution (extracted from index.ts so steps avoid an import cycle)
- **[src/lib/clarity-check.ts](src/lib/clarity-check.ts)** - Pre-implementation feasibility assessment (`runClarityCheck`)
- **[src/lib/errors.ts](src/lib/errors.ts)** - `UsageLimitError` (aborts a batch; re-thrown by the pipeline runner, never retried)
- **[src/webhook-server.ts](src/webhook-server.ts)** - Webhook server for automated PR review handling
- **[src/types/](src/types/)** - TypeScript interfaces
- `task-tracker.ts` - Platform-agnostic domain types (`Task`, `Comment`, `FormattedTaskDetails`, etc.)
- `jira.ts` - JIRA-specific type aliases (re-exports generic types for backward compatibility)
### Key Workflows

**JIRA Task Processing:**
Expand All @@ -22,6 +43,38 @@ This file provides guidance to Claude Code when working with this repository.

1. Webhook receives review → 2. Check bot mention → 3. Queue review → 4. Switch worktree to PR branch → 5. Fetch comments → 6. Run Claude → 7. Commit fixes → 8. Push & reply

### Pipeline & Steps

Task execution (everything after the `processSingleTask` preamble: fetch → clarity check → branch → In-Progress transition) runs through an ordered pipeline of steps sharing one mutable `TaskContext` (`src/lib/pipeline/`).

**Default pipeline** (used when `settings.pipeline` is absent; reproduces the classic flow):

```
implement → commit → auto-review → finalize
```

- `implement` — runs the agent (`runImplementation`); consumes `ctx.loopbackFeedback` / `ctx.pendingPromptOverride` as prompt overrides
- `commit` — commit with git-hook auto-fix retries; detects plan-only output and loops back to `implement` once with a "now implement the plan" prompt
- `auto-review` — self-gates on `--auto-review`; validates pre-push hook, runs `runAutoReviewLoop({ skipPush: true })`, re-validates
- `finalize` — hook validation (if not already done) → push → tracker comment → PR creation → status transition
- `clarity` and `verify` are registered but **not** in the default list. The preamble clarity check in `processSingleTask` still runs before branch creation; the `clarity` step exists for custom pipelines. `verify` is the opt-in requirements checker.

**Commit ordering matters:** `commit` must run before `auto-review`/`verify` because both diff `origin/<base>...HEAD`; uncommitted changes would be invisible.

**Failure model (two channels):**

- Execution errors (subprocess crash, unparseable verdict JSON) — steps **throw** `StepExecutionError`; the runner retries the step (default 1 retry) then halts.
- Verdict failures (requirements genuinely unmet) — steps **return** `status: "loopback"` with `ReviewFeedback`; the runner jumps back to `loopbackTo` (default `implement`), bounded by `maxLoopbacks`, then halts.
- `Halt` with `haltKind: "incomplete"` (default) triggers the `onHalt` callback (incomplete-implementation comment + revert to To Do); `haltKind: "stop"` stops quietly (e.g. unfixable pre-push hook).
- `UsageLimitError` is always re-thrown so a batch aborts (never retried).

**User extensibility (two tiers), via `settings.pipeline`:**

1. Declarative: `pipeline.steps: [{ "use": "verify", "onFail": "loopback", "minSeverity": "high", "maxIterations": 3 }, ...]` — any number of `verify` instances with different `prompt`/`onFail`/`minSeverity`.
2. Code plugins: `pipeline.plugins: ["./.devintern-code/steps/my-step.ts", "@org/pkg"]` — each module default-exports a `StepDefinition`; loaded via dynamic `import()` before step resolution, registered in the same registry as built-ins (name collisions error out). Typed API surface: `@getdevintern/code/pipeline` (exports live at `src/lib/pipeline/index.ts`; `src/**` ships in the npm tarball for this reason).

`runAgentHarness` in `src/index.ts` remains as a thin back-compat shim: it builds the `TaskContext`, loads plugins, resolves the pipeline (default when unconfigured), and runs it — preserving the old contract (resolves for normal/incomplete/max-turns so batches continue; rejects on timeout, non-zero exit, and `UsageLimitError`).

### Configuration

**Environment Variables (.devintern-code/.env):**
Expand Down
24 changes: 24 additions & 0 deletions packages/code/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,30 @@ Full docs: **[devintern.com/docs/code](https://devintern.com/docs/code/quick-sta

Source monorepo: [getdevintern/devintern](https://github.com/getdevintern/devintern)

## Extensible pipeline

The task workflow is an ordered pipeline of pluggable steps (default: `implement` → `commit` → `auto-review` → `finalize`). Customize it in `.devintern-code/settings.json`:

```json
{
"pipeline": {
"plugins": ["./.devintern-code/steps/my-step.ts"],
"steps": [
{ "use": "implement" },
{ "use": "commit" },
{ "use": "verify", "onFail": "loopback", "minSeverity": "high" },
{ "use": "my-step" },
{ "use": "finalize" }
]
}
}
```

- **Declarative (no code):** add the built-in `verify` step — an agent-backed requirements checker that feeds findings back to the implementer (`onFail: "loopback"`), halts, or warns. Multiple instances with different prompts are supported.
- **Code plugins:** a plugin module default-exports a `StepDefinition` (typed API from `@getdevintern/code/pipeline`) and is loaded at startup from a file path or npm package name — no rebuild required.

See the [Configuration guide](https://devintern.com/docs/code/configuration) for details.

## License

[FSL-1.1-Apache-2.0](./LICENSE.md). Interactive use free forever; unattended automation requires a license — see [pricing](https://devintern.com/pricing/).
5 changes: 5 additions & 0 deletions packages/code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"description": "Turn tracker tickets into pull requests with any coding agent. Self-hosted, BYOK. Free interactive use.",
"type": "module",
"main": "dist/index.js",
"exports": {
".": "./dist/index.js",
"./pipeline": "./src/lib/pipeline/index.ts"
},
"scripts": {
"start": "bun run src/index.ts",
"dev": "bun run src/index.ts",
Expand Down Expand Up @@ -87,6 +91,7 @@
},
"files": [
"dist/**/*",
"src/**/*",
"README.md",
"LICENSE.md",
".env.example"
Expand Down
Loading