Skip to content
Merged
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
36 changes: 36 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Bug report
description: Report a reproducible devloop bug
title: "fix: "
labels: ["bug"]
body:
- type: textarea
id: summary
attributes:
label: Summary
description: What failed, and what did you expect instead?
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: Reproduction
description: Include the exact devloop command, spec shape, and relevant output.
placeholder: |
devloop --plain .specs/change.md
validations:
required: true
- type: input
id: version
attributes:
label: devloop version
placeholder: "@satyaborg/devloop 0.1.0"
- type: textarea
id: environment
attributes:
label: Environment
description: Bun version, OS, shell, and configured coder/reviewer agents.
- type: textarea
id: logs
attributes:
label: Logs
description: Paste only logs that are safe to share. `.codex/` artifacts can contain prompts and local paths.
29 changes: 29 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Feature request
description: Propose a focused devloop improvement
title: "feat: "
labels: ["enhancement"]
body:
- type: textarea
id: problem
attributes:
label: Problem
description: What workflow is hard or missing today?
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposal
description: What should devloop do differently?
validations:
required: true
- type: textarea
id: acceptance
attributes:
label: Acceptance criteria
description: List concrete checks that would prove the feature works.
- type: textarea
id: scope
attributes:
label: Scope notes
description: What should stay out of scope?
13 changes: 13 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## Summary

## Implementation

## Verification

- [ ] `bun run typecheck`
- [ ] `bun test`
- [ ] `bun run package:smoke` when packaging, install docs, or release automation changes

## Notes

- [ ] No `.codex/`, `.specs/`, coverage output, dependency caches, or local worktrees included
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: CI

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
env:
NPM_CONFIG_CACHE: ${{ runner.temp }}/devloop-npm-cache
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- uses: actions/setup-node@v6
with:
node-version: 24
registry-url: https://registry.npmjs.org
package-manager-cache: false
- run: bun install --frozen-lockfile
- run: bun run typecheck
- run: bun test
- run: npm --cache "$NPM_CONFIG_CACHE" pack --dry-run --json
- run: bun run package:smoke
55 changes: 55 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Publish

on:
workflow_run:
workflows: ["Release Please"]
types: [completed]

permissions:
contents: read
id-token: write

jobs:
npm:
if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'main'
runs-on: ubuntu-latest
env:
NPM_CONFIG_CACHE: ${{ runner.temp }}/devloop-npm-cache
steps:
- uses: actions/checkout@v6
with:
ref: main
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- uses: actions/setup-node@v6
with:
node-version: 24
registry-url: https://registry.npmjs.org
package-manager-cache: false
- run: bun install --frozen-lockfile
- id: publishable
env:
GH_TOKEN: ${{ github.token }}
run: |
VERSION="$(node -p "require('./package.json').version")"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
if ! gh release view "v$VERSION" >/dev/null 2>&1; then
echo "publish=false" >> "$GITHUB_OUTPUT"
exit 0
fi
if npm --cache "$NPM_CONFIG_CACHE" view "@satyaborg/devloop@$VERSION" version >/dev/null 2>&1; then
echo "publish=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "publish=true" >> "$GITHUB_OUTPUT"
- if: steps.publishable.outputs.publish == 'true'
run: bun run typecheck
- if: steps.publishable.outputs.publish == 'true'
run: bun test
- if: steps.publishable.outputs.publish == 'true'
run: npm --cache "$NPM_CONFIG_CACHE" pack --dry-run --json
- if: steps.publishable.outputs.publish == 'true'
run: bun run package:smoke
- if: steps.publishable.outputs.publish == 'true'
run: npm publish
21 changes: 21 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Release Please

on:
push:
branches: [main]

permissions:
contents: write
pull-requests: write
issues: write

jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
token: ${{ secrets.RELEASE_PLEASE_TOKEN || github.token }}
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
# release-please-config.json sets release-type: node and CHANGELOG.md.
3 changes: 3 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "0.1.0"
}
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changelog

All notable changes to this project will be documented in this file.

Release Please updates this file from Conventional Commits when release PRs are opened.
9 changes: 9 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Code Of Conduct

Be direct, respectful, and specific.

This project is for building reliable local agent workflows. Contributions should focus on the work, avoid personal attacks, and make technical disagreements easy to evaluate.

Unacceptable behavior includes harassment, threats, doxxing, sustained disruption, or comments that make participation hostile for others.

Report conduct issues through GitHub issues or security advisories when privacy is needed. Maintainers may remove comments, close issues, or block participants to keep the project usable.
53 changes: 53 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Contributing

devloop is a Bun and TypeScript CLI. Keep changes narrow, typed, and covered by tests.

## Local Setup

```sh
bun scripts/install.ts
bun run typecheck
bun test
bun run package:smoke
```

`bun test` is configured with 100% line, function, and statement coverage for non-test TypeScript files.

## Pull Requests

- Use Conventional Commits in commit subjects: `feat:`, `fix:`, or `chore:`. Use `!` for breaking changes.
- Keep one logical change per commit.
- Include test evidence in the PR description.
- Update README examples when user-visible CLI behavior changes.
- Do not commit `.codex/`, `.specs/`, coverage output, dependency caches, or local worktrees.

## Release Automation

Release Please manages version bumps from Conventional Commits, opens release PRs, updates `CHANGELOG.md`, and creates GitHub releases when release PRs merge. The repository uses `release-please-config.json` with the `node` release type for `@satyaborg/devloop`.

The release workflow can use the default GitHub token, but GitHub-token-created pull requests and releases can have workflow trigger limitations. Maintainers who need CI to run on Release Please PRs should create a fine-grained `RELEASE_PLEASE_TOKEN` with repository contents and pull request permissions, then store it as a GitHub Actions secret. The workflow falls back to the default token when that secret is absent.

## npm Publishing

The package is published as `@satyaborg/devloop`; the installed binary remains `devloop`.

Publishing is handled by `.github/workflows/publish.yml`. It runs after the Release Please workflow completes, verifies that a matching GitHub release exists for the package version, skips versions that are already on npm, reruns typecheck/tests/package checks, and then runs `npm publish`.

The publish workflow uses npm trusted publishing through GitHub Actions OIDC. It intentionally does not use a long-lived `NPM_TOKEN` or `NODE_AUTH_TOKEN`.

One-time npm setup before the first automated publish:

1. Ensure the `@satyaborg` npm scope is owned by the maintainer account.
2. `@satyaborg/devloop` must be created or first-published by a maintainer as a public package if npm requires an existing package before trusted publishing can be configured.
3. In npm package settings, add a trusted publisher for GitHub Actions.
4. Configure owner `satyaborg`, repository `devloop`, workflow filename `publish.yml`, and allowed action `npm publish`.
5. Leave the environment blank unless the GitHub workflow is later changed to use a protected environment.

For a manual first publish, verify locally first:

```sh
bun run typecheck
bun test
npm --cache /private/tmp/devloop-npm-cache pack --dry-run --json
bun run package:smoke
```
45 changes: 40 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
[![CI](https://github.com/satyaborg/devloop/actions/workflows/ci.yml/badge.svg)](https://github.com/satyaborg/devloop/actions/workflows/ci.yml)
[![npm version](https://img.shields.io/npm/v/@satyaborg/devloop.svg)](https://www.npmjs.com/package/@satyaborg/devloop)
[![license](https://img.shields.io/npm/l/@satyaborg/devloop.svg)](LICENSE)
[![npm downloads](https://img.shields.io/npm/dm/@satyaborg/devloop.svg)](https://www.npmjs.com/package/@satyaborg/devloop)

```text
__ __
____/ /__ _ __/ /___ ____ ____
Expand All @@ -13,15 +18,36 @@ The coder makes the change. The reviewer reviews it. If the reviewer rejects it,

## Install

From this checkout:
Prerequisites:

- Bun 1.2 or newer
- git
- the local agent CLIs you configure
- Codex and Claude Code for the default coder/reviewer pairing

Install the public npm package globally:

```sh
bun scripts/install.ts
npm install -g @satyaborg/devloop
```

This installs dependencies and links `devloop` into `~/.local/bin`.
Run without a global install:

To use another bin directory:
```sh
bunx @satyaborg/devloop --help
```

The npm package name is `@satyaborg/devloop`, and the binary remains `devloop`.

For source checkout development:

```sh
git clone https://github.com/satyaborg/devloop.git
cd devloop
bun scripts/install.ts
```

This installs dependencies and links `devloop` into `~/.local/bin`. To use another bin directory:

```sh
DEVLOOP_BIN_DIR=/path/to/bin bun scripts/install.ts
Expand Down Expand Up @@ -100,7 +126,7 @@ By default, `devloop`:
- writes an HTML report
- requires the reviewer to pass every acceptance criterion with implementation and test evidence
- asks the reviewer to flag silent decisions, scope drift, and missing tests
- creates an isolated sibling git worktree and runs agents there
- creates isolated sibling git worktrees by default and runs agents there
- creates one conventional commit after each coder pass, before review
- never pushes or opens a PR

Expand Down Expand Up @@ -161,6 +187,14 @@ git -C <source-repo> branch -D 'feat!/<slug>'

If `worktree remove` reports local modifications, inspect the worktree first or rerun the command with `--force` to discard them.

## Security Model

devloop runs local agent CLIs with broad permissions because the configured coder and reviewer need to inspect and change a checkout. By default it creates isolated sibling git worktrees before running those agents, but the agents still execute on your machine with your local credentials and PATH.

devloop writes `.codex/` artifacts for specs, tracks, reviews, reports, logs, and session ids. devloop does not add telemetry, phone home, or send data anywhere itself. Network access depends on the agent CLIs and commands you configure.

CI currently verifies the package on Ubuntu. The maintainer development environment is macOS with Bun; other platforms may work but are not release-gated yet.

## Development

Prereqs: `bun`, `git`, and the agents you configure. The defaults require `codex` and `claude`.
Expand All @@ -169,6 +203,7 @@ Prereqs: `bun`, `git`, and the agents you configure. The defaults require `codex
bun scripts/install.ts
bun run typecheck
bun test
bun run package:smoke
```

`bun test` enforces 100% line, function, and statement coverage for the TypeScript core.
Expand Down
21 changes: 21 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Security

## Security Model

devloop runs local agent CLIs with broad permissions because the configured coder and reviewer need access to inspect and modify a checkout. By default, devloop creates isolated sibling git worktrees before invoking those agents, but the agents still run on your machine with your local credentials, environment variables, PATH, and filesystem permissions.

devloop writes `.codex/` artifacts for specs, tracks, reviews, reports, logs, and session ids. Treat those files as local development artifacts that may contain prompts, review text, command output, and repository paths.

devloop does not add telemetry, phone home, or send data anywhere itself. Network access depends on the agent CLIs and commands you configure.

## Reporting A Vulnerability

Open a private security advisory at:

https://github.com/satyaborg/devloop/security/advisories/new

If that is not available, open a minimal issue that does not include exploit details and ask for a private contact path.

## Supported Versions

Security fixes target the latest released npm package and the `main` branch.
2 changes: 1 addition & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading