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
38 changes: 10 additions & 28 deletions .claude/guides/architecture.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Architecture Guide

**Last Updated**: 2026-05-11

Complete architecture documentation for merlin-commit, including folder structure, data flow, module relationships, and design patterns.

---
Expand Down Expand Up @@ -212,7 +210,7 @@ type CommitAnswers = {
issues?: string; // Issue references
};

// Configuration loaded from ~/.merlinrc.json
// Configuration merged from ~/.merlinrc.json and <repo-root>/.merlinrc.json
type MerlinConfig = {
types?: CommitType[];
maxSubjectLength?: number;
Expand Down Expand Up @@ -291,8 +289,11 @@ External Dependencies:
βœ… commands β†’ types
βœ… lib β†’ utils
βœ… lib β†’ types
βœ… lib β†’ lib (acyclic)
βœ… lib β†’ external packages
βœ… utils β†’ utils (acyclic)
βœ… utils β†’ types
βœ… utils β†’ side-effect-free packages (chalk)

❌ lib β†’ commands (library shouldn't know about orchestration)
❌ utils β†’ commands (utils shouldn't know about orchestration)
Expand Down Expand Up @@ -475,22 +476,13 @@ export function getMessages(repoRoot?: string | null): ThemeMessages {

## Module File Size Guidelines

| Category | Target Size | Current |
| ----------- | ----------- | --------------------------------------------------------------------------------------- |
| Commands | < 150 lines | commit: 176, config: 922, init: 410 |
| Lib modules | < 300 lines | git: 345, editor: 256, setup: 270, prompt: 223, cfg-ld: 213, cl-sync: 191, terminal: 63 |
| Utils | < 200 lines | config: 68, validators: 115, theme: 205, constants: 359 |

---

## Code Statistics
| Category | Target size |
| ----------- | ----------- |
| Commands | < 150 lines |
| Lib modules | < 300 lines |
| Utils | < 200 lines |

| Category | Files | Total Lines |
| ------------- | ----- | ----------- |
| Source code | 24 | ~4,863 |
| Test files | 18 | ~7,152 |
| Config files | 9 | - |
| Documentation | 17 | - |
Current sizes and files over target are tracked in `.claude/maintenance/codebase-map.md`.

---

Expand Down Expand Up @@ -552,13 +544,3 @@ export function getMessages(repoRoot?: string | null): ThemeMessages {
Users can also build custom themes without code changes via `theme: "custom"` and
`customTheme` in `.merlinrc.json` (see `utils/theme.ts`). Adding a template
function to `ThemeMessages` requires an entry in `TEMPLATE_PARAMETER_NAMES`.

---

## Resources

- .claude/rules/commands.md - Command layer rules
- .claude/rules/lib.md - Library module rules
- .claude/rules/utils.md - Utility function rules
- .claude/guides/git-workflow.md - Git workflow
- .claude/guides/development.md - Development setup
99 changes: 37 additions & 62 deletions .claude/guides/development.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Development Guide

**Last Updated**: 2026-02-07

Complete development setup, commands, debugging tips, and common gotchas for merlin-commit.

---
Expand Down Expand Up @@ -58,12 +56,12 @@ merlin --version

```json
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"typescript.tsdk": "node_modules/typescript/lib"
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"typescript.tsdk": "node_modules/typescript/lib"
}
```

Expand Down Expand Up @@ -212,8 +210,8 @@ Add debug logs (remove before committing):

```typescript
// Temporary debugging
console.log('Debug:', { variable, otherVariable });
console.error('Error:', error);
console.log("Debug:", { variable, otherVariable });
console.error("Error:", error);
console.dir(complexObject, { depth: null });
```

Expand Down Expand Up @@ -297,13 +295,14 @@ git commit
**Don't do**:

```javascript
const { commitCommand } = require('./commands/commit'); // ❌
const { commitCommand } = require("./commands/commit"); // ❌
```

**Do**:

```typescript
import { commitCommand } from './commands/commit.js'; // βœ…
import { commitCommand } from "./commands/commit.js"; // βœ…

// Note: .js extension required for ESM
```

Expand All @@ -314,13 +313,14 @@ import { commitCommand } from './commands/commit.js'; // βœ…
**Don't do**:

```typescript
import { commit } from './lib/git'; // ❌
import { commit } from "./lib/git"; // ❌
```

**Do**:

```typescript
import { commit } from './lib/git.js'; // βœ…
import { commit } from "./lib/git.js"; // βœ…

// TypeScript compiler resolves .ts file
```

Expand All @@ -331,13 +331,13 @@ import { commit } from './lib/git.js'; // βœ…
**Don't do**:

```typescript
import execa from 'execa'; // ❌
import execa from "execa"; // ❌
```

**Do**:

```typescript
import { execa } from 'execa'; // βœ…
import { execa } from "execa"; // βœ…
```

### 4. Testing Async Functions
Expand All @@ -347,37 +347,34 @@ import { execa } from 'execa'; // βœ…
**Don't do**:

```typescript
it('should commit', () => {
commit('message'); // ❌ Missing await
expect(something).toBe(true);
it("should commit", () => {
commit("message"); // ❌ Missing await
expect(something).toBe(true);
});
```

**Do**:

```typescript
it('should commit', async () => {
await commit('message'); // βœ…
expect(something).toBe(true);
it("should commit", async () => {
await commit("message"); // βœ…
expect(something).toBe(true);
});
```

### 5. Mock Placement

**Issue**: Mocks must be before imports

**Don't do**:
**Issue**: A `vi.mock` factory throws because a variable it uses is undefined

```typescript
import { commit } from '../src/lib/git.js';
vi.mock('../src/lib/git.js'); // ❌ Too late!
```
**Reason**: Vitest hoists every `vi.mock` call above the imports, so its position in the file does
not matter, but the factory runs before ordinary top-level variables are initialized.

**Do**:
**Do**: Create anything the factory needs with `vi.hoisted`:

```typescript
vi.mock('../src/lib/git.js'); // βœ… Before imports
import { commit } from '../src/lib/git.js';
const { mockCommit } = vi.hoisted(() => ({ mockCommit: vi.fn() }));

vi.mock("../src/lib/git.js", () => ({ commit: mockCommit }));
```

### 6. Chalk and Colors
Expand All @@ -390,10 +387,10 @@ import { commit } from '../src/lib/git.js';

```typescript
// ❌ Don't test ANSI codes
expect(output).toContain('\x1b[32m');
expect(output).toContain("\x1b[32m");

// βœ… Test actual content
expect(output).toContain('Success');
expect(output).toContain("Success");
```

### 7. Path Separators
Expand All @@ -403,14 +400,15 @@ expect(output).toContain('Success');
**Don't do**:

```typescript
const configPath = `${homeDir}/.merlinrc.json`; // ❌ Breaks on Windows
const configPath = `${homeDir}/.merlinrc.json`; // ❌ Breaks on Windows
```

**Do**:

```typescript
import path from 'path';
const configPath = path.join(homeDir, '.merlinrc.json'); // βœ…
import path from "path";

const configPath = path.join(homeDir, ".merlinrc.json"); // βœ…
```

---
Expand Down Expand Up @@ -517,7 +515,7 @@ npx vitest run tests/unit/validators.test.ts
npm run test # Runs tests in parallel

# Skip slow tests during development
it.skip('slow test', () => { });
it.skip("slow test", () => {});
```

---
Expand All @@ -540,27 +538,4 @@ SKIP_HOOKS=1 merlin

## Release Checklist

Before releasing new version:

- [ ] All tests pass
- [ ] No console.logs in code
- [ ] README.md updated
- [ ] CHANGELOG.md updated
- [ ] Version bumped in package.json
- [ ] npm audit passes
- [ ] Build succeeds
- [ ] CLI works locally (`npm link`)
- [ ] Documentation updated
- [ ] Examples tested

---

## Resources

- [Node.js Documentation](https://nodejs.org/docs/)
- [TypeScript Handbook](https://www.typescriptlang.org/docs/)
- [Vitest Documentation](https://vitest.dev/)
- [Commander.js Documentation](https://github.com/tj/commander.js)
- [Inquirer Documentation](https://github.com/SBoudrias/Inquirer.js)
- .claude/guides/architecture.md - Architecture overview
- .claude/guides/git-workflow.md - Git workflow
See `docs/development/releases.md`.
14 changes: 1 addition & 13 deletions .claude/guides/git-workflow.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Git Workflow Guide

**Last Updated**: 2026-02-07

Complete guide to the git workflow, branching strategy, commit conventions, and release process for merlin-commit.

---
Expand Down Expand Up @@ -171,7 +169,7 @@ Merlin-commit follows [Conventional Commits](https://www.conventionalcommits.org
| **perf** | Performance improvement | `perf(git): cache git repo check result` |
| **test** | Adding/fixing tests | `test(validators): add edge case tests` |
| **build** | Build system changes | `build: update rollup configuration` |
| **ci** | CI configuration | `ci: add Node.js 20 to test matrix` |
| **ci** | CI configuration | `ci: run knip in the ci job` |
| **chore** | Maintenance | `chore(deps): upgrade inquirer to v10` |
| **revert** | Revert previous commit | `revert: revert "feat: add custom types"` |

Expand Down Expand Up @@ -623,13 +621,3 @@ merlin --amend
# Force push if already pushed
git push --force-with-lease origin feat/your-feature
```

---

## Resources

- [Conventional Commits](https://www.conventionalcommits.org/)
- [GitHub Flow](https://guides.github.com/introduction/flow/)
- [Pro Git Book](https://git-scm.com/book/en/v2)
- .claude/guides/architecture.md - Architecture overview
- .claude/guides/development.md - Development setup
2 changes: 1 addition & 1 deletion .claude/maintenance/codebase-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ This file tracks all source files, their responsibilities, sizes, and maintenanc

**Total**: 18 files, ~7,152 lines combined

**Coverage Target**: >80% overall, 100% for utils
**Coverage Target**: `vitest.config.ts` thresholds (80% lines/statements/functions, 75% branches)

---

Expand Down
Loading
Loading