Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
58 changes: 58 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Bug Report
description: Something isn't working as expected
labels: ["bug"]
body:
- type: markdown
attributes:
value: Thanks for reporting! Please fill out the sections below.

- type: input
id: command
attributes:
label: Command
description: Which aspens command were you running?
placeholder: "aspens doc init ."
validations:
required: true

- type: textarea
id: what-happened
attributes:
label: What happened?
description: Describe the bug. Include the full error message if there is one.
validations:
required: true

- type: textarea
id: expected
attributes:
label: What did you expect?
validations:
required: true

- type: textarea
id: reproduce
attributes:
label: Steps to reproduce
value: |
1.
2.
3.

- type: input
id: node-version
attributes:
label: Node.js version
placeholder: "v20.11.0"

- type: input
id: os
attributes:
label: OS
placeholder: "macOS 15.3 / Ubuntu 24.04 / Windows 11"

- type: textarea
id: context
attributes:
label: Additional context
description: Repo size, frameworks detected, anything else relevant.
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Question or Discussion
url: https://github.com/aspenkit/aspens/discussions
about: Ask questions or start a discussion
35 changes: 35 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Feature Request
description: Suggest a new feature or improvement
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: Have an idea? We'd love to hear it.

- type: textarea
id: problem
attributes:
label: Problem
description: What problem does this solve? What's frustrating or missing today?
validations:
required: true

- type: textarea
id: solution
attributes:
label: Proposed solution
description: How do you think it should work?
validations:
required: true

- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: Any other approaches you thought about?

- type: textarea
id: context
attributes:
label: Additional context
description: Screenshots, examples, links, anything helpful.
21 changes: 21 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## What

<!-- What does this PR do? One or two sentences. -->

## Why

<!-- Why is this change needed? Link to an issue if applicable. -->

Closes #

## How I tested

- [ ] `npm test` passes
- [ ] Tested against a real repo: <!-- which one? -->
- [ ] `--dry-run` output looks correct (if applicable)

## Checklist

- [ ] Changes are focused on a single feature or fix
- [ ] Tests added or updated for any logic changes
- [ ] No new dependencies added (or justified in the PR description)
132 changes: 104 additions & 28 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,136 @@
# Contributing to aspens

## Dev Setup
## Prerequisites

- [Node.js 18+](https://nodejs.org)
- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) (needed for `doc init`, `doc sync`, and `customize` commands)
- Git

## Setup

```bash
git clone https://github.com/aspenkit/aspens.git
# 1. Fork the repo on GitHub, then:
git clone https://github.com/<your-username>/aspens.git
cd aspens
npm install

# 2. Verify it works
node bin/cli.js --help
npm test
```

No build step. The CLI runs directly from source (ES modules).

## Testing Your Changes Locally

### Run the test suite

```bash
npm test # Run all tests
npx vitest run tests/scanner.test.js # Run a single test file
npx vitest --watch # Watch mode during development
```

### Test against a real repo

The best way to verify your changes is to run aspens against an actual codebase.

**Option 1: `npm link` (recommended)**

Link your local aspens globally so you can use it like the published package:

```bash
# In the aspens directory:
npm link

# Now test from any repo:
cd /path/to/some-project
aspens scan .
aspens doc init --dry-run .
```

When you're done, unlink:

```bash
npm unlink -g aspens
```

**Option 2: Run directly**

```bash
node /path/to/aspens/bin/cli.js scan /path/to/some-project
```

**Option 3: Use `--dry-run`**

Most write commands support `--dry-run` to preview output without touching files:

```bash
node bin/cli.js doc init --dry-run /path/to/some-project
node bin/cli.js doc sync --dry-run /path/to/some-project
```

## Code Review with CodeRabbit

We use [CodeRabbit](https://coderabbit.ai) for automated code review on every PR. Here's what to expect:

- **Automatic review** — CodeRabbit reviews your PR when you open it and on each push. No action needed from you.
- **Summary comment** — It posts a walkthrough summarizing your changes, sequence diagrams, and a file-by-file breakdown.
- **Inline suggestions** — It may leave inline comments with improvement suggestions. You can reply to these directly.
- **Chat commands** — You can interact with CodeRabbit in PR comments:
- `@coderabbitai resolve` — Mark a suggestion as resolved
- `@coderabbitai summary` — Regenerate the summary
- `@coderabbitai review` — Request a re-review after changes

Don't worry about "passing" CodeRabbit — the review profile is set to **chill**. It's there to catch things, not block you. A maintainer will do the final review.

## Submitting a Pull Request

1. Fork the repo and create a branch (`git checkout -b my-change`)
2. Make your changes
3. Run the tests (`npm test`)
4. Test against at least one real repo (see above)
5. Open a PR with a clear description of what changed and why

### What makes a good PR

- **Small and focused** — one feature or fix per PR
- **Tests included** — add or update tests in `tests/` for any logic changes
- **Tested against a real repo** — mention which repo you tested with in the PR description

## Project Structure

```
bin/cli.js # Entry point — commander setup, welcome screen
bin/cli.js # Entry point — Commander setup, welcome screen
src/
commands/
scan.js # Tech stack detection output
doc-init.js # Skill generation pipeline (3 modes)
doc-sync.js # Diff-based skill updates + git hook
add.js # Placeholder (Phase 4)
add.js # Add individual components
customize.js # Inject project context into agents
lib/
scanner.js # Deterministic repo scanner (no LLM)
runner.js # Claude CLI wrapper, prompt loading, output parsing
graph-builder.js # Import graph construction
context-builder.js # Assembles repo context for prompts
runner.js # Claude CLI wrapper, stream parsing
skill-writer.js # Writes skill files to disk
prompts/
doc-init.md # All-at-once generation prompt
doc-init-domain.md # Single domain prompt (chunked mode)
doc-init-claudemd.md # CLAUDE.md generation prompt
doc-sync.md # Sync prompt (diff -> updates)
partials/ # Shared format specs and examples
```

## Testing

There is no test runner yet. Test manually against real repos:

```bash
node bin/cli.js scan /path/to/repo
node bin/cli.js doc init --dry-run /path/to/repo
prompts/ # Markdown prompt templates
partials/ # Shared format specs
templates/ # Bundled components (agents, hooks, commands)
tests/ # Vitest test files
```
Comment thread
mvoutov marked this conversation as resolved.
Resolved

## Submitting Changes

1. Fork the repo
2. Create a branch (`git checkout -b my-change`)
3. Make your changes
4. Test against at least one real repo
5. Open a PR with a clear description of what changed and why

## Code Style

- **ES modules** — `import`/`export`, no `require()`
- **Path handling** — `path.resolve()` for absolute, `path.relative()` for display
- **UI** — `@clack/prompts` for interactive prompts, `picocolors` for color
- **Error handling** — throw descriptive errors with remediation hints, `process.exit(1)` on unrecoverable failures
- **File reads** — try/catch returning `null` on failure, never throw on missing files

## Where to Start

Look for issues labeled [`good first issue`](https://github.com/aspenkit/aspens/labels/good%20first%20issue) — these are scoped, well-described tasks ideal for first-time contributors.

If you have an idea but aren't sure where to start, open an issue first to discuss it.
11 changes: 8 additions & 3 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { program } from 'commander';
import pc from 'picocolors';
import { readdirSync } from 'fs';
import { readFileSync, readdirSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import { scanCommand } from '../src/commands/scan.js';
Expand All @@ -13,14 +13,16 @@ import { customizeCommand } from '../src/commands/customize.js';

const __dirname = dirname(fileURLToPath(import.meta.url));
const TEMPLATES_DIR = join(__dirname, '..', 'src', 'templates');
const PKG = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
const VERSION = PKG.version;

function countTemplates(subdir) {
try { return readdirSync(join(TEMPLATES_DIR, subdir)).filter(f => !f.startsWith('.')).length; } catch { return '?'; }
}

function showWelcome() {
console.log(`
${pc.cyan(pc.bold('aspens'))} ${pc.dim('v0.1.0')} — AI-ready documentation for your codebase
${pc.cyan(pc.bold('aspens'))} ${pc.dim(`v${VERSION}`)} — AI-ready documentation for your codebase

${pc.bold('Quick Start')}
${pc.green('aspens scan')} See your repo's tech stack and domains
Expand Down Expand Up @@ -63,7 +65,7 @@ function showWelcome() {
program
.name('aspens')
.description('Generate and maintain AI-ready documentation for your codebase')
.version('0.1.0')
.version(VERSION)
.action(() => {
// No command given — show welcome
showWelcome();
Expand All @@ -75,6 +77,8 @@ program
.description('Scan a repo and print its tech stack and structure')
.argument('[path]', 'Path to repo', '.')
.option('--json', 'Output as JSON')
.option('--domains <domains>', 'Additional domains to include (comma-separated)')
.option('--verbose', 'Show diagnostic output')
.action(scanCommand);

// Doc commands
Expand All @@ -91,6 +95,7 @@ doc
.option('--timeout <seconds>', 'Claude timeout in seconds', '300')
.option('--mode <mode>', 'Generation mode: all, chunked, base-only (skips interactive prompt)')
.option('--strategy <strategy>', 'Existing docs: improve, rewrite, skip (skips interactive prompt)')
.option('--domains <domains>', 'Additional domains to include (comma-separated, e.g., "backtest,advisory")')
.option('--model <model>', 'Claude model to use (e.g., sonnet, opus, haiku)')
.option('--verbose', 'Show what Claude is reading/doing in real time')
.action(docInitCommand);
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

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

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "aspens",
"version": "0.1.0",
"description": "CLI for managing shared AI coding config across repos",
"version": "0.2.0",
"description": "Generate and maintain AI-ready documentation for any codebase",
"type": "module",
"bin": {
"aspens": "./bin/cli.js"
Expand Down Expand Up @@ -30,6 +30,7 @@
"dependencies": {
"@clack/prompts": "^0.8.0",
"commander": "^12.0.0",
"es-module-lexer": "^2.0.0",
"picocolors": "^1.1.0"
},
"devDependencies": {
Expand Down
Loading
Loading