Skip to content

Comments

World load refactoring#2891

Merged
bylins merged 344 commits intomasterfrom
world-load-refactoring
Feb 22, 2026
Merged

World load refactoring#2891
bylins merged 344 commits intomasterfrom
world-load-refactoring

Conversation

@kvirund
Copy link
Collaborator

@kvirund kvirund commented Jan 31, 2026

No description provided.

@kvirund kvirund force-pushed the world-load-refactoring branch 4 times, most recently from 32619ee to 8f8ab53 Compare February 1, 2026 02:03
@kvirund kvirund marked this pull request as ready for review February 3, 2026 04:59
kvirund and others added 24 commits February 3, 2026 16:37
- Test file was in UTF-8, should be in KOI8-R like all source files
- Russian comments now properly encoded in KOI8-R
- Word 'тест' now shows correct bytes: 0xD4 0xC5 0xD3 0xD4
- All tests still pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Problem:
- YAML::Emitter validates strings as UTF-8
- KOI8-R bytes → UTF-8 replacement chars (�) in quoted/literal strings
- byte/ubyte fields → "\xNN" instead of numbers

Solution: Custom Koi8rYamlEmitter
- Manual YAML writing without UTF-8 validation
- API: Key(), Value(), BeginMap(), IncreaseIndent(), Comment()
- Literal blocks (|) for multiline strings
- KOI8-R bytes pass through unchanged
- Cast byte/ubyte to int before writing
- Comments match converter format (material names, skill names, trigger names, etc.)

Changes:
- Add Koi8rYamlEmitter class (~100 lines)
- Add helper functions for comments (~40 lines)
- Rewrite SaveMobs using emitter (~450 lines)
- Rewrite SaveObjects using emitter (~340 lines)
- Rewrite SaveRooms using emitter (~230 lines)
- Rewrite SaveTriggers using emitter (~140 lines)
- Remove YAML::Node creation and WriteYamlAtomic usage
- Total: ~1300 new lines, remove ~600 old lines

