Spec Kitを使って簡単な家計簿アプリ実装してみた
はじめに
2025年9月2日に GitHub によるオープンソースプロジェクト「SpecKit」が公開されました。
従来の「コード先行、仕様後付け」では、AIが意図を推測し、誤った実装を生成してしまうこともありましたが、SpecKit はこの問題に対応し、仕様(spec)を「実行可能・信頼できる唯一の情報源」として開発を進める新たなワークフローを提供しています。
「SpecKit」とは?
従来の「コードが中心、仕様は後回し」という開発スタイルを覆し、仕様(spec)を開発プロセスの中心とする Spec-Driven Development(仕様駆動開発)を実現するためのツールキットです 。
-
/specify
:まず何を、なぜ作るのか(ユーザーストーリーや目的)を記述し、それをもとに詳細仕様を生成。 -
/plan
:利用する技術スタックやアーキテクチャの方向性を提示し、実装計画を立案。 -
/tasks
:仕様と計画から、実装可能な小さなタスクに分解。
その後、選んだ AI エージェント(Copilot, Claude Code, Gemini CLI など)により、各タスクの実装が進められる、という多段型のプロセスを提供します 。
ツール構成
CLI とテンプレート群、さらには「プロンプト(/specify
, /plan
, /tasks
)」といったガイドラインが同梱され、GitHub Copilot や Claude Code、Gemini CLI などさまざまな AI コーディングエージェントと連携可能な点も特徴です 。
効果
仕様を「生きた実行可能なアーティファクト」として扱うことで、意図とズレの少ない高品質なコード生成が期待されます。プロセスの各段階に検証を設けることで、AI による「行き過ぎ」や「意図の抜け」を抑制し、より堅牢な開発フローを実現します 。
使ってみた
導入手順(for macOS)
1. インストールとプロジェクトの初期化
ターミナルから任意のディレクトリで下記コマンドを実行します。
※<PROJECT_NAME>には開始したいプロジェクトの名前を任意で指定して下さい。
uvx --from git+https://github.com/github/spec-kit.git specify init <PROJECT_NAME>
自身が使用しているコーディングエージェントを選択し、Enterを押します。
作成したsampleプロジェクトの中にはこれらのファイルができます。
.
├── memory //AI の行動規範を定義
│ ├── constitution.md
│ └── constitution_update_checklist.md
├── scripts //プロジェクト運営の自動化スクリプト群
│ ├── check-task-prerequisites.sh
│ ├── common.sh
│ ├── create-new-feature.sh
│ ├── get-feature-paths.sh
│ ├── setup-plan.sh
│ └── update-agent-context.sh
└── templates //仕様・計画・タスクを文書化するための雛形
├── agent-file-template.md
├── plan-template.md
├── spec-template.md
└── tasks-template.md
2. コーディングエージェントの起動
私はClaude Codeを選択・利用したので作成したプロジェクトの中でClaude Codeを起動します。
cd <PROJECT_NAME>
claude
3. 仕様を定義
/specify
コマンドを使用して、何を、なぜ構築したいのかに焦点を当てて構築したいものの説明を書きます。
/specify 収入と支出を入力して、グラフで可視化することができる家計簿アプリを作成したい。
作成されたspec.md
spec.md
Feature Specification: Household Budget Tracker with Visualization
Feature Branch: 001-
Created: 2025-09-08
Status: Draft
Input: User description: "収入と支出を入力して、グラフで可視化することができる家計簿アプリを作成したい。"
Execution Flow (main)
1. Parse user description from Input
→ If empty: ERROR "No feature description provided"
2. Extract key concepts from description
→ Identify: actors, actions, data, constraints
3. For each unclear aspect:
→ Mark with [NEEDS CLARIFICATION: specific question]
4. Fill User Scenarios & Testing section
→ If no clear user flow: ERROR "Cannot determine user scenarios"
5. Generate Functional Requirements
→ Each requirement must be testable
→ Mark ambiguous requirements
6. Identify Key Entities (if data involved)
7. Run Review Checklist
→ If any [NEEDS CLARIFICATION]: WARN "Spec has uncertainties"
→ If implementation details found: ERROR "Remove tech details"
8. Return: SUCCESS (spec ready for planning)
⚡ Quick Guidelines
- ✅ Focus on WHAT users need and WHY
- ❌ Avoid HOW to implement (no tech stack, APIs, code structure)
- 👥 Written for business stakeholders, not developers
Section Requirements
- Mandatory sections: Must be completed for every feature
- Optional sections: Include only when relevant to the feature
- When a section doesn't apply, remove it entirely (don't leave as "N/A")
For AI Generation
When creating this spec from a user prompt:
- Mark all ambiguities: Use [NEEDS CLARIFICATION: specific question] for any assumption you'd need to make
- Don't guess: If the prompt doesn't specify something (e.g., "login system" without auth method), mark it
- Think like a tester: Every vague requirement should fail the "testable and unambiguous" checklist item
-
Common underspecified areas:
- User types and permissions
- Data retention/deletion policies
- Performance targets and scale
- Error handling behaviors
- Integration requirements
- Security/compliance needs
User Scenarios & Testing (mandatory)
Primary User Story
As a household manager, I want to track my income and expenses and visualize them through graphs so that I can better understand my financial situation and make informed budgeting decisions.
Acceptance Scenarios
- Given a user has no transaction data, When they access the application, Then they should see an empty state with options to add their first income or expense entry
- Given a user has entered income entries, When they view the income section, Then they should see all income entries listed with [NEEDS CLARIFICATION: sort order - by date, amount, or category?]
- Given a user has entered expense entries, When they view the expense section, Then they should see all expense entries with details
- Given a user has both income and expense data, When they access the visualization feature, Then they should see graphs showing [NEEDS CLARIFICATION: what type of graphs - pie charts, bar charts, line graphs over time?]
- Given a user wants to add a new transaction, When they select add income/expense, Then they should be able to enter amount, [NEEDS CLARIFICATION: what other fields - date, category, description, recurring flag?]
Edge Cases
- What happens when user enters negative amounts for income or expenses?
- How does system handle [NEEDS CLARIFICATION: currency type - single currency or multi-currency support?]
- What happens when user tries to enter invalid date formats?
- How does system handle very large transaction amounts?
- What happens when there's insufficient data for meaningful visualization?
Requirements (mandatory)
Functional Requirements
- FR-001: System MUST allow users to add income entries with at minimum an amount value
- FR-002: System MUST allow users to add expense entries with at minimum an amount value
- FR-003: System MUST persist all entered income and expense data for [NEEDS CLARIFICATION: retention period - indefinitely, specific time period?]
- FR-004: System MUST display a list of all income entries
- FR-005: System MUST display a list of all expense entries
- FR-006: System MUST calculate and display the balance (total income minus total expenses)
- FR-007: System MUST provide graphical visualization of financial data
- FR-008: System MUST validate that amounts are [NEEDS CLARIFICATION: positive numbers only, or allow negative for corrections?]
- FR-009: Users MUST be able to [NEEDS CLARIFICATION: edit/delete existing entries, or are entries immutable once created?]
- FR-010: System MUST support [NEEDS CLARIFICATION: date range filtering for viewing specific periods?]
- FR-011: System MUST handle [NEEDS CLARIFICATION: categorization of income/expenses - predefined categories, custom categories, or no categories?]
- FR-012: System MUST [NEEDS CLARIFICATION: support multiple users/accounts or single user only?]
- FR-013: Data MUST be [NEEDS CLARIFICATION: stored locally only, cloud sync, or export/import capability?]
Key Entities (include if feature involves data)
- Income Entry: Represents money coming into the household, includes amount and [NEEDS CLARIFICATION: what other attributes - date, source, category, recurring flag?]
- Expense Entry: Represents money going out of the household, includes amount and [NEEDS CLARIFICATION: what other attributes - date, recipient, category, payment method?]
- Financial Summary: Calculated view showing total income, total expenses, and balance for [NEEDS CLARIFICATION: specific time period or all-time?]
- Visualization Data: Aggregated financial data formatted for graph display, grouped by [NEEDS CLARIFICATION: time period, category, or other dimension?]
Review & Acceptance Checklist
GATE: Automated checks run during main() execution
Content Quality
- No implementation details (languages, frameworks, APIs)
- Focused on user value and business needs
- Written for non-technical stakeholders
- All mandatory sections completed
Requirement Completeness
- No [NEEDS CLARIFICATION] markers remain
- Requirements are testable and unambiguous
- Success criteria are measurable
- Scope is clearly bounded
- Dependencies and assumptions identified
Execution Status
Updated by main() during processing
- User description parsed
- Key concepts extracted
- Ambiguities marked
- User scenarios defined
- Requirements generated
- Entities identified
- Review checklist passed (has clarifications needed)
4. 実装計画を立案
/plan
コマンドを使用して、テクノロジー スタックとアーキテクチャの選択肢を指定します。
/plan フロントエンドはHTML/CSS/JavaScriptで構成し、データ保存にはブラウザのLocalStorageを使用する。
作成されたファイルたち⬇︎
data-model.md
Data Model Specification
Core Entities
1. Transaction
Purpose: Represents a single income or expense entry
{
id: string, // UUID v4
type: string, // 'income' | 'expense'
amount: number, // Positive decimal (2 places max)
date: string, // ISO 8601 date (YYYY-MM-DD)
category: string, // Category name
description: string, // Optional notes (max 500 chars)
deleted: boolean, // Soft delete flag
createdAt: string, // ISO 8601 timestamp
updatedAt: string // ISO 8601 timestamp
}
Validation Rules:
-
id
: Required, must be valid UUID -
type
: Required, must be 'income' or 'expense' -
amount
: Required, positive number, max 2 decimal places, max value 999999999.99 -
date
: Required, valid date, cannot be future date -
category
: Required, non-empty string, max 50 characters -
description
: Optional, max 500 characters -
deleted
: Required, boolean, default false -
createdAt
: Required, valid ISO timestamp -
updatedAt
: Required, valid ISO timestamp
State Transitions:
- Created → Active (default state)
- Active → Deleted (soft delete)
- Deleted → Active (restore)
2. Category
Purpose: Defines available transaction categories
{
name: string, // Unique category name
type: string, // 'income' | 'expense'
isDefault: boolean, // System-provided vs user-created
color: string, // Hex color for charts
icon: string // Optional icon identifier
}
Default Categories:
// Income Categories
[
{ name: "Salary", type: "income", isDefault: true, color: "#4CAF50" },
{ name: "Freelance", type: "income", isDefault: true, color: "#8BC34A" },
{ name: "Investment", type: "income", isDefault: true, color: "#CDDC39" },
{ name: "Gift", type: "income", isDefault: true, color: "#FFC107" },
{ name: "Other Income", type: "income", isDefault: true, color: "#FF9800" }
]
// Expense Categories
[
{ name: "Food", type: "expense", isDefault: true, color: "#F44336" },
{ name: "Transportation", type: "expense", isDefault: true, color: "#E91E63" },
{ name: "Housing", type: "expense", isDefault: true, color: "#9C27B0" },
{ name: "Entertainment", type: "expense", isDefault: true, color: "#673AB7" },
{ name: "Healthcare", type: "expense", isDefault: true, color: "#3F51B5" },
{ name: "Shopping", type: "expense", isDefault: true, color: "#2196F3" },
{ name: "Utilities", type: "expense", isDefault: true, color: "#00BCD4" },
{ name: "Other Expense", type: "expense", isDefault: true, color: "#009688" }
]
3. UserPreferences
Purpose: Stores user settings and preferences
{
currency: string, // Currency symbol (default: "$")
currencyPosition: string, // 'before' | 'after'
dateFormat: string, // 'MM/DD/YYYY' | 'DD/MM/YYYY' | 'YYYY-MM-DD'
startOfWeek: number, // 0 (Sunday) - 6 (Saturday)
theme: string, // 'light' | 'dark' | 'auto'
defaultView: string // 'dashboard' | 'transactions' | 'charts'
}
4. FinancialSummary (Calculated)
Purpose: Aggregated financial data for display
{
period: string, // 'month' | 'year' | 'all-time' | 'custom'
startDate: string, // ISO 8601 date
endDate: string, // ISO 8601 date
totalIncome: number, // Sum of income transactions
totalExpenses: number, // Sum of expense transactions
balance: number, // totalIncome - totalExpenses
transactionCount: number, // Number of transactions
categoryBreakdown: [ // Spending by category
{
category: string,
amount: number,
percentage: number,
count: number
}
],
dailyBalance: [ // For trend charts
{
date: string,
income: number,
expenses: number,
balance: number
}
]
}
LocalStorage Schema
Storage Keys
const STORAGE_KEYS = {
TRANSACTIONS: 'budget_transactions',
CATEGORIES: 'budget_categories',
PREFERENCES: 'budget_preferences',
VERSION: 'budget_db_version'
};
Storage Format
// Transactions storage
localStorage.setItem(STORAGE_KEYS.TRANSACTIONS, JSON.stringify([
/* array of Transaction objects */
]));
// Categories storage
localStorage.setItem(STORAGE_KEYS.CATEGORIES, JSON.stringify([
/* array of Category objects */
]));
// Preferences storage
localStorage.setItem(STORAGE_KEYS.PREFERENCES, JSON.stringify({
/* UserPreferences object */
}));
// Version for migration support
localStorage.setItem(STORAGE_KEYS.VERSION, '1.0.0');
Data Access Patterns
1. Transaction Queries
- Get all transactions (excluding deleted)
- Get transactions by date range
- Get transactions by category
- Get transactions by type (income/expense)
- Get single transaction by ID
2. Aggregation Queries
- Calculate total income for period
- Calculate total expenses for period
- Calculate balance for period
- Group expenses by category
- Calculate daily/monthly/yearly trends
3. Write Operations
- Create new transaction
- Update existing transaction
- Soft delete transaction
- Restore deleted transaction
- Bulk import transactions
Indexing Strategy
Since LocalStorage doesn't support indexing, we'll maintain in-memory indexes:
// In-memory indexes for performance
const indexes = {
byDate: new Map(), // date -> [transactions]
byCategory: new Map(), // category -> [transactions]
byMonth: new Map(), // YYYY-MM -> [transactions]
deleted: new Set() // Set of deleted transaction IDs
};
Migration Strategy
Version Detection
function getCurrentVersion() {
return localStorage.getItem(STORAGE_KEYS.VERSION) || '0.0.0';
}
Migration Path
const migrations = {
'0.0.0': migrate_0_0_0_to_1_0_0,
'1.0.0': migrate_1_0_0_to_1_1_0,
// Future migrations
};
Migration Example
function migrate_0_0_0_to_1_0_0() {
// Initialize with default data structure
const defaultCategories = [...]; // Default categories
const emptyTransactions = [];
const defaultPreferences = {
currency: '$',
currencyPosition: 'before',
dateFormat: 'MM/DD/YYYY',
startOfWeek: 0,
theme: 'light',
defaultView: 'dashboard'
};
localStorage.setItem(STORAGE_KEYS.CATEGORIES, JSON.stringify(defaultCategories));
localStorage.setItem(STORAGE_KEYS.TRANSACTIONS, JSON.stringify(emptyTransactions));
localStorage.setItem(STORAGE_KEYS.PREFERENCES, JSON.stringify(defaultPreferences));
localStorage.setItem(STORAGE_KEYS.VERSION, '1.0.0');
}
Data Constraints
Storage Limits
- LocalStorage: ~5-10MB total
- Per transaction: ~200 bytes
- Estimated capacity: 25,000-50,000 transactions
- Warning at 80% capacity
- Implement data archiving at 90% capacity
Performance Targets
- Load time: <100ms for 1000 transactions
- Query time: <50ms for filtered views
- Save time: <10ms per transaction
- Aggregation: <100ms for yearly summary
Security Considerations
- No PII in transaction IDs
- Sanitize all text inputs before storage
- Escape HTML in descriptions for XSS prevention
- No sensitive financial account information stored
plan.md
Implementation Plan: Household Budget Tracker with Visualization
Branch: 001-
| Date: 2025-09-08 | Spec: spec.md
Input: Feature specification from /specs/001-/spec.md
Execution Flow (/plan command scope)
1. Load feature spec from Input path
→ If not found: ERROR "No feature spec at {path}"
2. Fill Technical Context (scan for NEEDS CLARIFICATION)
→ Detect Project Type from context (web=frontend+backend, mobile=app+api)
→ Set Structure Decision based on project type
3. Evaluate Constitution Check section below
→ If violations exist: Document in Complexity Tracking
→ If no justification possible: ERROR "Simplify approach first"
→ Update Progress Tracking: Initial Constitution Check
4. Execute Phase 0 → research.md
→ If NEEDS CLARIFICATION remain: ERROR "Resolve unknowns"
5. Execute Phase 1 → contracts, data-model.md, quickstart.md, agent-specific template file (e.g., `CLAUDE.md` for Claude Code, `.github/copilot-instructions.md` for GitHub Copilot, or `GEMINI.md` for Gemini CLI).
6. Re-evaluate Constitution Check section
→ If new violations: Refactor design, return to Phase 1
→ Update Progress Tracking: Post-Design Constitution Check
7. Plan Phase 2 → Describe task generation approach (DO NOT create tasks.md)
8. STOP - Ready for /tasks command
IMPORTANT: The /plan command STOPS at step 7. Phases 2-4 are executed by other commands:
- Phase 2: /tasks command creates tasks.md
- Phase 3-4: Implementation execution (manual or via tools)
Summary
A household budget tracking application that allows users to input income and expense transactions and visualize their financial data through interactive graphs. The application will use HTML/CSS/JavaScript for the frontend with LocalStorage for client-side data persistence.
Technical Context
Language/Version: JavaScript (ES6+), HTML5, CSS3
Primary Dependencies: None (Vanilla JavaScript approach)
Storage: Browser LocalStorage API
Testing: Jest for unit tests, Cypress for E2E tests
Target Platform: Modern web browsers (Chrome, Firefox, Safari, Edge)
Project Type: single (client-side only web application)
Performance Goals: <100ms UI response time, instant graph updates
Constraints: Offline-capable, no server dependency, <5MB total size
Scale/Scope: Single user, unlimited transactions (LocalStorage limit ~5-10MB)
Constitution Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
Simplicity:
- Projects: 1 (single client-side web app)
- Using framework directly? Yes (vanilla JS, no wrapper classes)
- Single data model? Yes (Transaction and Summary models only)
- Avoiding patterns? Yes (no unnecessary abstractions)
Architecture:
- EVERY feature as library? Yes (modular JS libraries)
- Libraries listed:
- budget-storage: LocalStorage data persistence
- budget-calculator: Financial calculations and aggregations
- budget-charts: Graph visualization
- budget-ui: UI components and interactions
- CLI per library: N/A (browser-based, but will provide debug console commands)
- Library docs: llms.txt format planned? Yes
Testing (NON-NEGOTIABLE):
- RED-GREEN-Refactor cycle enforced? Yes
- Git commits show tests before implementation? Yes
- Order: Contract→Integration→E2E→Unit strictly followed? Yes
- Real dependencies used? Yes (actual LocalStorage, not mocks)
- Integration tests for: new libraries, contract changes, shared schemas? Yes
- FORBIDDEN: Implementation before test, skipping RED phase - Understood
Observability:
- Structured logging included? Yes (console with levels)
- Frontend logs → backend? N/A (no backend)
- Error context sufficient? Yes (detailed error messages)
Versioning:
- Version number assigned? 1.0.0
- BUILD increments on every change? Yes
- Breaking changes handled? Yes (data migration for LocalStorage schema changes)
Project Structure
Documentation (this feature)
specs/[###-feature]/
├── plan.md # This file (/plan command output)
├── research.md # Phase 0 output (/plan command)
├── data-model.md # Phase 1 output (/plan command)
├── quickstart.md # Phase 1 output (/plan command)
├── contracts/ # Phase 1 output (/plan command)
└── tasks.md # Phase 2 output (/tasks command - NOT created by /plan)
Source Code (repository root)
# Option 1: Single project (DEFAULT)
src/
├── models/
├── services/
├── cli/
└── lib/
tests/
├── contract/
├── integration/
└── unit/
# Option 2: Web application (when "frontend" + "backend" detected)
backend/
├── src/
│ ├── models/
│ ├── services/
│ └── api/
└── tests/
frontend/
├── src/
│ ├── components/
│ ├── pages/
│ └── services/
└── tests/
# Option 3: Mobile + API (when "iOS/Android" detected)
api/
└── [same as backend above]
ios/ or android/
└── [platform-specific structure]
Structure Decision: Option 1 (Single project - client-side only application)
Phase 0: Outline & Research
-
Extract unknowns from Technical Context above:
- For each NEEDS CLARIFICATION → research task
- For each dependency → best practices task
- For each integration → patterns task
-
Generate and dispatch research agents:
For each unknown in Technical Context: Task: "Research {unknown} for {feature context}" For each technology choice: Task: "Find best practices for {tech} in {domain}"
-
Consolidate findings in
research.md
using format:- Decision: [what was chosen]
- Rationale: [why chosen]
- Alternatives considered: [what else evaluated]
Output: research.md with all NEEDS CLARIFICATION resolved
Phase 1: Design & Contracts
Prerequisites: research.md complete
-
Extract entities from feature spec →
data-model.md
:- Entity name, fields, relationships
- Validation rules from requirements
- State transitions if applicable
-
Generate API contracts from functional requirements:
- For each user action → endpoint
- Use standard REST/GraphQL patterns
- Output OpenAPI/GraphQL schema to
/contracts/
-
Generate contract tests from contracts:
- One test file per endpoint
- Assert request/response schemas
- Tests must fail (no implementation yet)
-
Extract test scenarios from user stories:
- Each story → integration test scenario
- Quickstart test = story validation steps
-
Update agent file incrementally (O(1) operation):
- Run
/scripts/update-agent-context.sh [claude|gemini|copilot]
for your AI assistant - If exists: Add only NEW tech from current plan
- Preserve manual additions between markers
- Update recent changes (keep last 3)
- Keep under 150 lines for token efficiency
- Output to repository root
- Run
Output: data-model.md, /contracts/*, failing tests, quickstart.md, agent-specific file
Phase 2: Task Planning Approach
This section describes what the /tasks command will do - DO NOT execute during /plan
Task Generation Strategy:
- Load
/templates/tasks-template.md
as base - Generate tasks from Phase 1 design docs (contracts, data model, quickstart)
- Each API endpoint → contract test task [P]
- Each entity → model creation task [P]
- Each library → module creation task
- Each user story → integration test task
- Implementation tasks to make tests pass
Specific Tasks to Generate:
- Setup tasks (project structure, dependencies)
- Model definition tasks (Transaction, Category, Preferences)
- Storage library tasks (CRUD operations, queries)
- Calculator library tasks (aggregations, summaries)
- Chart library tasks (pie, bar, line charts)
- UI component tasks (forms, lists, modals)
- API implementation tasks (all endpoints)
- Integration test tasks (user flows from quickstart)
- E2E test tasks (critical paths)
- Documentation tasks (README, API docs)
Ordering Strategy:
- TDD order: Tests before implementation
- Dependency order: Models → Storage → Calculator → UI → Integration
- Mark [P] for parallel execution (independent files)
- Group related tasks for context switching efficiency
Estimated Output: 30-35 numbered, ordered tasks in tasks.md
IMPORTANT: This phase is executed by the /tasks command, NOT by /plan
Phase 3+: Future Implementation
These phases are beyond the scope of the /plan command
Phase 3: Task execution (/tasks command creates tasks.md)
Phase 4: Implementation (execute tasks.md following constitutional principles)
Phase 5: Validation (run tests, execute quickstart.md, performance validation)
Complexity Tracking
Fill ONLY if Constitution Check has violations that must be justified
Violation | Why Needed | Simpler Alternative Rejected Because |
---|---|---|
[e.g., 4th project] | [current need] | [why 3 projects insufficient] |
[e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] |
Progress Tracking
This checklist is updated during execution flow
Phase Status:
- Phase 0: Research complete (/plan command)
- Phase 1: Design complete (/plan command)
- Phase 2: Task planning complete (/plan command - describe approach only)
- Phase 3: Tasks generated (/tasks command)
- Phase 4: Implementation complete
- Phase 5: Validation passed
Gate Status:
- Initial Constitution Check: PASS
- Post-Design Constitution Check: PASS
- All NEEDS CLARIFICATION resolved
- Complexity deviations documented (none required)
Based on Constitution v2.1.1 - See /memory/constitution.md
quickstart.md
Budget Tracker Quick Start Guide
Setup
- Open
index.html
in a modern web browser - The application will initialize with default categories and empty transaction list
First-Time User Flow
Step 1: Add Your First Income
- Click the "Add Transaction" button
- Select "Income" as the transaction type
- Enter the amount (e.g., 5000.00)
- Select today's date
- Choose "Salary" from the category dropdown
- Add optional description (e.g., "Monthly salary")
- Click "Save"
- ✓ Verify: Transaction appears in the transaction list
Step 2: Add Your First Expense
- Click "Add Transaction" again
- Select "Expense" as the transaction type
- Enter the amount (e.g., 45.50)
- Select today's date
- Choose "Food" from the category dropdown
- Add optional description (e.g., "Lunch at cafe")
- Click "Save"
- ✓ Verify: Transaction appears in the list with negative amount
Step 3: View Your Balance
- Navigate to the Dashboard view
- ✓ Verify: Total Income shows $5,000.00
- ✓ Verify: Total Expenses shows $45.50
- ✓ Verify: Balance shows $4,954.50
Step 4: View Charts
- Click on the "Charts" tab
- ✓ Verify: Pie chart shows expense breakdown by category
- ✓ Verify: Bar chart shows income vs expenses for current month
- ✓ Verify: Line chart shows balance trend
Step 5: Filter Transactions
- Go back to Transactions view
- Select "This Month" from the date filter
- ✓ Verify: Only current month transactions are displayed
- Select "Income" from the type filter
- ✓ Verify: Only income transactions are displayed
- Click "Clear Filters"
- ✓ Verify: All transactions are displayed again
Step 6: Edit a Transaction
- Click the edit icon next to any transaction
- Change the amount to a different value
- Click "Update"
- ✓ Verify: Transaction is updated in the list
- ✓ Verify: Balance is recalculated
Step 7: Delete a Transaction
- Click the delete icon next to any transaction
- Confirm deletion in the dialog
- ✓ Verify: Transaction is removed from the list
- ✓ Verify: Balance is updated
Step 8: Add Custom Category
- Go to Settings
- Click "Manage Categories"
- Click "Add Custom Category"
- Enter name: "Subscription"
- Select type: "Expense"
- Choose a color
- Click "Save"
- ✓ Verify: New category appears in category list
- Add a new transaction with the custom category
- ✓ Verify: Transaction saves with custom category
Step 9: Export Data
- Go to Settings
- Click "Export Data"
- Select date range (or leave empty for all data)
- Click "Export as CSV"
- ✓ Verify: CSV file downloads with transaction data
- Open in Excel/Google Sheets
- ✓ Verify: Data is properly formatted
Step 10: Change Preferences
- Go to Settings
- Change currency symbol to "€"
- Change date format to "DD/MM/YYYY"
- Toggle theme to "Dark"
- Click "Save Preferences"
- ✓ Verify: Currency symbol updates throughout app
- ✓ Verify: Dates display in new format
- ✓ Verify: Dark theme is applied
Testing Checklist
Data Persistence
- Add 5 transactions
- Refresh the browser
- Verify all transactions persist
- Verify preferences persist
Validation
- Try to add transaction with negative amount - should fail
- Try to add transaction with future date - should fail
- Try to add transaction without required fields - should fail
- Try to add transaction with amount > 999999999.99 - should fail
Performance
- Add 100 transactions via bulk import
- Verify list scrolls smoothly
- Verify charts render within 1 second
- Verify filters apply instantly
Edge Cases
- Add transaction for December 31st
- Add transaction for January 1st
- Verify year transition in charts
- Delete all transactions
- Verify empty states display correctly
Mobile Testing
- Open on mobile device/responsive mode
- Verify all buttons are tappable
- Verify forms are usable
- Verify charts are scrollable
- Verify navigation works
Command Line Testing (Browser Console)
// Test data access
BudgetApp.getTransactions();
BudgetApp.getSummary('month');
BudgetApp.getCategories();
// Test operations
BudgetApp.addTransaction({
type: 'income',
amount: 1000,
date: '2025-01-15',
category: 'Salary',
description: 'Test income'
});
// Verify storage
console.log(localStorage.getItem('budget_transactions'));
console.log(localStorage.getItem('budget_categories'));
console.log(localStorage.getItem('budget_preferences'));
// Test performance
console.time('Load 1000 transactions');
BudgetApp.loadTransactions();
console.timeEnd('Load 1000 transactions'); // Should be < 100ms
Success Criteria
- All verification steps pass
- No console errors during normal usage
- LocalStorage data persists across sessions
- Application works offline
- All user stories from spec are achievable
research.md
Research & Technical Decisions
Feature Context
Building a household budget tracker with income/expense tracking and visualization capabilities using vanilla HTML/CSS/JavaScript with LocalStorage for persistence.
Technical Decisions
1. Data Persistence Strategy
Decision: LocalStorage with JSON serialization
Rationale:
- Simple, synchronous API perfect for small-scale personal data
- No server dependency aligns with offline-first requirement
- 5-10MB limit sufficient for years of transaction data
Alternatives considered: - IndexedDB: Overkill for simple key-value storage needs
- SessionStorage: Data would be lost on tab close
- Cookies: Too small (4KB limit) and unnecessary server transmission
2. Transaction Field Structure
Decision: Comprehensive but simple schema
{
id: string (UUID),
type: 'income' | 'expense',
amount: number,
date: string (ISO 8601),
category: string,
description: string,
createdAt: string (ISO 8601),
updatedAt: string (ISO 8601)
}
Rationale: Balances simplicity with future extensibility
Alternatives considered:
- Minimal (amount only): Too limiting for useful analysis
- Complex (tags, attachments, recurring): Over-engineering for MVP
3. Visualization Library Choice
Decision: Chart.js (lightweight, standalone)
Rationale:
- No dependencies, works with vanilla JS
- Responsive and mobile-friendly out of the box
- Rich chart types (pie, bar, line) for financial data
- Small size (~60KB gzipped)
Alternatives considered: - D3.js: Too complex for simple charts
- Canvas API directly: Too much implementation work
- CSS-only charts: Limited interactivity
4. Category Management
Decision: Predefined categories with custom addition
Rationale:
- Quick start with common categories
- Flexibility for personalization
- Simpler than full taxonomy management
Default categories: - Income: Salary, Freelance, Investment, Gift, Other
- Expense: Food, Transportation, Housing, Entertainment, Healthcare, Shopping, Utilities, Other
5. Date Range Filtering
Decision: Implement standard periods + custom range
Periods: This Month, Last Month, This Year, Last 30 Days, Last 90 Days, Custom
Rationale: Covers 90% of use cases with simple implementation
Alternatives considered:
- No filtering: Poor UX for long-term users
- Complex filtering: Unnecessary complexity
6. Edit/Delete Capabilities
Decision: Full CRUD operations with soft delete
Rationale:
- Users need to correct mistakes
- Soft delete preserves audit trail
- Can be hidden from UI but recovered if needed
Implementation: Adddeleted: boolean
field, filter in queries
7. Currency Handling
Decision: Single currency with formatting options
Rationale:
- Multi-currency adds significant complexity
- Target audience likely uses single currency
- Can store currency symbol as user preference
Future path: Version 2 could add currency conversion
8. Data Validation Rules
Decision: Client-side validation with these rules:
- Amount: Positive numbers only, max 2 decimal places
- Date: Cannot be future date (for past transactions)
- Required fields: amount, type, date, category
- Description: Optional, max 500 characters
Rationale: Prevents data corruption while maintaining flexibility
9. Graph Types and Visualizations
Decision: Three primary visualizations
- Pie Chart: Expense breakdown by category (current month)
- Bar Chart: Income vs Expenses comparison (monthly)
-
Line Chart: Balance trend over time
Rationale: Covers different analytical needs without overwhelming users
10. Performance Optimizations
Decision: Implement these optimizations:
- Lazy load Chart.js only when viewing charts
- Cache calculated summaries in memory
- Debounce LocalStorage writes (batch updates)
- Virtual scrolling for transaction lists >100 items
Rationale: Ensures smooth experience even with years of data
11. Data Export/Import
Decision: CSV export for Excel compatibility
Rationale:
- Most requested format for financial data
- Easy to implement
- Compatible with banking tools
Future: JSON export/import for full backup/restore
12. Mobile Responsiveness
Decision: Mobile-first responsive design
Breakpoints:
- Mobile: <768px
- Tablet: 768px-1024px
- Desktop: >1024px
Rationale: Many users track expenses on the go
Security Considerations
- No sensitive data in URLs
- XSS protection via proper escaping
- Input sanitization before storage
- LocalStorage encryption not needed (device-level security sufficient)
Browser Support
Minimum versions:
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
Rationale: Covers 95%+ of users, allows modern JS features
Resolved Clarifications from Spec
All NEEDS CLARIFICATION items have been resolved with reasonable defaults that can be adjusted based on user feedback post-launch.
5. タスクの分解
/tasks
コマンドを使用して、実行可能なタスクリストを作成し、エージェントに機能を実装するよう依頼します。
/tasks
作成されたtasks.mdの中身⬇︎
tasks.md
Tasks: Household Budget Tracker with Visualization
Input: Design documents from /specs/001-/
Prerequisites: plan.md (required), research.md, data-model.md, contracts/api-spec.json
Execution Flow (main)
1. Load plan.md from feature directory
→ Extract: JavaScript/HTML/CSS, LocalStorage, Chart.js
2. Load design documents:
→ data-model.md: Transaction, Category, UserPreferences entities
→ contracts/api-spec.json: 10 API endpoints
→ research.md: Technical decisions
3. Generate tasks by category:
→ Setup: project structure, dependencies
→ Tests: contract tests, integration tests
→ Core: models, libraries, API
→ Integration: LocalStorage, Chart.js
→ Polish: unit tests, docs
4. Apply TDD rules:
→ Tests before implementation
→ [P] for independent files
5. Number tasks T001-T035
6. Return: SUCCESS (tasks ready)
[ID] [P?] Description
Format: - [P]: Can run in parallel (different files, no dependencies)
- Include exact file paths in descriptions
Path Conventions
-
Single project structure (from plan.md):
-
src/
- Source code -
tests/
- Test files -
assets/
- CSS, images -
index.html
- Main entry point
-
Phase 3.1: Setup
- T001 Create project structure: src/{models,services,lib,cli}, tests/{contract,integration,unit}, assets/{css,js,images}
- T002 Initialize package.json with Jest and Cypress dependencies
- T003 [P] Create index.html with basic structure and viewport meta tags
- T004 [P] Create assets/css/main.css with mobile-first responsive layout
- T005 [P] Configure Jest in jest.config.js for unit and contract tests
- T006 [P] Configure Cypress in cypress.config.js for E2E tests
Phase 3.2: Tests First (TDD) ⚠️ MUST COMPLETE BEFORE 3.3
CRITICAL: These tests MUST be written and MUST FAIL before ANY implementation
Contract Tests
- T007 [P] Contract test GET /api/transactions in tests/contract/test_transactions_get.js
- T008 [P] Contract test POST /api/transactions in tests/contract/test_transactions_post.js
- T009 [P] Contract test PUT /api/transactions/{id} in tests/contract/test_transactions_put.js
- T010 [P] Contract test DELETE /api/transactions/{id} in tests/contract/test_transactions_delete.js
- T011 [P] Contract test GET /api/summary in tests/contract/test_summary_get.js
- T012 [P] Contract test GET /api/categories in tests/contract/test_categories_get.js
- T013 [P] Contract test POST /api/categories in tests/contract/test_categories_post.js
- T014 [P] Contract test GET /api/preferences in tests/contract/test_preferences_get.js
- T015 [P] Contract test PUT /api/preferences in tests/contract/test_preferences_put.js
Integration Tests
- T016 [P] Integration test: Add first income transaction in tests/integration/test_add_income.js
- T017 [P] Integration test: Add first expense transaction in tests/integration/test_add_expense.js
- T018 [P] Integration test: View balance calculation in tests/integration/test_balance.js
- T019 [P] Integration test: Filter transactions by date in tests/integration/test_filter.js
- T020 [P] Integration test: Edit and delete transactions in tests/integration/test_crud.js
- T021 [P] Integration test: Export data as CSV in tests/integration/test_export.js
Phase 3.3: Core Implementation (ONLY after tests are failing)
Data Models
- T022 [P] Transaction model with validation in src/models/transaction.js
- T023 [P] Category model with defaults in src/models/category.js
- T024 [P] UserPreferences model in src/models/preferences.js
Library Modules
- T025 [P] LocalStorage service (CRUD, migration) in src/lib/budget-storage.js
- T026 [P] Calculator service (sums, grouping) in src/lib/budget-calculator.js
- T027 [P] Chart service (pie, bar, line) in src/lib/budget-charts.js
- T028 [P] UI components (forms, modals, lists) in src/lib/budget-ui.js
API Implementation
- T029 Transaction API endpoints (GET, POST, PUT, DELETE) in src/services/transactionService.js
- T030 Summary API endpoint with aggregations in src/services/summaryService.js
- T031 Category API endpoints (GET, POST) in src/services/categoryService.js
- T032 Preferences API endpoints (GET, PUT) in src/services/preferencesService.js
- T033 Export API endpoint for CSV generation in src/services/exportService.js
Main Application
- T034 Wire up all services in assets/js/app.js with BudgetApp global
- T035 Implement UI event handlers and form validation in assets/js/ui-handlers.js
- T036 Add Chart.js integration and lazy loading in assets/js/charts.js
Phase 3.4: Integration
- T037 Connect all services to LocalStorage with proper error handling
- T038 Implement data migration for schema changes
- T039 Add structured logging with console levels
- T040 Implement CSV export with proper formatting
- T041 Add virtual scrolling for transaction lists >100 items
Phase 3.5: Polish
- T042 [P] Unit tests for validation functions in tests/unit/test_validation.js
- T043 [P] Unit tests for calculator functions in tests/unit/test_calculator.js
- T044 [P] Unit tests for storage operations in tests/unit/test_storage.js
- T045 Performance test: 1000 transactions render <100ms
- T046 [P] Create README.md with setup and usage instructions
- T047 [P] Create API documentation in docs/api.md
- T048 Run quickstart.md validation checklist
Dependencies
- Setup (T001-T006) blocks everything
- All tests (T007-T021) before implementation (T022-T036)
- Models (T022-T024) before services (T029-T033)
- Libraries (T025-T028) before main app (T034-T036)
- Core implementation before integration (T037-T041)
- Everything before polish (T042-T048)
Parallel Execution Examples
Launch all contract tests together:
# Run T007-T015 in parallel
Task: "Contract test GET /api/transactions"
Task: "Contract test POST /api/transactions"
Task: "Contract test PUT /api/transactions/{id}"
Task: "Contract test DELETE /api/transactions/{id}"
Task: "Contract test GET /api/summary"
Task: "Contract test GET /api/categories"
Task: "Contract test POST /api/categories"
Task: "Contract test GET /api/preferences"
Task: "Contract test PUT /api/preferences"
Launch all models together:
# Run T022-T024 in parallel
Task: "Transaction model with validation"
Task: "Category model with defaults"
Task: "UserPreferences model"
Launch all libraries together:
# Run T025-T028 in parallel
Task: "LocalStorage service (CRUD, migration)"
Task: "Calculator service (sums, grouping)"
Task: "Chart service (pie, bar, line)"
Task: "UI components (forms, modals, lists)"
Notes
- Tests MUST fail before implementation (TDD requirement)
- Commit after each task completion
- Use actual LocalStorage, not mocks
- Follow mobile-first responsive design
- Ensure all text inputs are HTML-escaped
Validation Checklist
- All 10 API endpoints have contract tests
- All 3 entities have model tasks
- All 6 user stories have integration tests
- Tests come before implementation (T007-T021 before T022-T036)
- Parallel tasks use different files
- Each task specifies exact file path
- Total tasks: 48 (comprehensive coverage)
ここまで実施して作成されたファイルと役割のまとめ⬇︎
.
├── CLAUDE.md
├── memory
│ ├── constitution.md
│ └── constitution_update_checklist.md
├── scripts
│ ├── check-task-prerequisites.sh
│ ├── common.sh
│ ├── create-new-feature.sh
│ ├── get-feature-paths.sh
│ ├── setup-plan.sh
│ └── update-agent-context.sh
├── specs
│ └── 001-
│ ├── contracts
│ │ └── api-spec.json //手順#4で作成されたAPI のインタフェース仕様を JSON 形式で記述したファイル
│ ├── data-model.md //手順#4で作成されたアプリケーションで扱うデータ構造を定義
│ ├── plan.md //手順#4で作成された技術的な実装計画をまとめる文書
│ ├── quickstart.md //手順#4で作成された開発者やユーザーが素早く環境構築や動作確認できるようにする手順書
│ ├── research.md //手順#4で作成された技術調査や比較検討の結果をまとめる文書
│ └── spec.md //手順#3で作成された仕様の中心となるファイル
│ └── tasks.md //手順#5で作成されたタスクリスト
└── templates
├── agent-file-template.md
├── plan-template.md
├── spec-template.md
└── tasks-template.md
6. コーディングツールで実装を進める
ClaudeCodeで実装を指示しました。
上記仕様と実装計画だけで出来上がったものが以下になります。
テスト仕様も同時に作成しているためバグなく出来上がりました。
SpecKitを使用することのメリット
- AIとの整合性向上
仕様を明確な「唯一の情報源」とすることで、AIの出力がプロジェクトの目的に対してずれにくくなります。 - フェーズ分割による安定性
各フェーズで検証・修正を行えるため、問題の早期発見と修正が可能です。
特にレガシー改修や既存システムへの追加開発に有効だと考えます。 - ツール整備と対応力
コマンドラインインターフェース(CLI)、テンプレート、プンプトなどがあらかじめ整備されており、導入障壁が低いです。 - オープンソースかつ柔軟
MITライセンスで公開され、誰でも利用・拡張可能です。
加えて、複数AIエージェントや技術スタックを横断して活用できます。
MITライセンスとは
MITライセンスとは、オープンソースソフトウェアで最もよく使われるライセンスの一つで、シンプルで自由度が高いライセンスです。
特徴
-
利用制限がほとんどない
ソフトウェアを 商用利用・改変・配布・再利用 することができます。
→ 企業や個人が安心してプロダクトに組み込めるのが大きなメリット。 -
著作権表示とライセンス文言の保持が条件
元のソフトウェアに付いている著作権表示とライセンス文を、再配布時や改変した場合でも残す必要があります。 -
無保証(No Warranty)
ソフトウェアの動作について保証はなく、利用者が自己責任で使う前提です。
→ 「このソフトで損害が出ても作者は責任を負いません」ということ。
注意点・今後の課題
-
AI品質依存
SpecKit 自体が生成品質を保証するわけではなく、AIの性能(推論精度や文脈理解)に依存します。AIモデルの選択は慎重に行って下さい。 -
仕様の曖昧さを回避
「実行可能な仕様」を書くには、開発者側にも一定のスキルと経験が必要だと感じました。
仕様が曖昧だと、AIが誤解した生成をしてしまうリスクがあります。
おわりに
SpecKit は、AI によるコード生成の精度と信頼性を高めるための 仕様主導の開発手法 を現実のツールとして実現した革新的な試みです。CLI やテンプレート、プンプトなど、開発フローへ組み込みやすい機能が整備されており、プロジェクトの新規立ち上げからレガシー改善まで幅広く活用できます。
ただし、導入には仕様記述スキルや適切なAIモデル選定など、前提となる準備も重要です。
それらをクリアできれば、SpecKitはAIコーディングの信頼性を一段引き上げる強力な武器となると考えます。
SpecKitは同じアプローチをしているKiroと違ってオープンソースのため、手を出しやすいのは魅力ですね。
この記事を参考に、SpecKit を自分のプロジェクトで試し、AI主導の開発体験をさらに強固で予測可能なものに進化させるきっかけになれば幸いです。
Discussion