.agents/skills/incremental-commits/SKILL.md
Break multi-file changes into atomic commits ordered by dependency. Use for refactors, breaking API changes, or features touching 3+ files.
npx skillsauth add aspiers/ai-config incremental-commitsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
When a feature touches multiple files, implement in waves. Each wave is one logical concern, one commit. This creates a clean git history that tells a story.
Wave 1: Foundation (types, interfaces)
↓
Wave 2: Factories/Builders (functions that create instances)
↓
Wave 3: Contracts/APIs (public interfaces that use types)
↓
Wave 4: Infrastructure (utilities, converters, dependencies)
↓
Wave 5: Consumers (apps, UI, integrations)
Not every change needs all waves. A simple bugfix might be one wave. A cross-cutting refactor might need five.
Each wave must be:
| Property | Description | | ------------- | ---------------------------------------------- | | Atomic | One logical concern per wave | | Buildable | Code compiles after this wave (run type-check) | | Focused | Changes relate to ONE layer/concern | | Complete | No half-done work within a wave |
This feature moved metadata from workspace to tables. Five waves:
feat(schema): add IconDefinition, CoverDefinition, and FieldMetadata types
- Add IconDefinition discriminated union (emoji | external)
- Add CoverDefinition discriminated union (external)
- Add FieldMetadata with optional name/description to all field types
- Update TableDefinition to use icon/cover instead of emoji/order
Files: types.ts only. Foundation for everything else.
feat(schema): add optional name/description to field factory functions
All factory functions (id, text, richtext, integer, real, boolean, date,
select, tags, json) now accept optional name and description parameters.
Files: factories.ts only. Uses types from Wave 1.
feat(schema): remove emoji and description from WorkspaceSchema
Workspace is now just a container with guid, id, name, tables, and kv.
Visual metadata (icon, cover, description) now lives on TableDefinition.
Files: contract.ts only. API change using new types.
feat(schema): use slugify for human-readable SQL column names
- Add @sindresorhus/slugify dependency
- Add toSqlIdentifier() helper using slugify with '_' separator
- SQLite columns now use field.name (or derived from key) instead of key
Files: to-drizzle.ts, package.json. Utility that uses field metadata.
feat(schema): update epicenter app to use TablesWithMetadata
- WorkspaceSchema now accepts TablesSchema | TablesWithMetadata
- Export new types from package index
- Update app to create proper TableDefinition with metadata
Files: App files that consume the new types.
Plan waves before coding
Implement one wave
Verify the wave
bun run tsc --noEmitCommit the wave
Repeat for next wave
| Scenario | Waves? | Why | | ------------------------ | ------ | -------------------------- | | Single file bugfix | No | One change, one commit | | Add new type + factory | Maybe | Could be 1-2 waves | | Refactor across 5+ files | Yes | Need logical grouping | | Breaking API change | Yes | Types → API → Consumers | | Add dependency + use it | Yes | Infra wave then usage wave |
refactor: update schema system
- Add new types
- Update factories
- Change contracts
- Add slugify
- Update app
Problem: One monolithic commit. Can't bisect, can't revert partially, no story.
feat: add IconDefinition type
feat: add CoverDefinition type
feat: add FieldMetadata type
feat: update IdFieldSchema
feat: update TextFieldSchema
...
Problem: Too granular. 20 commits for one logical change. Noise.
Wave 1: Update app to use new types ❌
Wave 2: Add the types ❌
Problem: Wave 1 won't compile. Bottom-up, not top-down.
When deciding wave order, ask: "What does this file import?"
types.ts → imports nothing (foundation)
factories.ts → imports types.ts
contract.ts → imports types.ts
converters.ts → imports types.ts, may add deps
app/ → imports everything above
Files that import nothing come first. Files that import everything come last.
For multi-wave work:
# Create feature branch
git checkout -b feat/my-feature
# Wave 1
# ... make changes ...
git add <files> && git commit -m "feat(scope): wave 1 description"
# Wave 2
# ... make changes ...
git add <files> && git commit -m "feat(scope): wave 2 description"
# ... continue waves ...
# When done, all waves are individual commits on the branch
# PR shows clean history of how the feature evolved
Before starting:
For each wave:
After all waves:
development
Run tests according to repository guidelines. Use after linting passes, before staging changes.
development
Orchestrate the complete development workflow for implementing sub-tasks from a task list. Use for end-to-end feature implementation with quality controls.
development
Implement a single sub-task from a task list. Use when working on feature development with existing task lists.
data-ai
Generate a detailed task list from a PRP. Use after a PRP is created and ready for implementation planning.