Commit Graph

702 Commits

Author SHA1 Message Date
4thfever
84027fc1d7 Feat/retreat (#104)
* feat: add retreat
2026-01-26 23:18:11 +08:00
Zihao Xu
406d62f983 test(web): add tests for utility functions (#102)
Add tests for utility modules:
- formatters/number.ts: formatHp, formatAge
- mapStyles.ts: REGION_STYLES, getRegionTextStyle
- procedural.ts: getClusteredTileVariant
- theme.ts: GRADE_COLORS, getEntityColor

Total: 52 new tests added

Closes #87
2026-01-26 10:01:38 +08:00
Zihao Xu
c3ac584a90 feat: add spec-interview skill for requirement gathering (#103) 2026-01-25 15:39:39 -08:00
bridge
4a4c45c428 update: en screenshot gif 2026-01-25 19:06:10 +08:00
Zihao Xu
c406d2988f feat: add draggable sidebar resizer (#100)
* feat: add draggable sidebar resizer

- Add resizer handle between map and event panel
- Sidebar width adjustable from 300px to 50% screen width
- Default width remains 400px
- Auto-adjust on window resize

* fix: preserve map zoom when resizing sidebar

Only update viewport screen size without re-fitting the map

* fix: use window size for canvas to prevent map scaling on resize

- Canvas size now based on window instead of container
- Sidebar resize only clips the visible area, map stays same size
- Remove CSS stretch on canvas element

* docs: update sidebar-resizer spec with canvas fix
2026-01-25 18:44:54 +08:00
Zihao Xu
aaa636a08e fix: use str() instead of .value for realm i18n display (#98)
* fix: use str() instead of .value for realm i18n display

Fix bug where user-facing messages displayed raw enum values like
"FOUNDATION_ESTABLISHMENT" instead of translated names like "筑基".

The Realm and Stage classes already have __str__ methods that return
i18n translated text, but several places were incorrectly using
.value which returns the raw enum string.

Changed files:
- src/classes/single_choice.py: item exchange messages
- src/classes/kill_and_grab.py: loot messages
- src/classes/fortune.py: fortune discovery messages
- src/classes/avatar/inventory_mixin.py: purchase error messages

Also added unit tests and integration tests to prevent regression.

* test: add integration tests for all modified files

Add tests covering:
- kill_and_grab.py: context string realm display
- fortune.py: weapon/auxiliary intro realm display
- inventory_mixin.py: can_buy_item error message realm display
2026-01-25 18:44:13 +08:00
Zihao Xu
2b5ec24455 test(web): add tests for all composables (#101)
Add comprehensive tests for Vue composables:
- useSharedTicker (100% coverage)
- useTextures (97% coverage)
- useGameControl (92% coverage)
- useGameInit (69% coverage)

Tests cover:
- Lifecycle hooks (mount/unmount)
- State management
- Function exports
- Error handling
- LLM configuration flow
- Keyboard event handling

Closes #86
2026-01-25 01:17:02 -08:00
Zihao Xu
5fa8016334 docs: add test coverage guidelines to test-validate skill (#99) 2026-01-24 23:29:40 -08:00
Zihao Xu
0d8a001f8c feat: add Gemini preset template for LLM settings (#97)
* feat: add Gemini preset template for LLM settings

* docs: add comment explaining Gemini /openai suffix requirement

* feat: update Gemini preset to use latest 3-pro and 3-flash models

* docs: improve comment to reference backend client.py implementation
2026-01-24 22:42:46 -08:00
Zihao Xu
e286d249c4 feat: add claude-compatible skills for git-pr and test-validate (#96) 2026-01-24 17:21:42 -08:00
Zihao Xu
a2f2010ee5 feat: auto npm install in dev mode to sync dependencies (#94) 2026-01-24 17:19:44 -08:00
bridge
8af763531b update: mode 2026-01-24 23:40:54 +08:00
bridge
547cc01aef fix: pack i18n v1.3.0 2026-01-24 14:44:45 +08:00
bridge
b772fe0c3a update: version 2026-01-24 14:08:47 +08:00
bridge
1224dd2fcb feat: more weapons 2026-01-24 14:06:03 +08:00
bridge
339f6a655e fix: auxiliary in frontend 2026-01-24 13:58:29 +08:00
4thfever
e1091fdf5a Feat/i18n (#92)
* feat: add vue-i18n

* feat: add vue-i18n

* feat: add vue-i18n

* feat: add language class

* add: en templates and configs

* add: en names

* refactor: name gender id and sect id

* feat(i18n): add gettext infrastructure for dynamic text translation (#81)

* feat(i18n): add gettext infrastructure for dynamic text translation

- Add src/i18n/ module with t() translation function
- Add .po/.mo files for zh_CN and en_US locales
- Update LanguageManager to reload translations on language change
- Add comprehensive tests (14 tests, all passing)
- Add implementation spec at docs/specs/i18n-dynamic-text.md

Phase 1 of i18n dynamic text implementation.

* feat(i18n): expand .po files with comprehensive translation entries

Add translation messages for:
- Battle result messages (fatal/non-fatal outcomes)
- Fortune event messages (item discovery, cultivation gains)
- Misfortune event messages (losses, damage, regression)
- Death reason messages
- Item exchange messages (equip, sell, discard)
- Single choice context and option labels
- Common labels (weapon, auxiliary, technique, elixir)

Both zh_CN and en_US locales updated with matching entries.

* test: add .po file integrity tests

* feat: i18n for actions

* feat: i18n for effects

* feat: i18n for gathering

* feat: i18n for classes

* feat: i18n for classes

* feat: i18n for classes

* feat: i18n for classes

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* fix bugs

* update csv

* update world info

* update prompt

* update prompt

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* fix bug

* update

* update

* update

* update

* update

* update

* update

---------

Co-authored-by: Zihao Xu <xzhseh@gmail.com>
2026-01-24 13:47:23 +08:00
Zihao Xu
6f4b648d6e test(web): add comprehensive tests for all Pinia stores (#90)
* test(web): add comprehensive tests for all Pinia stores

* test(web): add edge case tests for Pinia stores

* test(web): document race condition bugs in ui and world stores

* fix(web): fix race condition bugs in ui and world stores

- ui.ts: Add detailRequestId counter to prevent stale responses from
  overwriting fresh data when reselecting the same target
- world.ts: Add eventsRequestId counter to prevent stale responses
  when filter changes rapidly via resetEvents
- Update tests to verify the fix works correctly

* fix(web): fix race condition in fetchInitStatus

- Add fetchStatusRequestId counter to prevent stale responses from
  overwriting fresh data when fetchInitStatus is called rapidly
- Add test that first proves the bug exists, then verifies the fix

* fix(web): fix race condition in fetchState

Add fetchStateRequestId counter to prevent stale responses from
overwriting fresh data when fetchState is called rapidly.

* test(web): add missing edge case tests for world store

- Add changePhenomenon API failure test
- Add initialize concurrent calls test
- Add getPhenomenaList concurrent calls test

Total: 108 tests

* test(web): add comprehensive socket store tests

- Add init() duplicate call guard test
- Add setup listener tests
- Add message handling tests (tick, game_reinitialized)
- Add status change handling tests

Total: 118 tests

* test(web): add missing socket message handling tests

- Add llm_config_required message tests
- Add unknown message type test

Total: 121 tests

* test(web): add handleTick edge case tests

- Add test for avatars without id (ignored)
- Add test for empty events array
- Add test for events filtered to empty

Total: 124 tests
2026-01-23 03:07:33 -08:00
Zihao Xu
00c8860c56 test: add edge case tests for game initialization (#83)
* test: add edge case tests for game initialization

* test: add 3 more edge case tests for game initialization

* test: add 8 more edge case tests for comprehensive coverage

* docs: add comprehensive coverage report to test file header
2026-01-21 00:18:52 -08:00
Zihao Xu
38327c1b10 test: add game initialization integration tests (#82)
Add 17 tests covering the complete init_game_async flow:
- Phase progress updates (4 tests)
- Full initialization success (2 tests)
- History processing (2 tests)
- LLM check failure handling (1 test)
- Avatar generation (2 tests)
- Error handling (3 tests)
- Sect initialization (1 test)
- Phase name constants (2 tests)

Closes #72
2026-01-21 00:03:42 -08:00
Zihao Xu
ec71310588 docs: update LLM config section in README (#80)
* docs: update LLM config section in README

* fix: use deepseek as example (matches default config)
2026-01-21 15:35:12 +08:00
Zihao Xu
666e19215d test: add comprehensive LLM failure scenario tests (#79)
* test: add comprehensive LLM failure scenario tests

Add 29 tests covering:
- HTTP errors: 401, 403, 404, 500, timeout, connection refused
- Parse errors: invalid JSON, empty response, array instead of object
- Retry logic: retry on parse failure, max retries exceeded
- Connectivity test: friendly error messages for common failures
- Configuration validation: missing base URL, URL normalization
- Async call_llm: success and error propagation
- Exception classes: LLMError, ParseError

Closes #71

* refactor: add comment explaining unreachable code for type checker
2026-01-20 23:27:04 -08:00
Zihao Xu
189e675711 test: add comprehensive WebSocket handler tests (#78)
Add 31 tests covering:
- ConnectionManager: connect, disconnect, broadcast, auto-pause
- WebSocket endpoint: connection, ping/pong, LLM config required message
- Control API: pause, resume, reset endpoints
- State/Map API: error handling, data serialization
- Event serialization: empty list, full fields, minimal fields

Closes #70
2026-01-20 23:00:48 -08:00
bridge
2b8812852c feat: code owner 2026-01-20 23:23:14 +08:00
bridge
64732d6912 update: license & contributing 2026-01-20 21:12:55 +08:00
Zihao Xu
6ed614814f feat: add i18n glossary in CSV format (Phase 0) (#67) 2026-01-20 20:54:33 +08:00
Zihao Xu
498249e83b fix: handle overlapping avatar names in highlightAvatarNames (#77)
Use single-pass regex replacement instead of multiple replaceAll calls.
This prevents shorter names from matching inside already-replaced longer names.

For example, with names '张三' and '张三丰', the text '张三丰是大师' now
correctly highlights only '张三丰', not '张三' within it.
2026-01-19 23:46:42 -08:00
Zihao Xu
d4b9b7303d ci: add frontend tests to CI workflow (#68)
* ci: add frontend tests to CI workflow

* chore: sync package-lock.json with test dependencies

* test: skip failing overlapping names test (known bug)
2026-01-19 23:32:23 -08:00
Zihao Xu
a1241a9156 fix: make cooldown_action decorator properly await async finish() (#75)
* fix: make cooldown_action decorator properly await async finish()

The decorator was incorrectly wrapping the async finish() method with a sync
wrapper, causing cooldown to be recorded BEFORE the action actually executed.

This fix:
- Changes wrapper to async def finish()
- Awaits original_finish() before recording cooldown
- Ensures cooldown is only recorded on successful execution

Fixes #74

* test: add test to verify cooldown not recorded on failure

This test actually reveals the async/await bug:
- Creates a FailingAction that raises in finish()
- Verifies cooldown is NOT recorded when action fails
- Fails with buggy sync wrapper, passes with async fix
2026-01-20 15:32:14 +08:00
Zihao Xu
5f236361dc feat: add Ollama preset for local LLM deployment (#76) 2026-01-19 23:31:36 -08:00
Zihao Xu
a8666950b1 test: add comprehensive tests for mutual actions (talk, spar, impart) (#73)
- Talk: 31% -> 98% coverage
- Spar: 49% -> 100% coverage
- Impart: 37% -> 95% coverage
- Add 30 new test cases
- Overall coverage: 58.64% -> 60% (meets CI threshold)

Testing strategy: Mock LLM calls via call_llm_with_task_name

Closes #69
2026-01-19 23:09:38 -08:00
bridge
325c72e513 update: readme 2026-01-20 01:01:45 +08:00
bridge
2c9ef96c36 update: contributing 2026-01-19 21:56:09 +08:00
bridge
a7ab18ea1c fix: package bug v1.2.2 2026-01-19 21:26:09 +08:00
bridge
bf13cdf2d2 fix: incorrect relationship for new avatar 2026-01-19 21:14:20 +08:00
Zihao Xu
31d0c060e8 feat: enhance README with activity graph and contributor avatars (#65) 2026-01-19 20:50:33 +08:00
Zihao Xu
7f31d9884f test: add comprehensive tests for ai.py (13% -> 98% coverage) (#64)
- Test LLM response parsing (list and dict formats)
- Test null params conversion to empty dict
- Test invalid format handling and skipping
- Test emotion update logic with all emotion types
- Test fallback to CALM on invalid/missing emotion
- Test batch avatar processing
- Test AI.decide wrapper returns NULL_EVENT
- Test thinking field variants (avatar_thinking vs thinking)
- Add testing strategy documentation to test file

Closes #63
2026-01-19 20:49:24 +08:00
Zihao Xu
665d94addb test(web): add example frontend tests (#61)
* test(web): setup frontend test infrastructure

- Add testing dependencies (vitest, vue-test-utils, testing-library, jsdom, msw)
- Create vitest.config.ts with jsdom environment and coverage settings
- Create setup.ts with Pinia initialization and fake timers
- Add test scripts to package.json (test, test:run, test:coverage)

Closes #56, closes #57

* test(web): add example frontend tests

- Add system store tests (initial state, getters, togglePause)
- Add eventHelper utility tests (processNewEvents, mergeAndSortEvents, avatarIdToColor, highlightAvatarNames)

Closes #59
2026-01-19 20:48:43 +08:00
Zihao Xu
8bf5f64bc3 test(web): setup frontend test infrastructure (#60)
- Add testing dependencies (vitest, vue-test-utils, testing-library, jsdom, msw)
- Create vitest.config.ts with jsdom environment and coverage settings
- Create setup.ts with Pinia initialization and fake timers
- Add test scripts to package.json (test, test:run, test:coverage)

Closes #56, closes #57
2026-01-19 20:48:28 +08:00
Zihao Xu
9677055faa fix: use sect_id instead of sect in fortune technique filter (#55)
PR #32 changed Technique.sect (str) to Technique.sect_id (int), but
fortune.py was not updated. This caused AttributeError when fortune
event triggered and tried to access t.sect.

Error: 'Technique' object has no attribute 'sect'
2026-01-19 20:48:05 +08:00
Zihao Xu
8f7c2cfa66 docs: add Codecov coverage badge to README (#54)
Closes #49
2026-01-19 20:47:49 +08:00
Zihao Xu
ee2964e151 ci: add coverage reporting, 60% threshold, and Codecov integration (#53)
- Add pytest-cov to CI dependencies
- Generate coverage report (xml + terminal)
- Set minimum coverage threshold to 60% (current: 63%, target: 90%)
- Upload coverage to Codecov
- Add 10 minute timeout

Closes #46, closes #47, closes #48
2026-01-19 20:47:26 +08:00
Zihao Xu
daa7a20679 test: add fixed_random_seed fixture with autouse=True (#52)
Ensures all tests have deterministic random behavior by setting
random.seed(42) before each test. This prevents flaky tests caused
by random number generation.

Closes #44
2026-01-19 20:46:59 +08:00
Zihao Xu
ed2d8720aa chore: configure coverage settings in pyproject.toml (#51)
- Add [tool.coverage.run] with source and branch coverage
- Add [tool.coverage.report] with exclude patterns and show_missing

Closes #43
2026-01-19 20:46:42 +08:00
Zihao Xu
5a82a186a7 chore: add pytest-cov to requirements (#50)
Closes #42
2026-01-19 20:46:09 +08:00
Zihao Xu
1a34b7724b feat(web): make avatar names in event log clickable (#41)
When avatars overlap (e.g., during sparring, talking, dual cultivation),
it's hard to click on them directly. This adds the ability to click on
colored avatar names in the event panel to open their detail view.

- Modify highlightAvatarNames to include data-avatar-id attribute
- Add click event delegation in EventPanel
- Add hover styles for clickable names
2026-01-19 20:45:44 +08:00
bridge
2e04b718e8 update: splash 2026-01-18 21:49:13 +08:00
bridge
a075c1cc59 update: history prompt 2026-01-18 21:44:47 +08:00
bridge
bc6725b302 update: version v1.2.1 2026-01-18 17:25:27 +08:00
4thfever
6185d314af refactor: remove region_names dict, use regions traversal instead (#40)
The region_names dictionary was a redundant index that needed manual
sync when HistoryManager modified region names. This caused bugs where
resolve_query couldn't find regions by their new (history-modified) names.

Instead of maintaining two data structures (regions[id] and region_names[name]),
we now only use regions[id] as the single source of truth. The _resolve_region
function iterates over regions.values() to find matches by name.

This approach:
- Eliminates the sync bug entirely
- Simplifies the codebase
- Has negligible performance impact (region count is small)

Co-authored-by: Zihao Xu <xzhseh@gmail.com>
2026-01-18 17:13:28 +08:00