The repository now lives under the tiennm99 account, so the published
site base is https://tiennm99.github.io/ai-coding-workflow-labs/.
Repo-path Pages do not redirect across owners, so the old host URL is
gone rather than forwarded.
chore: update vulnerable dependencies and add Maven CI
Bump jackson-databind 2.15.2 -> 2.22.1, logback-classic 1.4.8 -> 1.5.38,
slf4j-api 2.0.7 -> 2.0.17, and netty-all 4.1.94 -> 4.1.136 to clear all
open Dependabot security advisories.
Add a GitHub Actions workflow building on JDK 11, and a .gitignore for
Maven/IDE artifacts.
@
gstack moved to npm on 2026-08-17 and ships package-lock.json with no
bun.lock, but the Pages workflow still installed bun and ran
"bun install --frozen-lockfile". Builds stayed green only because bun
falls back to consuming package-lock.json, so the mismatch never
surfaced. Its six sibling subprojects already use npm ci.
Verified locally: npm ci && npm run build produces the same 4 pages plus
the sitemap.
- Human verification passed for all Phase 1 requirements
- PEOPLE-01 through PEOPLE-04 confirmed working
- 20/20 automated tests passing
- Phase 1 Bill Entry & Assignment complete
- Subscribes to store.items signal
- Displays each item with name and formatted price
- Includes ItemAssign component for each item
- Shows empty state when no items added
- Multi-select checkbox UI for each person
- Reflects current assignment state
- Toggles person on/off when clicked
- Calls store.setAssignment on change
- Shows hint when no people added
- Controlled form with name and price inputs
- Calls store.addItem on form submit
- Shows error message on validation failure
- Clears inputs on successful add
- Created 01-03-SUMMARY.md with full execution documentation
- Updated STATE.md position to Plan 3 of 5 (60% progress)
- Added decisions: controlled forms, signal access pattern
- All 3 tasks committed atomically
- Created 01-02-SUMMARY.md documenting currency utilities and billStore
- Updated ROADMAP.md to mark 01-02 as complete (2/5 plans done)
- All tests passing (20/20)
- Created SUMMARY.md with execution details and deviations
- Updated STATE.md with plan completion metrics
- Updated ROADMAP.md with plan 01-01 progress
- Marked PEOPLE-01 through PEOPLE-04 as complete in REQUIREMENTS.md
- Subscribes to store.people signal
- Renders list of person names with unique keys
- Shows empty state when no people added
- Preact Signals auto-track dependencies in components
- Controlled form with useState for local state
- Calls store.addPerson on form submit
- Shows error message if addPerson fails
- Clears input on successful add
- Uses Preact hooks for form state management
- Add package.json with Vitest, jsdom, Vite, and Preact dependencies
- Configure Vitest with jsdom environment for component testing
- Create test stubs for billStore (PEOPLE-01, PEOPLE-02, PEOPLE-03, PEOPLE-04)
- Create test stubs for currency utilities (dollarsToCents, centsToDollars, formatCurrency)
- Add vitest.config.js with jsdom environment and global test APIs
- Install vitest and jsdom as dev dependencies
- Add test scripts (test, test:run) to package.json
Archive and finalize v1.0 milestone and planning artifacts: add MILESTONES.md, milestone archives (v1.0-ROADMAP.md, v1.0-REQUIREMENTS.md), verification and phase artifacts, and update phase/roadmap/project state to mark v1.0 MVP as shipped. Tidy PROJECT and ROADMAP to reflect shipped features and next steps, remove the old REQUIREMENTS.md (moved to milestone archive), and update STATE.md to show milestone completion. Minor code change: expose GridManager.events as public readonly to allow external subscribers. Package metadata: normalize keywords formatting and add an optional dependency entry in package.json for rollup native binary support.
Bug: Game was listening on its own events emitter for 'tilesSelected'
but GridManager emits on its own events emitter.
Fix: Changed listener from this.events to this.gridManager.events
- Enhanced setupCanvas() with viewport-based scaling
- Scale down only, never scales up
- CSS transform for display scaling (preserves coordinates
- Added comprehensive test coverage for responsive scaling behavior
- Enhanced setupCanvas() with viewport-based scaling
- Scale down only on scales to fit viewport on mobile devices
- CSS transform for display scaling (preserves coordinate mapping
- Added comprehensive test coverage for responsive scaling
- Verified coordinate mapping works correctly with CSS transform
- MatchAnimation class with easeOutBack easing for satisfying pop effect
- scale+fade transforms in renderTile()
- CONFIG.animation.matchDuration = 250ms
- All tests passing
- Created 06-02-SUMMARY.md with accomplishments, deviations, and metrics
- Updated STATE.md with plan completion and decisions
- Updated ROADMAP.md progress (3/4 summaries complete)
- Marked UX-01 requirement complete
- Add animateMatch() method to start animations for matched tiles
- Apply scale/alpha transforms in renderTile() when animation exists
- Clean up completed animations from matchAnimations map
- Add tests for animateMatch integration
- Add animation.matchDuration=250 to CONFIG
- Add matchAnimations Map and animateMatch method to Renderer
- Apply scale+alpha transforms in renderTile for animating tiles
- Wire animateMatch call in Game.ts after drawPath
This completes the dependency from plan 06-01 (Rule 2 auto-fix for missing critical functionality)
- Add shadowBlur=15 and shadowColor='#00ff00' for green glow
- Wrap path drawing in ctx.save()/ctx.restore() for state preservation
- Add tests for glow effect properties (shadowBlur, shadowColor, save/restore)
- SUMMARY.md with RippleAnimation implementation details
- STATE.md updated with Phase 6 position and decisions
- ROADMAP.md updated with plan progress
- REQUIREMENTS.md: UX-02 marked complete
- Add renderer.addRipple(x, y) call in handleInput method
- Ripple appears at touch/click coordinates before tile selection
- Provides visual feedback for all input interactions
- Add RippleAnimation class with 300ms duration and 40px max radius
- Add rippleAnimations property to Renderer
- Add addRipple(x, y) method to trigger ripple effect
- Render ripples in main render loop with auto-cleanup
- Use selection color (rgba 233, 69, 96) for visual consistency
- Add touch-action: none to canvas to prevent zoom/scroll
- Add overflow: hidden to body to prevent page scroll
- Mobile touch gestures now properly blocked during gameplay
Update project planning and implement game-end components: tweak .gitignore entries, bump planning state progress, and add extensive Phase 04 artifacts (plans, summary, research, validation) plus Phase 05 initial plan. Deliverables include index.html overlay for game-over UI and modifications to src/game/Game.ts and src/models/Tile.ts to support win / no-moves detection and restart hooks; also add GameStateManager / NoMovesDetector integration notes and tests scaffolding in planning docs. Purpose: prepare and record implementation details for win/lose detection, game-over overlay, input blocking, reset/restart flow, and board-generation recovery.
- Add board:generated event to GameEvents interface
- implement generateRandomGrid() method with solvability verification
- Enhance initializeGrid() to use NoMovesDetector for verification
- Add tests for random board generation
- add import for NoMovesDetector
- shuffleTiles() redistributes tile types while preserving positions
- Clears selection to prevent stale tile references
- Emits board:shuffling before and board:shuffled after
- Handles partially cleared boards correctly
- Added comprehensive test coverage for shuffle functionality
- Added previousScore property to Game class
- Implemented restart() method that stores previousScore, resets grid/score/state/UI
- Added updatePreviousScoreDisplay() helper method
- Added game:restart event type to GameEvents interface
- Restart resets grid via initializeGrid(), resets score to 0, transitions state to IDLE
- Previous score preserved and displayed, hidden if 0
- All tests passing for restart functionality
- Added tests for previous-score-display element existence and styling
- Added previous-score-display div to HTML with score-container wrapper
- Element initially hidden with display: none
- Follows existing score-display pattern for consistency
- Created 04-02-SUMMARY.md with implementation details
- NoMovesDetector with type-optimized algorithm (94% reduction in PathFinder calls)
- Game over overlay HTML with semi-transparent styling
- GameStateManager.reset() method (already implemented in 04-01)
- Updated STATE.md with progress and decisions
- Updated ROADMAP.md with phase 4 progress
- Added game-over-overlay div with fixed positioning and z-index 1000
- Added overlay-content div with semi-transparent background
- Added game-over-message h1 element for win/lose message
- Added restart-button button with hover effect
- Overlay hidden by default (display: none)
- Styling matches score overlay pattern
- Created comprehensive test suite with 10 test cases
- Tests cover valid/invalid move detection, type-optimization, edge cases
- Tests verify path detection with 0, 1, and 2 turns
- Tests verify cleared tiles are skipped and empty board handling
- Add transition validation with validTransitions mapping
- Implement transitionTo() method with validation and event emission
- Add canSelectTile() helper method for input blocking
- Add reset() method for restart functionality
- Update tests to cover all state machine behavior (7 test cases)
- Added div with id=\"score-display\" in top-right corner
- Semi-transparent background (rgba(26, 26, 70, 0.9))
- Large bold font (24px) with light text color (#eaeaea)
- Initial text shows \"Score: 0\"
- Positioned above canvas with z-index: 100
- Added clearTiles method that marks tiles as cleared
- Emits tile:cleared event for each cleared tile
- Calls deselectAll() after clearing tiles
- Enables CORE-05 (connected tiles disappear) and CORE-07 (cleared tiles become passable)
- Created test suite with 5 test cases for score calculation
- Tests cover base score (100), 0-turn bonus (150), 1-turn bonus (125)
- Tests verify default to base score for invalid turn counts
- Tests verify integer scores (no floating point)
- Added PathNode interface for BFS state tracking (row, col, direction, turns, path)
- Added MatchResult interface for match validation results (valid, reason, path, turns)
- Created test file with type import tests
- Direction encoding: -1=none/start, 0=up, 1=right, 2=down, 3=left
- Add shell configs, IDE files, and local configs to .gitignore
- Add Phase 2 planning artifacts (CONTEXT, RESEARCH, VERIFICATION)
- Add GridManager test suite
- Create 02-03-SUMMARY.md with implementation details
- Update STATE.md with Phase 2 complete status
- Update ROADMAP.md to mark Phase 2 as complete
- Record all task commits and decisions
Phase 2 (Grid and Input) is now 100% complete with all 4 plans finished.
- Add setupInputListeners() public method
- Add handleClick and handleTouch event handlers
- Add handleInput() method for coordinate translation
- Implement getBoundingClientRect() for accurate hit detection
- Account for device pixel ratio in coordinate calculations
- Map canvas coordinates to tile grid position
- Call gridManager.selectTile() for valid tiles
Implements Task 2 of plan 02-03
- Add GridManager and Renderer imports
- Add gridManager and renderer fields to Game class
- Initialize GridManager and create grid in constructor
- Initialize Renderer with canvas reference
- Delegate render() to renderer.render()
- Add tilesSelected event listener for logging
Implements Task 1 of plan 02-03
- Created Renderer class with tile rendering, selection highlighting, and fade-in animations
- Created GridManager class with tile array and selection state management (blocking dependency)
- Added tilesSelected event to GameEvents interface
- Created comprehensive test suite for Renderer with 9 test cases
**Renderer Features:**
- Renders all non-cleared tiles from GridManager at correct positions
- Centers grid horizontally and vertically within canvas
- Displays emoji characters centered within tile bounds
- Selection highlights with border (3px) and background tint (30% opacity)
- Fade-in animation over ~100ms using performance.now()
- Uses CONFIG.tile.size, gap, cornerRadius for positioning
- Respects CONFIG.colors for styling
**GridManager Features:**
- Manages 2D tile array (10x16 grid = 160 tiles)
- Selection state tracking with toggle behavior (0-2 tiles)
- selectTile() with toggle deselect and cleared tile filtering
- Emits tilesSelected event when 2 tiles selected
- getTileAt() for coordinate-based tile access
**Note:** Tests created but not runnable due to sandbox file system restrictions
preventing npm install. Implementation verified manually against plan requirements.
- Create Plan 02-00 (Wave 0) with test file stubs for Nyquist compliance
- Update Plans 02-01, 02-02, 02-03 to depend on 02-00
- Fix wave numbers: 02-01 and 02-02 remain in Wave 1, 02-03 stays in Wave 2
- Update VALIDATION.md: mark nyquist_compliant: true, wave_0_complete: true
Resolves checker issues:
- Nyquist Compliance: Wave 0 test files now exist
- All TDD tasks have test stubs to run against
- Phase 1 Core Foundation complete
- Game class orchestrates loop, events, and canvas
- main.ts entry point with DOMContentLoaded initialization
- Configuration validation tests added
- Fixed browser compatibility with custom EventEmitter