Skip to content

feat: add lua_list_characters and lua_import_character - #8

Closed
mcagnion wants to merge 4 commits into
ianderse:mainfrom
mcagnion:feat/import-poe-character
Closed

mcagnion wants to merge 4 commits into
ianderse:mainfrom
mcagnion:feat/import-poe-character

Conversation

@mcagnion

Copy link
Copy Markdown
Contributor

Summary

Adds two new MCP tools that import a live PoE character into the loaded build via the official pathofexile.com/character-window/* API.

  • lua_list_characters — HTTP-only listing (no Lua bridge required). Sorted by lastLoginTime descending. Renders a markdown table with name / level / class / ascendancy / league / realm / last-login / pinnable.
  • lua_import_character — replaces the active spec's tree, jewels, items, and skill gems with the in-game state. Returns a before/after diff (stats, items per slot, skill groups, tree node count) so callers can verify the import. clear_* and ignore_weapon_swap flags are exposed for granular control.

The feature relies on JSON-RPC handlers added on the matching PoB branch — see ianderse/PathOfBuilding#1 (draft). Build notes, configuration, other tree specs, and other item sets are preserved across an import.

Notable design points

  • Architecture: HTTP fetches happen on the Node side (PoB headless has lcurl disabled), then JSON bodies are forwarded to Lua via the new import_passive_tree / import_items_skills JSON-RPC actions.
  • The bridge does NOT support concurrent requests; the handler captures pre/post-import snapshots sequentially. There is a regression test for this contract.
  • lua_list_characters is intentionally registered in the BASE tool schemas (not Lua-only) since it doesn't need the Lua bridge. A schema-guard test prevents duplicate registration.
  • HTTP client: 15s timeout via AbortController, 403/404/429 mapped to actionable error messages, POE_SESSION_ID env var supported for private profiles.
  • Partial-state handling: if import_items_skills fails after import_passive_tree succeeds, the user gets a clear "build is in a PARTIAL state — run lua_reload_build" message.

Tests

41 new tests, all green:

  • tests/unit/poeCharacterApi.test.ts (21) — fetch mocking, 403/404/429 mapping, header/auth/encoding, timeout via fake timers
  • tests/unit/importHandlers.test.ts (20) — full handler flow incl. the sequential-bridge-call regression test, all error paths, all flag forwarding
  • tests/unit/toolSchemas.test.ts (2) — schema guard for lua_list_characters placement and duplicates

Test plan

  • npm install && npm run build && npm test
  • Smoke test on a real character with default args (block / EHP / resists should match in-game)
  • Smoke test with ignore_weapon_swap=true (preserves swap config)
  • Verify private-profile flow with POE_SESSION_ID
  • PoB-side PR (Add character import API handlers PathOfBuilding#1) merged before this can run end-to-end against a vanilla api-stdio worktree

🤖 Generated with Claude Code

Bridge methods return res.item / res.skills, not res.result. The mock
fixture used result for both, which masked the type mismatch and hid
bugs from regression tests. Uncovered while writing tests for the new
character-import bridge methods.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mcagnion

Copy link
Copy Markdown
Contributor Author

Heads-up on the PoB-side dependency: companion PR (ianderse/PathOfBuilding#1) was originally targeted at api-stdio but has been retargeted at dev because api-stdio is stale (last upstream sync Nov 2025, missing 3.28 tree data). On a 3.28 build, lua_load_build would leave treeTab.specList empty and any subsequent import crashed at Classes/TreeTab.lua:499.

End-to-end smoke test on the rebased dev base passes — block 75% preserved on import, stats coherent with in-game character.

Anyone testing locally should point POB_FORK_PATH at a worktree based on the rebased feature/import-poe-character branch (or anything that includes recent PathOfBuildingCommunity/dev so the 3.28 tree data is present).

mcagnion and others added 2 commits April 25, 2026 16:06
…ntegration

Adds two new MCP tools that import a live PoE character into the loaded
build via the official PoE character-window API.

- lua_list_characters: HTTP-only listing (no Lua bridge required), sorted
  by lastLoginTime, displays class/ascendancy/league/realm/last login.
- lua_import_character: replaces the active spec's tree, jewels, items,
  and skill gems with the in-game state. Returns a before/after diff
  (stats, items per slot, skill groups, tree node count) so callers can
  verify the import result.

The feature works against the JSON-RPC handlers added on the matching
PoB branch (see ianderse/PathOfBuilding#1). Configuration, build notes,
other tree specs, and other item sets are preserved.

Includes 41 unit tests covering the HTTP client, the handler flow
(critical regression test for sequential bridge calls), and a schema
guard against duplicate tool registration. POE_SESSION_ID env var
documented for private profiles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The api-stdio branch was last synced with upstream on 2025-11-01 and is
missing tree data for league 3.27+. Using it crashes on lua_load_build
of any 3.28 build because TreeTab:Load early-returns on the unknown
tree version, leaving treeTab.specList empty. The active JSON-RPC API
work has migrated to ianderse/dev, which is kept in sync with
PathOfBuildingCommunity/dev (the head of upstream PR #9505).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mcagnion
mcagnion force-pushed the feat/import-poe-character branch from 8440b8d to 8663aac Compare April 25, 2026 14:06

@ianderse ianderse left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Node-side code type-checks, but this registers import_passive_tree and import_items_skills, neither of which is implemented or version-checked in this repository. The PR explicitly depends on a separate draft Path of Building PR, so a supported checkout can accept the MCP tool and then fail only after it has fetched data and begun a destructive import.

Please either land/pin the matching bridge implementation first, or add a bridge capability/version handshake that disables these tools until both actions are present. An end-to-end test against that pinned bridge should cover the partial-import failure path.

@ianderse

Copy link
Copy Markdown
Owner

Thank you for the serious work on character import, especially the attention to sequential bridge calls and partial-state handling. I am closing this PR rather than merging it because the project is moving toward vanilla PoB and this destructive import path still depends on a separate bridge implementation. Your contribution is acknowledged in the contributor list, and the design work remains valuable if we return to a safe, vanilla-compatible import flow.

@ianderse

Copy link
Copy Markdown
Owner

Closing this in favor of the vanilla-PoB direction and a future import flow with durable rollback semantics.

@ianderse ianderse closed this Jul 21, 2026
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