Tested:
- Compiles successfully with YAML support
- Server boots with YAML world without errors

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Core Features:
- Unix Domain Socket JSON API (#ifdef ENABLE_ADMIN_API)
- Authentication via existing imm/builder credentials
- OLC integration for mob/object/room/trigger operations
- UTF-8 support for Admin API connections

Admin API Endpoints:
- Authentication: auth (username/password)
- Mobs: list_mobs, get_mob, update_mob, create_mob, delete_mob
- Objects: list_objects, get_object, update_object, create_object, delete_object
- Rooms: list_rooms, get_room, update_room, create_room, delete_room
- Triggers: list_triggers, get_trigger, update_trigger, create_trigger, delete_trigger
- Zones: list_zones, get_zone, update_zone

Implementation:
- src/engine/network/admin_api.{cpp,h} - Admin API protocol handler
- src/engine/core/comm.cpp - Unix socket initialization and connection handling
- src/engine/core/config.{cpp,h} - Admin API configuration
- lib.template/misc/configuration.xml - Admin API settings (socket_path, require_auth)

Testing:
- tests/test_admin_api.py - Python test client
- Uses environment variables MUD_USERNAME and MUD_PASSWORD for authentication

Bug Fixes:
- zedit.cpp: Add null check for d->character in zedit_disp_menu()
- do_telegram.cpp: Fix memory leak in curl_easy_escape()
- utils_time.h: Fix profiler log path (log/ instead of ../log/)
- yaml_world_data_source.cpp: Add YAML quoting for special characters

Documentation:
- CLAUDE.md: Add proper KOI8-R file editing workflow
- WEB_ADMIN_READY.md: Implementation status and next steps
- WEB_ADMIN_IMPLEMENTATION_STATUS.md: Detailed progress tracking
- YAML_BUGS.md: Known YAML converter issues

Configuration:
- .gitattributes: Add UTF-8 exception for Python test files
- .gitignore: Add __pycache__/ for Python bytecode
- Fix memory allocation: use NEWCREATE instead of CREATE
- Fix kInvalidSocket reference: use -1 directly
- Fix write_to_descriptor: add iosystem:: namespace
- Add admin_socket to epoll monitoring
- Add admin connection handling in game_loop
- Add conditional process_input for admin_api_mode
- Add EAGAIN/EWOULDBLOCK handling in admin_api_process_input
- Add koi8r_to_utf8 helper function for encoding conversion
- Remove hardcoded credentials from test script

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Initialize output buffer in new_admin_descriptor
- Skip formatting in process_output for Admin API
- Admin API uses raw JSON output without \r\n formatting

Fixes segfault in get_mob command.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add test_get_room and test_update_room functions
- Add get_room and update_room commands
- Add room tests to full_crud_test
- Improve error messages with command list

All CRUD operations tested and working:
- Mobs: get, update
- Objects: get, update
- Rooms: get, update

YAML files update correctly with proper KOI8-R encoding.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add test_list_mobs, test_list_objects, test_list_rooms, test_list_zones
- Add list commands to CLI interface
- Add list tests to full_crud_test
- Update usage messages

All list commands tested and working:
- list_zones: 640 zones
- list_mobs: zone-filtered mob listing
- list_objects: zone-filtered object listing
- list_rooms: zone-filtered room listing

Full test suite now includes:
- List commands (zones, mobs, objects, rooms)
- GET commands (mob, object, room)
- UPDATE commands (mob, object, room)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add test_create_mob and test_delete_mob functions
- Add create_delete_test command for testing mob creation
- Update usage messages

Create functionality tested and working:
- Mobs can be created with auto-assigned vnums
- Data persists to YAML files
- Uses OLC backend (medit_save_internally)

Delete functionality intentionally disabled for safety:
- "Mob deletion via API disabled for safety. Use in-game OLC instead."

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add test_create_object, test_delete_object
- Add test_create_room, test_delete_room
- Extend create_delete_test to cover all entity types
- Handle zone capacity issues (use zone 10 for objects)
- Add explicit vnum for room creation

Testing shows:
- create_mob: ✓ works (auto-vnum in zone range)
- create_object: requires available vnum space
- create_room: requires explicit vnum field
- delete_*: disabled for safety on all entity types

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed critical issues in Admin API implementation:

1. **Fix create_room crash (SIGSEGV)**
   - OLC functions (redit_disp_menu) call SendMsgToChar which requires ch->desc
   - Create dummy CharData with descriptor set for temp_d
   - Initialize output buffer for temp_d to capture OLC messages
   - Applied to all create functions (mob/object/room/trigger)

2. **Fix room file naming (zero-padding)**
   - Room files were saved as "0.yaml" instead of "00.yaml"
   - Changed yaml_world_data_source.cpp to use fmt::format("{:02d}")
   - Now correctly creates 00.yaml, 01.yaml, ..., 99.yaml

3. **Add OLC output to JSON responses**
   - Capture OLC menu/messages from temp_d->output buffer
   - Convert KOI8-R to UTF-8 and add to JSON as "olc_output" field
   - Added to all create functions for debugging/logging

4. **Extend test suite**
   - Updated test_admin_api.py to display olc_output when present
   - Helps verify OLC integration is working correctly

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Log all Admin API commands (except auth/ping) to immortals via IMLOG channel:
- Uses admin_user_name saved during authentication
- Logs with BRF level, visible to implementators (level 34+)
- Format: "Admin API: {username} executed '{command}'"

This provides audit trail and real-time monitoring of Admin API usage.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
YAML Emitter fixes:
- Fix comment placement: moved comment output from Key() to Value()
- Comments now appear AFTER values: "spell: 0  # comment" (was "spell:  # comment 0")
- Affects all numeric fields with comments (spell, material, etc)

YAML serialization fixes:
- Fix short_desc saving: use get_short_description() instead of get_description()
- This bug caused short_desc and description to be swapped in saved files

Test improvements:
- Add field mapping in verify_yaml_file() for API→YAML structure
- Map flat fields (aliases, short_desc) to nested YAML (names.aliases, descriptions.short_desc)
- Tests now correctly verify YAML file contents after updates

All CRUD tests now pass with YAML verification.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
YAML verification fixes:
- Add field mapping for 'name' field (mob/object → names.aliases, room/zone → root)
- Add field mapping for 'level' field (mob → stats.level, object → root)
- Filter out 'vnum' from verification (it's in filename, not content)
- Expand short_desc/long_desc mapping for different entity types

Test improvements:
- Use explicit vnum for create_object to avoid "no available vnums" error
- Change test zone from 10 to 3 (has free vnums)
- All create tests now pass with YAML verification

Results:
✅ create_mob: YAML verified
✅ create_object: YAML verified
✅ create_room: YAML verified

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changes:
- get_room: return triggers array (vnums from proto_script)
- update_room: accept triggers array to update proto_script
- Verify trigger vnums exist before adding

Triggers are now fully supported in room editing via Admin API,
matching OLC functionality (redit 'S' command).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
New test command: comprehensive_test
- Tests ALL supported fields for mobs (names, descriptions, stats, sex, position)
- Tests ALL supported fields for objects (weight, cost, rent, type, material, durability)
- Tests ALL supported fields for rooms (name, description, sector, triggers)

All comprehensive tests pass successfully.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Admin API improvements:
- Add get_stats endpoint returning zones/mobs/objects/rooms/triggers counts
- Fix alignment field assignment (use direct field access instead of non-existent setter)
- Fix heap-buffer-overflow with bounds checking in list_mobs
- Fix JSON parsing to read from correct nested form structures
- Fix triggers handling (shared_ptr<list> instead of vector)

Web UI improvements:
- Redesign all 16 templates in unified Modern Skeuomorphic style
- Update CSS with new design system (parchment cards, typography)
- Add full mob edit form with 50+ fields (names, stats, abilities, resistances, etc.)
- Fix header logo/title layout (remove button wrapper from text)
- Connect index page to get_stats endpoint for live statistics
- Add get_stats method to MudAdminClient

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
JavaScript fixes:
- Skip empty string fields (don't call setNestedValue for empty values)
- Add cleanEmptyObjects() to remove empty nested objects before sending
- Prevents sending malformed JSON with empty objects causing type errors

Admin API improvements:
- Add authentication logging (notify immortals on login/failed login)
- Add detailed JSON logging in update_mob for debugging
- Log format: "Admin API: {username} connected and authenticated"

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace separate stats grid + nav cards with single unified section
- Each card now shows statistic number AND is clickable link
- Visual hierarchy: icon → number → label → description
- Add .stat-nav-card classes with hover/active states
- Keep legacy .stat-card and .nav-card classes for compatibility
- Reduce index.html from 171 to 112 lines

Design: Modern Skeuomorphic parchment cards with tactile feedback

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove log() call that dumps full JSON on every mob update
- Debug logging was added for diagnostics, no longer needed
- Keep only mudlog() for authentication and command execution

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removed:
- Encoding conversion hex dumps (koi8r->utf8, utf8->koi8r)
- "Received command" logs (duplicates mudlog)
- All operation logs (create/update/delete for mobs/objects/rooms/triggers)
- 40+ lines of debug code eliminated

Kept:
- Error logs (buffer overflow, read errors, disconnects)
- Authentication logs (success/failure, access denied)
- Warning logs (missing triggers)
- mudlog() for immortals (command execution)

Fixed:
- Unused parameter warnings in delete_* functions

Result: Clean production-ready logging

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Current situation:
- API supports: names, descriptions, stats, abilities, triggers
- API does NOT support: position, behavior, resistances, savings, flags

Solution: Filter unsupported fields before sending JSON

This ensures saving works NOW. Full support will be added separately.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements comprehensive mob field handling including resistances,
savings, position (nested object), and behavior (nested object).

Changes:
- admin_api.cpp: Add support for resistances (7 fields), savings (3 fields),
  position as nested object (default_position, load_position), and behavior
  (class, attack_type). Fixes "type must be number, but is object" error.
- mob_edit.html: Remove JavaScript filtering - all fields now sent to API
- test_admin_api.py: Update comprehensive test to validate all new fields

All fields now work as in OLC. Tested compilation - no errors/warnings.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removes redundant comprehensive_test command and merges it into
full_crud_test. Now full_crud_test runs comprehensive field testing
for all entity types (mobs, objects, rooms) including all new fields.

Changes:
- full_crud_test now uses test_comprehensive_mob/object/room functions
- Removed separate comprehensive_test command (redundant)
- Updated help text to clarify Individual commands vs Test suites

Benefits:
- Single command to test all endpoints with comprehensive data
- No confusion about which test to run
- Tests ALL fields including resistances, savings, position, behavior

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Extends get_mob to return ALL fields that can be updated via update_mob,
so web forms can display current values instead of empty defaults.

New fields added to get_mob response:
- abilities: strength, dexterity, constitution, intelligence, wisdom, charisma
- resistances: fire, air, water, earth, vitality, mind, immunity (7 fields)
- savings: will, stability, reflex (3 fields)
- position: default_position, load_position (nested object)
- behavior: class, attack_type (nested object)
- stats.sex, stats.race, stats.alignment
- triggers: array of trigger vnums

This ensures parity between get_mob and update_mob - every field that
can be updated is also returned, enabling proper form pre-population.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
kvirund and others added 7 commits February 20, 2026 09:54
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v5 supports tokenless upload for public repos via OIDC,
fixing the JSON parse error from v4.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nch)

Coverage summary and HTML artifact remain available in GitHub Actions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Token via CODECOV_TOKEN secret (required for protected branch master).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Expose is_substring/word_check/compare_cmd/one_phrase via new
  dg_triggers.h header for unit testing
- tests/trigger_indenter.cpp: 9 tests for TriggerIndenter::indent()
  covering if/else/end, while/done, switch/case/break, nesting,
  level clamp at zero, and reset
- tests/dg_string_matching.cpp: 20 tests for string-matching functions
  (word boundary checks, wildcards, quoted phrases, compare_cmd modes)
- tests/dg_var_context.cpp: 8 tests for add/find/remove_var_cntx
  covering context separation, upsert semantics, and removal
- All 334 tests pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@kvirund kvirund reopened this Feb 21, 2026
kvirund and others added 21 commits February 21, 2026 12:31
All build configurations are passing. Soft-failure mode was a
temporary measure during initial CI setup -- remove it so a broken
build actually turns the check red.

Also update the build-summary note to reflect the new policy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- dg_scripts.cpp: indent body of `if (!char_handled)` block by one
  tab level -- the block was split from a long if/else chain to work
  around MSVC C1061, but the contents were left at the wrong level
- CMakeLists.txt: remove duplicate vim modeline that ended up in the
  middle of the file (correct one remains at the end)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Проверка была добавлена при введении Admin API, чтобы избежать краша
при вызове zedit_disp_menu без персонажа. Код, который это вызывал,
больше не существует: HandleUpdateZone работает напрямую с zone_table,
не используя OLC и не вызывая zedit_setup.

Заодно заменён вводящий в заблуждение TODO в HandleUpdateZone на
объяснение намеренного дизайна: Admin API и OLC оба работают с
zone_table в памяти; сохранение на диск -- отдельный явный шаг
(эндпоинт save_zone / команда сохранения в OLC) через IWorldDataSource.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Баг: setup_full_world() не очищала dest_dir перед распаковкой архива.
При повторном запуске `mv lib/* dest_dir/` падало с "cannot overwrite
... Directory not empty", оставляя данные от предыдущего Admin API
теста. Следующий прогон считал чексуммы изменённого мира → несовпадение.

Фикс:
- Добавить `rm -rf "$dest_dir"` перед `mkdir -p` в setup_full_world()
- Убрать условные пропуски setup_full_world для legacy и yaml — полный
  мир всегда пересоздаётся при каждом запуске

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Та же проблема, что и с полным миром: setup_small_world не чистила
dest_dir перед cmake, а вызовы для legacy и yaml были условными.
После Admin API тестов (создание/удаление триггера 103, изменения
комнат/мобов/объектов) грязные данные оставались и чексуммы расходились.

Фикс:
- rm -rf "$dest_dir" в начале setup_small_world (до cmake)
- Убрать условные пропуски для всех трёх форматов малого мира

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CMake создавал симлинк build/lib -> source/lib.template при конфигурации.
Это ошибочное поведение: сервер запускается с -d small (или -d full),
а не из корня build-директории. Симлинк не нужен и вводит в заблуждение.

Заодно: в setup_full_world для yaml убрать lib/world перед mv,
чтобы не было "cannot overwrite" (world уже создан конвертором).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Раньше конвертор читал из dest_dir/lib/ и писал в dest_dir/ — это
порождало конфликт mv (dest_dir/world/ уже существовал после конверсии).

Теперь: сначала mv lib/* → dest_dir/ (flatten), затем конвертация
in-place (-i dest_dir -o dest_dir), как у малого мира.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Порядок: распаковка в full/lib/, конвертация in-place там же
(все конфиги на месте), затем mv lib/* full/ + rmdir lib.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lib/misc/grouping и lib/misc/noob_help.xml не трекаются в git —
они находятся в lib.template/. На свежем клоне без cp lib.template/* lib/
cmake падал с "Cannot find source file".

Исправлено на lib.template/misc/grouping и lib.template/misc/noob_help.xml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… constant

The zone_table[0]-as-sentinel pattern conflicted with `kNowhere = 0` which is
a room-specific constant. Using kNowhere as a zone sentinel was a design mistake:
GetZoneRnum() returning 0 was indistinguishable from a valid zone at index 0.

Changes:
- Add `const ZoneRnum kNoZone = -1` to structs.h (zone-specific nil sentinel)
- db.cpp: GetZoneRnum() starts search from bot=0, returns kNoZone on miss
- db.cpp: zone_table no longer pre-allocates sentinel slot at index 0
- db.cpp: CalculateFirstAndLastRooms() sets zone_table[0].first = 1 explicitly
  (first zone never gets a transition-in, so the loop never sets its .first)
- db.cpp: all kNowhere/0 zone comparisons updated to kNoZone
- yaml_world_data_source.cpp, sqlite_world_data_source.cpp: vnum→idx mapping
  no longer adds +1 offset; zone_idx starts at 0
- boot_data_files.cpp: s_zone_number starts at 0 (not 1)
- zedit.cpp, do_show_zone_stat.cpp: comparisons updated to kNoZone

Fix crash in find_first_step (graph.cpp) when mob has kStayZone flag and is not
in the world (in_room == kNowhere): GetZoneRooms() return value was unchecked,
leading to rnum_start=-1 and world[-1]->unset_flag() SIGSEGV.
- graph.cpp: guard GetZoneRooms() failure with early return kBfsError
- do_stat.cpp: skip path-finding when mob is not in the world

Fix perslog path: ../log/perslog/ → log/perslog/ (logs are inside data dir)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In master, setup_logs() was called before chdir(), creating log/ and
log/perslog/ directories next to the binary (where autorun and other
production scripts expect them). Our branch swapped the order, moving
all log files inside the data directory.

Fix: pass the data dir path explicitly to runtime_config.load() so it
can read misc/configuration.xml without needing chdir() first, then
restore setup_logs() before chdir() as in master.

Also revert log path changes in logger.cpp:
- log/perslog/ → ../log/perslog/
- log/olc.log  → ../log/olc.log

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…torun

PORT defaults to 4000 but can be overridden with MUD_PORT.
FLAGS defaults to empty but can be overridden with MUD_FLAGS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bare & does not protect against SIGHUP on session close.
nohup ensures autorun survives terminal disconnect.
autorun.pid allows stopping the server with: kill $(cat autorun.pid)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Убраны захардкоженные PORT/FLAGS из autorun — дефолты (lib/, 4000)
уже определены в бинарнике. Вместо этого все аргументы пробрасываются
через "$@", что позволяет при необходимости передавать флаги и порт:

  ./launch -W 5555
  ./launch -d /path/to/world

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
По умолчанию build/circle, можно переопределить:
  MUD_BINARY=build_debug/circle ./launch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…UD_BINARY → CIRCLE

Запуск из произвольной директории:
  CIRCLE=./circle ../launch -d ../lib/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
setup_logs() теперь вызывается до chdir(), поэтому syslog создаётся
в рабочей директории бинарника. Запуск с 'cd $data_dir && binary -d .'
гарантирует, что syslog и log/ окажутся внутри data_dir, где их ожидает тест.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… PID

logger.cpp: mkdir("../log/perslog") перед первым открытием файла персонального лога.
setup_logs() создаёт log/ рядом с бинарником, но ../log/perslog/ может не
совпадать с этим местом (например, ./circle -d ../lib/ из build/).

run_load_tests.sh: заменить (cd && binary) & на (cd && exec binary) &,
чтобы $! захватывал PID бинарника, а не сабшелла. Без exec kill убивал
только сабшелл, оставляя сервер висеть на порту и ломая следующий тест.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Заменить все жёстко прописанные пути ../log/X.log на
runtime_config.log_dir() + "/X.log". setup_logs() теперь
вычисляет абсолютный путь к log/ через getcwd() до chdir()
и сохраняет в m_log_dir. Это устраняет проблему с perslog
и прочими логами, которые создавались не там при запуске
бинарника из произвольной директории.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Добавить fuser -k 4001/tcp перед запуском чтобы убить зависший
сервер от предыдущего запуска тестов. Добавить wait $server_pid
в обоих путях завершения — чтобы порт 4001 освобождался до
старта следующего теста.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bylins bylins merged commit c198f74 into master Feb 22, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants