idlerpg.sh 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +171 -0
- package/dist/affix/AffixRegistry.d.ts +68 -0
- package/dist/affix/AffixRegistry.d.ts.map +1 -0
- package/dist/affix/AffixRegistry.js +245 -0
- package/dist/affix/AffixRegistry.js.map +1 -0
- package/dist/affix/PluginLoader.d.ts +66 -0
- package/dist/affix/PluginLoader.d.ts.map +1 -0
- package/dist/affix/PluginLoader.js +321 -0
- package/dist/affix/PluginLoader.js.map +1 -0
- package/dist/affix/builtin.d.ts +6 -0
- package/dist/affix/builtin.d.ts.map +1 -0
- package/dist/affix/builtin.js +311 -0
- package/dist/affix/builtin.js.map +1 -0
- package/dist/affix/index.d.ts +8 -0
- package/dist/affix/index.d.ts.map +1 -0
- package/dist/affix/index.js +11 -0
- package/dist/affix/index.js.map +1 -0
- package/dist/affix/types.d.ts +152 -0
- package/dist/affix/types.d.ts.map +1 -0
- package/dist/affix/types.js +8 -0
- package/dist/affix/types.js.map +1 -0
- package/dist/ai/PlayKitClient.d.ts +208 -0
- package/dist/ai/PlayKitClient.d.ts.map +1 -0
- package/dist/ai/PlayKitClient.js +721 -0
- package/dist/ai/PlayKitClient.js.map +1 -0
- package/dist/ai/index.d.ts +5 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +8 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/app/App.d.ts +85 -0
- package/dist/app/App.d.ts.map +1 -0
- package/dist/app/App.js +296 -0
- package/dist/app/App.js.map +1 -0
- package/dist/app/EventBus.d.ts +222 -0
- package/dist/app/EventBus.d.ts.map +1 -0
- package/dist/app/EventBus.js +88 -0
- package/dist/app/EventBus.js.map +1 -0
- package/dist/app/Keybind.d.ts +83 -0
- package/dist/app/Keybind.d.ts.map +1 -0
- package/dist/app/Keybind.js +184 -0
- package/dist/app/Keybind.js.map +1 -0
- package/dist/app/Router.d.ts +123 -0
- package/dist/app/Router.d.ts.map +1 -0
- package/dist/app/Router.js +142 -0
- package/dist/app/Router.js.map +1 -0
- package/dist/app/ScreenManager.d.ts +97 -0
- package/dist/app/ScreenManager.d.ts.map +1 -0
- package/dist/app/ScreenManager.js +216 -0
- package/dist/app/ScreenManager.js.map +1 -0
- package/dist/app/index.d.ts +14 -0
- package/dist/app/index.d.ts.map +1 -0
- package/dist/app/index.js +19 -0
- package/dist/app/index.js.map +1 -0
- package/dist/app/screens/BaseScreen.d.ts +101 -0
- package/dist/app/screens/BaseScreen.d.ts.map +1 -0
- package/dist/app/screens/BaseScreen.js +132 -0
- package/dist/app/screens/BaseScreen.js.map +1 -0
- package/dist/app/screens/CharacterCreationScreen.d.ts +42 -0
- package/dist/app/screens/CharacterCreationScreen.d.ts.map +1 -0
- package/dist/app/screens/CharacterCreationScreen.js +467 -0
- package/dist/app/screens/CharacterCreationScreen.js.map +1 -0
- package/dist/app/screens/CombatScreen.d.ts +30 -0
- package/dist/app/screens/CombatScreen.d.ts.map +1 -0
- package/dist/app/screens/CombatScreen.js +309 -0
- package/dist/app/screens/CombatScreen.js.map +1 -0
- package/dist/app/screens/DialogScreen.d.ts +29 -0
- package/dist/app/screens/DialogScreen.d.ts.map +1 -0
- package/dist/app/screens/DialogScreen.js +295 -0
- package/dist/app/screens/DialogScreen.js.map +1 -0
- package/dist/app/screens/ExploreScreen.d.ts +50 -0
- package/dist/app/screens/ExploreScreen.d.ts.map +1 -0
- package/dist/app/screens/ExploreScreen.js +308 -0
- package/dist/app/screens/ExploreScreen.js.map +1 -0
- package/dist/app/screens/HelpScreen.d.ts +12 -0
- package/dist/app/screens/HelpScreen.d.ts.map +1 -0
- package/dist/app/screens/HelpScreen.js +155 -0
- package/dist/app/screens/HelpScreen.js.map +1 -0
- package/dist/app/screens/InventoryScreen.d.ts +27 -0
- package/dist/app/screens/InventoryScreen.d.ts.map +1 -0
- package/dist/app/screens/InventoryScreen.js +326 -0
- package/dist/app/screens/InventoryScreen.js.map +1 -0
- package/dist/app/screens/PrologueScreen.d.ts +24 -0
- package/dist/app/screens/PrologueScreen.d.ts.map +1 -0
- package/dist/app/screens/PrologueScreen.js +176 -0
- package/dist/app/screens/PrologueScreen.js.map +1 -0
- package/dist/app/screens/TitleScreen.d.ts +42 -0
- package/dist/app/screens/TitleScreen.d.ts.map +1 -0
- package/dist/app/screens/TitleScreen.js +380 -0
- package/dist/app/screens/TitleScreen.js.map +1 -0
- package/dist/app/screens/TravelScreen.d.ts +22 -0
- package/dist/app/screens/TravelScreen.d.ts.map +1 -0
- package/dist/app/screens/TravelScreen.js +122 -0
- package/dist/app/screens/TravelScreen.js.map +1 -0
- package/dist/app/screens/index.d.ts +14 -0
- package/dist/app/screens/index.d.ts.map +1 -0
- package/dist/app/screens/index.js +17 -0
- package/dist/app/screens/index.js.map +1 -0
- package/dist/commands/CommandRegistry.d.ts +91 -0
- package/dist/commands/CommandRegistry.d.ts.map +1 -0
- package/dist/commands/CommandRegistry.js +159 -0
- package/dist/commands/CommandRegistry.js.map +1 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +10 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/core/Actor.d.ts +103 -0
- package/dist/core/Actor.d.ts.map +1 -0
- package/dist/core/Actor.js +409 -0
- package/dist/core/Actor.js.map +1 -0
- package/dist/core/Combat.d.ts +37 -0
- package/dist/core/Combat.d.ts.map +1 -0
- package/dist/core/Combat.js +294 -0
- package/dist/core/Combat.js.map +1 -0
- package/dist/core/DungeonRunner.d.ts +169 -0
- package/dist/core/DungeonRunner.d.ts.map +1 -0
- package/dist/core/DungeonRunner.js +627 -0
- package/dist/core/DungeonRunner.js.map +1 -0
- package/dist/core/Game.d.ts +133 -0
- package/dist/core/Game.d.ts.map +1 -0
- package/dist/core/Game.js +644 -0
- package/dist/core/Game.js.map +1 -0
- package/dist/core/IdleCombat.d.ts +61 -0
- package/dist/core/IdleCombat.d.ts.map +1 -0
- package/dist/core/IdleCombat.js +461 -0
- package/dist/core/IdleCombat.js.map +1 -0
- package/dist/core/IdleGameManager.d.ts +198 -0
- package/dist/core/IdleGameManager.d.ts.map +1 -0
- package/dist/core/IdleGameManager.js +688 -0
- package/dist/core/IdleGameManager.js.map +1 -0
- package/dist/core/IdleSaveManager.d.ts +109 -0
- package/dist/core/IdleSaveManager.d.ts.map +1 -0
- package/dist/core/IdleSaveManager.js +296 -0
- package/dist/core/IdleSaveManager.js.map +1 -0
- package/dist/core/NewGameFlowManager.d.ts +64 -0
- package/dist/core/NewGameFlowManager.d.ts.map +1 -0
- package/dist/core/NewGameFlowManager.js +153 -0
- package/dist/core/NewGameFlowManager.js.map +1 -0
- package/dist/core/Player.d.ts +65 -0
- package/dist/core/Player.d.ts.map +1 -0
- package/dist/core/Player.js +261 -0
- package/dist/core/Player.js.map +1 -0
- package/dist/core/RoomHandlers.d.ts +75 -0
- package/dist/core/RoomHandlers.d.ts.map +1 -0
- package/dist/core/RoomHandlers.js +383 -0
- package/dist/core/RoomHandlers.js.map +1 -0
- package/dist/core/SaveManager.d.ts +84 -0
- package/dist/core/SaveManager.d.ts.map +1 -0
- package/dist/core/SaveManager.js +281 -0
- package/dist/core/SaveManager.js.map +1 -0
- package/dist/core/SaveMigration.d.ts +69 -0
- package/dist/core/SaveMigration.d.ts.map +1 -0
- package/dist/core/SaveMigration.js +408 -0
- package/dist/core/SaveMigration.js.map +1 -0
- package/dist/core/StateAdapter.d.ts +79 -0
- package/dist/core/StateAdapter.d.ts.map +1 -0
- package/dist/core/StateAdapter.js +397 -0
- package/dist/core/StateAdapter.js.map +1 -0
- package/dist/core/Team.d.ts +145 -0
- package/dist/core/Team.d.ts.map +1 -0
- package/dist/core/Team.js +371 -0
- package/dist/core/Team.js.map +1 -0
- package/dist/core/TeamCombat.d.ts +88 -0
- package/dist/core/TeamCombat.d.ts.map +1 -0
- package/dist/core/TeamCombat.js +405 -0
- package/dist/core/TeamCombat.js.map +1 -0
- package/dist/core/TeamDungeonRunner.d.ts +186 -0
- package/dist/core/TeamDungeonRunner.d.ts.map +1 -0
- package/dist/core/TeamDungeonRunner.js +758 -0
- package/dist/core/TeamDungeonRunner.js.map +1 -0
- package/dist/core/TimeManager.d.ts +114 -0
- package/dist/core/TimeManager.d.ts.map +1 -0
- package/dist/core/TimeManager.js +318 -0
- package/dist/core/TimeManager.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +12 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/timeConstants.d.ts +135 -0
- package/dist/core/timeConstants.d.ts.map +1 -0
- package/dist/core/timeConstants.js +157 -0
- package/dist/core/timeConstants.js.map +1 -0
- package/dist/core/types.d.ts +780 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +16 -0
- package/dist/core/types.js.map +1 -0
- package/dist/data/continents/index.d.ts +163 -0
- package/dist/data/continents/index.d.ts.map +1 -0
- package/dist/data/continents/index.js +31 -0
- package/dist/data/continents/index.js.map +1 -0
- package/dist/data/continents/verdantia.d.ts +294 -0
- package/dist/data/continents/verdantia.d.ts.map +1 -0
- package/dist/data/continents/verdantia.js +327 -0
- package/dist/data/continents/verdantia.js.map +1 -0
- package/dist/handlers/DialogHandler.d.ts +95 -0
- package/dist/handlers/DialogHandler.d.ts.map +1 -0
- package/dist/handlers/DialogHandler.js +450 -0
- package/dist/handlers/DialogHandler.js.map +1 -0
- package/dist/handlers/SaveLoadHandler.d.ts +60 -0
- package/dist/handlers/SaveLoadHandler.d.ts.map +1 -0
- package/dist/handlers/SaveLoadHandler.js +187 -0
- package/dist/handlers/SaveLoadHandler.js.map +1 -0
- package/dist/handlers/TitleScreenHandler.d.ts +43 -0
- package/dist/handlers/TitleScreenHandler.d.ts.map +1 -0
- package/dist/handlers/TitleScreenHandler.js +508 -0
- package/dist/handlers/TitleScreenHandler.js.map +1 -0
- package/dist/handlers/WorkshopHandler.d.ts +75 -0
- package/dist/handlers/WorkshopHandler.d.ts.map +1 -0
- package/dist/handlers/WorkshopHandler.js +401 -0
- package/dist/handlers/WorkshopHandler.js.map +1 -0
- package/dist/handlers/index.d.ts +12 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +14 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/types.d.ts +34 -0
- package/dist/handlers/types.d.ts.map +1 -0
- package/dist/handlers/types.js +8 -0
- package/dist/handlers/types.js.map +1 -0
- package/dist/i18n/en.d.ts +3 -0
- package/dist/i18n/en.d.ts.map +1 -0
- package/dist/i18n/en.js +130 -0
- package/dist/i18n/en.js.map +1 -0
- package/dist/i18n/index.d.ts +40 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +105 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/types.d.ts +133 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +8 -0
- package/dist/i18n/types.js.map +1 -0
- package/dist/i18n/zh.d.ts +3 -0
- package/dist/i18n/zh.d.ts.map +1 -0
- package/dist/i18n/zh.js +130 -0
- package/dist/i18n/zh.js.map +1 -0
- package/dist/instrument.d.ts +8 -0
- package/dist/instrument.d.ts.map +1 -0
- package/dist/instrument.js +33 -0
- package/dist/instrument.js.map +1 -0
- package/dist/main-new.d.ts +12 -0
- package/dist/main-new.d.ts.map +1 -0
- package/dist/main-new.js +32 -0
- package/dist/main-new.js.map +1 -0
- package/dist/main.d.ts +7 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +2816 -0
- package/dist/main.js.map +1 -0
- package/dist/map/ContinentManager.d.ts +88 -0
- package/dist/map/ContinentManager.d.ts.map +1 -0
- package/dist/map/ContinentManager.js +241 -0
- package/dist/map/ContinentManager.js.map +1 -0
- package/dist/map/DungeonGenerator.d.ts +32 -0
- package/dist/map/DungeonGenerator.d.ts.map +1 -0
- package/dist/map/DungeonGenerator.js +615 -0
- package/dist/map/DungeonGenerator.js.map +1 -0
- package/dist/map/MapGenerator.d.ts +27 -0
- package/dist/map/MapGenerator.d.ts.map +1 -0
- package/dist/map/MapGenerator.js +485 -0
- package/dist/map/MapGenerator.js.map +1 -0
- package/dist/map/index.d.ts +5 -0
- package/dist/map/index.d.ts.map +1 -0
- package/dist/map/index.js +8 -0
- package/dist/map/index.js.map +1 -0
- package/dist/npc/NPCGenerator.d.ts +68 -0
- package/dist/npc/NPCGenerator.d.ts.map +1 -0
- package/dist/npc/NPCGenerator.js +468 -0
- package/dist/npc/NPCGenerator.js.map +1 -0
- package/dist/npc/NPCManager.d.ts +86 -0
- package/dist/npc/NPCManager.d.ts.map +1 -0
- package/dist/npc/NPCManager.js +217 -0
- package/dist/npc/NPCManager.js.map +1 -0
- package/dist/npc/fixedNPCs.d.ts +7 -0
- package/dist/npc/fixedNPCs.d.ts.map +1 -0
- package/dist/npc/fixedNPCs.js +196 -0
- package/dist/npc/fixedNPCs.js.map +1 -0
- package/dist/npc/index.d.ts +9 -0
- package/dist/npc/index.d.ts.map +1 -0
- package/dist/npc/index.js +12 -0
- package/dist/npc/index.js.map +1 -0
- package/dist/npc/traits.d.ts +33 -0
- package/dist/npc/traits.d.ts.map +1 -0
- package/dist/npc/traits.js +795 -0
- package/dist/npc/traits.js.map +1 -0
- package/dist/npc/types.d.ts +193 -0
- package/dist/npc/types.d.ts.map +1 -0
- package/dist/npc/types.js +9 -0
- package/dist/npc/types.js.map +1 -0
- package/dist/quest/QuestManager.d.ts +79 -0
- package/dist/quest/QuestManager.d.ts.map +1 -0
- package/dist/quest/QuestManager.js +273 -0
- package/dist/quest/QuestManager.js.map +1 -0
- package/dist/quest/index.d.ts +6 -0
- package/dist/quest/index.d.ts.map +1 -0
- package/dist/quest/index.js +9 -0
- package/dist/quest/index.js.map +1 -0
- package/dist/quest/types.d.ts +81 -0
- package/dist/quest/types.d.ts.map +1 -0
- package/dist/quest/types.js +8 -0
- package/dist/quest/types.js.map +1 -0
- package/dist/strategy/StrategyExecutor.d.ts +159 -0
- package/dist/strategy/StrategyExecutor.d.ts.map +1 -0
- package/dist/strategy/StrategyExecutor.js +479 -0
- package/dist/strategy/StrategyExecutor.js.map +1 -0
- package/dist/strategy/StrategyParser.d.ts +48 -0
- package/dist/strategy/StrategyParser.d.ts.map +1 -0
- package/dist/strategy/StrategyParser.js +321 -0
- package/dist/strategy/StrategyParser.js.map +1 -0
- package/dist/strategy/defaultStrategy.d.ts +40 -0
- package/dist/strategy/defaultStrategy.d.ts.map +1 -0
- package/dist/strategy/defaultStrategy.js +254 -0
- package/dist/strategy/defaultStrategy.js.map +1 -0
- package/dist/strategy/index.d.ts +8 -0
- package/dist/strategy/index.d.ts.map +1 -0
- package/dist/strategy/index.js +14 -0
- package/dist/strategy/index.js.map +1 -0
- package/dist/tui/ExploreMenu.d.ts +106 -0
- package/dist/tui/ExploreMenu.d.ts.map +1 -0
- package/dist/tui/ExploreMenu.js +282 -0
- package/dist/tui/ExploreMenu.js.map +1 -0
- package/dist/tui/GameUI.d.ts +313 -0
- package/dist/tui/GameUI.d.ts.map +1 -0
- package/dist/tui/GameUI.js +2116 -0
- package/dist/tui/GameUI.js.map +1 -0
- package/dist/tui/GameUIAdapter.d.ts +207 -0
- package/dist/tui/GameUIAdapter.d.ts.map +1 -0
- package/dist/tui/GameUIAdapter.js +1342 -0
- package/dist/tui/GameUIAdapter.js.map +1 -0
- package/dist/tui/Input.d.ts +139 -0
- package/dist/tui/Input.d.ts.map +1 -0
- package/dist/tui/Input.js +278 -0
- package/dist/tui/Input.js.map +1 -0
- package/dist/tui/Menu.d.ts +110 -0
- package/dist/tui/Menu.d.ts.map +1 -0
- package/dist/tui/Menu.js +365 -0
- package/dist/tui/Menu.js.map +1 -0
- package/dist/tui/Screen.d.ts +228 -0
- package/dist/tui/Screen.d.ts.map +1 -0
- package/dist/tui/Screen.js +502 -0
- package/dist/tui/Screen.js.map +1 -0
- package/dist/tui/components/Box.d.ts +36 -0
- package/dist/tui/components/Box.d.ts.map +1 -0
- package/dist/tui/components/Box.js +43 -0
- package/dist/tui/components/Box.js.map +1 -0
- package/dist/tui/components/List.d.ts +69 -0
- package/dist/tui/components/List.d.ts.map +1 -0
- package/dist/tui/components/List.js +136 -0
- package/dist/tui/components/List.js.map +1 -0
- package/dist/tui/components/ProgressBar.d.ts +42 -0
- package/dist/tui/components/ProgressBar.d.ts.map +1 -0
- package/dist/tui/components/ProgressBar.js +75 -0
- package/dist/tui/components/ProgressBar.js.map +1 -0
- package/dist/tui/components/index.d.ts +8 -0
- package/dist/tui/components/index.d.ts.map +1 -0
- package/dist/tui/components/index.js +11 -0
- package/dist/tui/components/index.js.map +1 -0
- package/dist/tui/core/BaseSection.d.ts +98 -0
- package/dist/tui/core/BaseSection.d.ts.map +1 -0
- package/dist/tui/core/BaseSection.js +174 -0
- package/dist/tui/core/BaseSection.js.map +1 -0
- package/dist/tui/core/Component.d.ts +61 -0
- package/dist/tui/core/Component.d.ts.map +1 -0
- package/dist/tui/core/Component.js +32 -0
- package/dist/tui/core/Component.js.map +1 -0
- package/dist/tui/core/Section.d.ts +101 -0
- package/dist/tui/core/Section.d.ts.map +1 -0
- package/dist/tui/core/Section.js +24 -0
- package/dist/tui/core/Section.js.map +1 -0
- package/dist/tui/core/SectionManager.d.ts +108 -0
- package/dist/tui/core/SectionManager.d.ts.map +1 -0
- package/dist/tui/core/SectionManager.js +258 -0
- package/dist/tui/core/SectionManager.js.map +1 -0
- package/dist/tui/core/index.d.ts +9 -0
- package/dist/tui/core/index.d.ts.map +1 -0
- package/dist/tui/core/index.js +12 -0
- package/dist/tui/core/index.js.map +1 -0
- package/dist/tui/index.d.ts +15 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +23 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/screens/BaseScreen.d.ts +62 -0
- package/dist/tui/screens/BaseScreen.d.ts.map +1 -0
- package/dist/tui/screens/BaseScreen.js +55 -0
- package/dist/tui/screens/BaseScreen.js.map +1 -0
- package/dist/tui/screens/CombatScreen.d.ts +43 -0
- package/dist/tui/screens/CombatScreen.d.ts.map +1 -0
- package/dist/tui/screens/CombatScreen.js +125 -0
- package/dist/tui/screens/CombatScreen.js.map +1 -0
- package/dist/tui/screens/DialogScreen.d.ts +53 -0
- package/dist/tui/screens/DialogScreen.d.ts.map +1 -0
- package/dist/tui/screens/DialogScreen.js +90 -0
- package/dist/tui/screens/DialogScreen.js.map +1 -0
- package/dist/tui/screens/DungeonScreen.d.ts +80 -0
- package/dist/tui/screens/DungeonScreen.d.ts.map +1 -0
- package/dist/tui/screens/DungeonScreen.js +317 -0
- package/dist/tui/screens/DungeonScreen.js.map +1 -0
- package/dist/tui/screens/ExploreScreen.d.ts +69 -0
- package/dist/tui/screens/ExploreScreen.d.ts.map +1 -0
- package/dist/tui/screens/ExploreScreen.js +224 -0
- package/dist/tui/screens/ExploreScreen.js.map +1 -0
- package/dist/tui/screens/SectionScreen.d.ts +84 -0
- package/dist/tui/screens/SectionScreen.d.ts.map +1 -0
- package/dist/tui/screens/SectionScreen.js +156 -0
- package/dist/tui/screens/SectionScreen.js.map +1 -0
- package/dist/tui/screens/TitleScreen.d.ts +40 -0
- package/dist/tui/screens/TitleScreen.d.ts.map +1 -0
- package/dist/tui/screens/TitleScreen.js +253 -0
- package/dist/tui/screens/TitleScreen.js.map +1 -0
- package/dist/tui/screens/TownScreen.d.ts +98 -0
- package/dist/tui/screens/TownScreen.d.ts.map +1 -0
- package/dist/tui/screens/TownScreen.js +370 -0
- package/dist/tui/screens/TownScreen.js.map +1 -0
- package/dist/tui/screens/TravelScreen.d.ts +67 -0
- package/dist/tui/screens/TravelScreen.d.ts.map +1 -0
- package/dist/tui/screens/TravelScreen.js +286 -0
- package/dist/tui/screens/TravelScreen.js.map +1 -0
- package/dist/tui/screens/index.d.ts +8 -0
- package/dist/tui/screens/index.d.ts.map +1 -0
- package/dist/tui/screens/index.js +17 -0
- package/dist/tui/screens/index.js.map +1 -0
- package/dist/tui/sections/ActionsSection.d.ts +71 -0
- package/dist/tui/sections/ActionsSection.d.ts.map +1 -0
- package/dist/tui/sections/ActionsSection.js +184 -0
- package/dist/tui/sections/ActionsSection.js.map +1 -0
- package/dist/tui/sections/DungeonSection.d.ts +65 -0
- package/dist/tui/sections/DungeonSection.d.ts.map +1 -0
- package/dist/tui/sections/DungeonSection.js +144 -0
- package/dist/tui/sections/DungeonSection.js.map +1 -0
- package/dist/tui/sections/EventsSection.d.ts +50 -0
- package/dist/tui/sections/EventsSection.d.ts.map +1 -0
- package/dist/tui/sections/EventsSection.js +134 -0
- package/dist/tui/sections/EventsSection.js.map +1 -0
- package/dist/tui/sections/MapSection.d.ts +66 -0
- package/dist/tui/sections/MapSection.d.ts.map +1 -0
- package/dist/tui/sections/MapSection.js +669 -0
- package/dist/tui/sections/MapSection.js.map +1 -0
- package/dist/tui/sections/StatusSection.d.ts +47 -0
- package/dist/tui/sections/StatusSection.d.ts.map +1 -0
- package/dist/tui/sections/StatusSection.js +133 -0
- package/dist/tui/sections/StatusSection.js.map +1 -0
- package/dist/tui/sections/TeamSection.d.ts +71 -0
- package/dist/tui/sections/TeamSection.d.ts.map +1 -0
- package/dist/tui/sections/TeamSection.js +224 -0
- package/dist/tui/sections/TeamSection.js.map +1 -0
- package/dist/tui/sections/TravelingSection.d.ts +51 -0
- package/dist/tui/sections/TravelingSection.d.ts.map +1 -0
- package/dist/tui/sections/TravelingSection.js +106 -0
- package/dist/tui/sections/TravelingSection.js.map +1 -0
- package/dist/tui/sections/index.d.ts +9 -0
- package/dist/tui/sections/index.d.ts.map +1 -0
- package/dist/tui/sections/index.js +12 -0
- package/dist/tui/sections/index.js.map +1 -0
- package/dist/ui/Terminal.d.ts +68 -0
- package/dist/ui/Terminal.d.ts.map +1 -0
- package/dist/ui/Terminal.js +297 -0
- package/dist/ui/Terminal.js.map +1 -0
- package/dist/ui/index.d.ts +5 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +8 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/utils/configMigration.d.ts +14 -0
- package/dist/utils/configMigration.d.ts.map +1 -0
- package/dist/utils/configMigration.js +92 -0
- package/dist/utils/configMigration.js.map +1 -0
- package/dist/utils/errorHandler.d.ts +86 -0
- package/dist/utils/errorHandler.d.ts.map +1 -0
- package/dist/utils/errorHandler.js +224 -0
- package/dist/utils/errorHandler.js.map +1 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +43 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/weapon/WeaponFactory.d.ts +32 -0
- package/dist/weapon/WeaponFactory.d.ts.map +1 -0
- package/dist/weapon/WeaponFactory.js +216 -0
- package/dist/weapon/WeaponFactory.js.map +1 -0
- package/dist/weapon/index.d.ts +5 -0
- package/dist/weapon/index.d.ts.map +1 -0
- package/dist/weapon/index.js +8 -0
- package/dist/weapon/index.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Terminal.js","sources":["ui/Terminal.ts"],"sourceRoot":"/","sourcesContent":["/**\r\n * Terminal UI rendering utilities\r\n */\r\n\r\nimport { getStrings, t } from '../i18n/index.js';\r\nimport type { GameState, Player, Room, CombatState } from '../core/types.js';\r\n\r\n// ANSI color codes\r\nconst COLORS = {\r\n reset: '\\x1b[0m',\r\n bold: '\\x1b[1m',\r\n dim: '\\x1b[2m',\r\n \r\n // Foreground\r\n black: '\\x1b[30m',\r\n red: '\\x1b[31m',\r\n green: '\\x1b[32m',\r\n yellow: '\\x1b[33m',\r\n blue: '\\x1b[34m',\r\n magenta: '\\x1b[35m',\r\n cyan: '\\x1b[36m',\r\n white: '\\x1b[37m',\r\n \r\n // Background\r\n bgBlack: '\\x1b[40m',\r\n bgRed: '\\x1b[41m',\r\n bgGreen: '\\x1b[42m',\r\n bgYellow: '\\x1b[43m',\r\n bgBlue: '\\x1b[44m',\r\n bgMagenta: '\\x1b[45m',\r\n bgCyan: '\\x1b[46m',\r\n bgWhite: '\\x1b[47m',\r\n};\r\n\r\n/**\r\n * Apply color to text\r\n */\r\nexport function color(text: string, ...codes: string[]): string {\r\n return codes.join('') + text + COLORS.reset;\r\n}\r\n\r\n/**\r\n * Clear the terminal screen\r\n */\r\nexport function clearScreen(): void {\r\n process.stdout.write('\\x1Bc');\r\n}\r\n\r\n/**\r\n * Move cursor to position\r\n */\r\nexport function moveCursor(row: number, col: number): void {\r\n process.stdout.write(`\\x1b[${row};${col}H`);\r\n}\r\n\r\n/**\r\n * Hide cursor\r\n */\r\nexport function hideCursor(): void {\r\n process.stdout.write('\\x1b[?25l');\r\n}\r\n\r\n/**\r\n * Show cursor\r\n */\r\nexport function showCursor(): void {\r\n process.stdout.write('\\x1b[?25h');\r\n}\r\n\r\n/**\r\n * Draw a box with content\r\n */\r\nexport function drawBox(\r\n title: string,\r\n content: string[],\r\n width: number = 40\r\n): string[] {\r\n const lines: string[] = [];\r\n const innerWidth = width - 4;\r\n\r\n // Top border with title\r\n const titleStr = title ? `─ ${title} ` : '';\r\n lines.push('┌' + titleStr + '─'.repeat(width - 2 - titleStr.length) + '┐');\r\n\r\n // Content\r\n for (const line of content) {\r\n const trimmed = line.slice(0, innerWidth);\r\n lines.push('│ ' + trimmed.padEnd(innerWidth) + ' │');\r\n }\r\n\r\n // Bottom border\r\n lines.push('└' + '─'.repeat(width - 2) + '┘');\r\n\r\n return lines;\r\n}\r\n\r\n/**\r\n * Draw a progress bar\r\n */\r\nexport function progressBar(\r\n current: number,\r\n max: number,\r\n width: number = 20,\r\n filled: string = '█',\r\n empty: string = '░'\r\n): string {\r\n const ratio = Math.max(0, Math.min(1, current / max));\r\n const filledCount = Math.floor(ratio * width);\r\n const emptyCount = width - filledCount;\r\n\r\n return filled.repeat(filledCount) + empty.repeat(emptyCount);\r\n}\r\n\r\n/**\r\n * Format time in mm:ss\r\n */\r\nexport function formatTime(seconds: number): string {\r\n const mins = Math.floor(seconds / 60);\r\n const secs = Math.floor(seconds % 60);\r\n return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;\r\n}\r\n\r\n/**\r\n * Render the main game UI\r\n */\r\nexport function renderMainUI(state: GameState): string[] {\r\n const lines: string[] = [];\r\n const s = getStrings();\r\n const width = 70;\r\n\r\n // Header\r\n lines.push('╔' + '═'.repeat(width - 2) + '╗');\r\n lines.push('║ ' + color(s.game.title, COLORS.bold, COLORS.cyan) + \r\n ' │ ' + `${s.status.level}.${state.player.stats.level} ${state.player.name}` +\r\n ' │ ' + `${s.status.hp}:${state.player.stats.hp}/${state.player.stats.maxHp}` +\r\n ' │ ⏰ ' + new Date().toLocaleTimeString().padEnd(width - 60) + '║');\r\n lines.push('╠' + '═'.repeat(width - 2) + '╣');\r\n\r\n // Map section (left) and Status section (right)\r\n const mapLines = renderMiniMap(state);\r\n const statusLines = renderStatus(state);\r\n\r\n lines.push('║' + ' '.repeat(width - 2) + '║');\r\n \r\n const maxLines = Math.max(mapLines.length, statusLines.length);\r\n for (let i = 0; i < maxLines; i++) {\r\n const mapPart = (mapLines[i] || '').padEnd(35);\r\n const statusPart = (statusLines[i] || '').padEnd(30);\r\n lines.push('║ ' + mapPart + ' ' + statusPart + ' ║');\r\n }\r\n\r\n lines.push('║' + ' '.repeat(width - 2) + '║');\r\n\r\n // Event log\r\n lines.push('║ ┌─── Event Log ' + '─'.repeat(width - 21) + '┐ ║');\r\n const eventLines = renderEventLog(state);\r\n for (const event of eventLines.slice(-5)) {\r\n lines.push('║ │ ' + event.padEnd(width - 8) + ' │ ║');\r\n }\r\n lines.push('║ └' + '─'.repeat(width - 6) + '┘ ║');\r\n\r\n lines.push('║' + ' '.repeat(width - 2) + '║');\r\n\r\n // Controls\r\n const controls = '[M]ap [I]nventory [C]haracter [Q]uests [W]orkshop [N]PC [H]elp';\r\n lines.push('║ ' + controls.padEnd(width - 4) + '║');\r\n \r\n lines.push('╚' + '═'.repeat(width - 2) + '╝');\r\n\r\n return lines;\r\n}\r\n\r\n/**\r\n * Render mini map\r\n */\r\nexport function renderMiniMap(state: GameState): string[] {\r\n const lines: string[] = [];\r\n const s = getStrings();\r\n\r\n lines.push('┌─── ' + s.ui.map + ' ───────────────────┐');\r\n lines.push('│ │');\r\n lines.push('│ [?]━━━[T]━━━[?] │');\r\n lines.push('│ │ │ │');\r\n \r\n // Current room indicator\r\n const currentSymbol = state.currentRoom.type === 'town' ? '[T]' : '[@]';\r\n lines.push('│ [D]━━━' + currentSymbol + '━━━[!] │');\r\n lines.push('│ │ ↑ │ │');\r\n lines.push('│ [S]━━━[·]━━━[B] │');\r\n lines.push('│ │');\r\n lines.push('│ [@]' + s.map.player + ' [T]' + s.map.town + ' [D]' + s.map.dungeon + ' │');\r\n lines.push('│ [S]' + s.map.shop + ' [B]' + s.map.boss + ' [?]' + s.map.unexplored + ' │');\r\n lines.push('└────────────────────────────────┘');\r\n\r\n return lines;\r\n}\r\n\r\n/**\r\n * Render status panel\r\n */\r\nexport function renderStatus(state: GameState): string[] {\r\n const lines: string[] = [];\r\n const p = state.player;\r\n const s = getStrings();\r\n\r\n lines.push('┌─── Status ────────────┐');\r\n lines.push('│ │');\r\n lines.push('│ ' + s.status.location + ': ' + state.currentRoom.name.slice(0, 14).padEnd(14) + ' │');\r\n \r\n if (state.player.activeQuests.length > 0) {\r\n const quest = state.player.activeQuests[0];\r\n lines.push('│ ' + s.status.quest + ': ' + quest.name.slice(0, 14).padEnd(14) + ' │');\r\n lines.push('│ ' + s.status.progress + ': ' + progressBar(50, 100, 12) + ' │');\r\n } else {\r\n lines.push('│ ' + s.status.quest + ': None'.padEnd(20) + ' │');\r\n lines.push('│ │');\r\n }\r\n\r\n lines.push('│ │');\r\n lines.push('│ ' + s.status.equipment + ': │');\r\n \r\n if (p.equipment.weapon) {\r\n lines.push('│ ' + p.equipment.weapon.name.slice(0, 18).padEnd(18) + ' │');\r\n } else {\r\n lines.push('│ (none)'.padEnd(24) + ' │');\r\n }\r\n\r\n lines.push('│ │');\r\n lines.push('│ ' + s.status.gold + ': ' + p.stats.gold.toString().padEnd(16) + ' │');\r\n lines.push('└────────────────────────┘');\r\n\r\n return lines;\r\n}\r\n\r\n/**\r\n * Render event log\r\n */\r\nexport function renderEventLog(state: GameState): string[] {\r\n const logs: string[] = [];\r\n const time = new Date().toLocaleTimeString().slice(0, 5);\r\n\r\n // Always show current location\r\n logs.push(`[${time}] Location: ${state.currentRoom.name}`);\r\n\r\n // Show pending events\r\n for (const event of state.pendingEvents.slice(-4)) {\r\n const eventTime = new Date(event.timestamp).toLocaleTimeString().slice(0, 5);\r\n logs.push(`[${eventTime}] ${event.title}: ${event.description.slice(0, 40)}...`);\r\n }\r\n\r\n // Show phase-specific info\r\n if (state.phase === 'traveling' && state.travelState) {\r\n const progress = Math.floor(state.travelState.progress * 100);\r\n logs.push(`[${time}] Traveling... ${progress}% complete`);\r\n }\r\n\r\n if (state.phase === 'combat' && state.combat) {\r\n const enemyInfo = state.combat.enemies\r\n .filter(e => e.hp > 0)\r\n .map(e => `${e.name}(${e.hp}HP)`)\r\n .join(', ');\r\n logs.push(`[${time}] Fighting: ${enemyInfo}`);\r\n }\r\n\r\n // Show active quest progress\r\n if (state.player.activeQuests.length > 0) {\r\n const quest = state.player.activeQuests[0];\r\n const completed = quest.objectives.filter(o => o.isComplete).length;\r\n const total = quest.objectives.length;\r\n logs.push(`[${time}] Quest \"${quest.name}\": ${completed}/${total} objectives`);\r\n }\r\n\r\n // Fill remaining slots with room description if needed\r\n if (logs.length < 3) {\r\n logs.push(`[${time}] ${state.currentRoom.description}`);\r\n }\r\n\r\n return logs.slice(0, 5);\r\n}\r\n\r\n/**\r\n * Render combat UI\r\n */\r\nexport function renderCombatUI(combat: CombatState, player: Player): string[] {\r\n const lines: string[] = [];\r\n const s = getStrings();\r\n const width = 60;\r\n\r\n lines.push('┌─ Combat ' + '─'.repeat(width - 11) + '┐');\r\n lines.push('│' + ' '.repeat(width - 2) + '│');\r\n\r\n // Player HP bar\r\n const playerHpBar = progressBar(combat.playerHp, player.stats.maxHp, 20);\r\n lines.push(`│ [${player.name}] HP: ${playerHpBar} ${combat.playerHp}/${player.stats.maxHp}`.padEnd(width - 1) + '│');\r\n\r\n lines.push('│' + ' '.repeat(width - 2) + '│');\r\n\r\n // Enemy HP bars\r\n for (const enemy of combat.enemies) {\r\n const enemyHpBar = progressBar(enemy.hp, enemy.maxHp, 15);\r\n const status = enemy.hp <= 0 ? color('DEFEATED', COLORS.dim) : '';\r\n lines.push(`│ vs [${enemy.name}] HP: ${enemyHpBar} ${enemy.hp}/${enemy.maxHp} ${status}`.padEnd(width - 1) + '│');\r\n }\r\n\r\n lines.push('│' + ' '.repeat(width - 2) + '│');\r\n\r\n // Combat log\r\n lines.push('│ ─── Battle Log ───'.padEnd(width - 1) + '│');\r\n for (const entry of combat.log.slice(-5)) {\r\n lines.push('│ > ' + entry.message.slice(0, width - 8).padEnd(width - 6) + '│');\r\n }\r\n\r\n lines.push('│' + ' '.repeat(width - 2) + '│');\r\n\r\n // Strategy options\r\n lines.push('│ Strategy: [1]Aggressive [2]Defensive [3]Balanced [4]Skills'.padEnd(width - 1) + '│');\r\n lines.push('│ Current: ' + combat.strategy.padEnd(width - 13) + '│');\r\n\r\n lines.push('└' + '─'.repeat(width - 2) + '┘');\r\n\r\n return lines;\r\n}\r\n\r\n/**\r\n * Render NPC dialog UI\r\n */\r\nexport function renderDialogUI(\r\n npcName: string,\r\n history: Array<{ role: string; content: string }>,\r\n isStreaming: boolean\r\n): string[] {\r\n const lines: string[] = [];\r\n const s = getStrings();\r\n const width = 70;\r\n\r\n lines.push('╔' + '═'.repeat(width - 2) + '╗');\r\n lines.push('║ ◈ ' + s.npc.talkTo + ' [' + npcName + ']' + ' '.repeat(width - 20 - npcName.length) + '║');\r\n lines.push('╠' + '═'.repeat(width - 2) + '╣');\r\n\r\n lines.push('║' + ' '.repeat(width - 2) + '║');\r\n\r\n // Dialog history\r\n for (const entry of history.slice(-6)) {\r\n const prefix = entry.role === 'player' ? '[You] ' : `[${npcName}] `;\r\n const text = prefix + entry.content;\r\n \r\n // Word wrap\r\n const maxLen = width - 6;\r\n for (let i = 0; i < text.length; i += maxLen) {\r\n const line = text.slice(i, i + maxLen);\r\n lines.push('║ ' + line.padEnd(width - 4) + '║');\r\n }\r\n lines.push('║' + ' '.repeat(width - 2) + '║');\r\n }\r\n\r\n if (isStreaming) {\r\n lines.push('║ ' + color('▌' + s.npc.waitingForResponse, COLORS.dim).padEnd(width - 4) + '║');\r\n }\r\n\r\n lines.push('║' + ' '.repeat(width - 2) + '║');\r\n lines.push('║ ' + 'Your response: _'.padEnd(width - 4) + '║');\r\n lines.push('║' + ' '.repeat(width - 2) + '║');\r\n\r\n lines.push('╚' + '═'.repeat(width - 2) + '╝');\r\n\r\n return lines;\r\n}\r\n\r\n/**\r\n * Print lines to terminal\r\n */\r\nexport function render(lines: string[]): void {\r\n console.log(lines.join('\\n'));\r\n}\r\n"],"names":[],"mappings":"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","debug_id":"db6c6406-9f88-5f5d-a139-9a49d9ec32ba"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"/","sources":["ui/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,eAAe,CAAC"}
|
package/dist/ui/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI module exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5e03b10b-c07f-50d0-81e7-c2eef6fa205b")}catch(e){}}();
|
|
6
|
+
export * from './Terminal.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
8
|
+
//# debugId=5e03b10b-c07f-50d0-81e7-c2eef6fa205b
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["ui/index.ts"],"sourceRoot":"/","sourcesContent":["/**\r\n * UI module exports\r\n */\r\n\r\nexport * from './Terminal.js';\r\n"],"names":[],"mappings":"AAAA;;GAEG;;;AAEH,cAAc,eAAe,CAAC","debug_id":"5e03b10b-c07f-50d0-81e7-c2eef6fa205b"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Migration Utility
|
|
3
|
+
* Handles migration from old config directory (~/.roguelike-terminal) to new (~/.idlerpg-terminal)
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Check if migration is needed and perform it
|
|
7
|
+
* Returns true if migration was performed, false otherwise
|
|
8
|
+
*/
|
|
9
|
+
export declare function migrateConfigDirectory(): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Get the config directory path (with auto-migration)
|
|
12
|
+
*/
|
|
13
|
+
export declare function getConfigDir(): string;
|
|
14
|
+
//# sourceMappingURL=configMigration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configMigration.d.ts","sourceRoot":"/","sources":["utils/configMigration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAgChD;AAuCD;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAUrC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Migration Utility
|
|
3
|
+
* Handles migration from old config directory (~/.roguelike-terminal) to new (~/.idlerpg-terminal)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9cc7a756-b82f-591d-aae4-7b2e0ea3136a")}catch(e){}}();
|
|
7
|
+
import { existsSync, mkdirSync, readdirSync, copyFileSync, unlinkSync, rmdirSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { homedir } from 'os';
|
|
10
|
+
import { Sentry } from '../instrument.js';
|
|
11
|
+
const OLD_CONFIG_DIR = join(homedir(), '.roguelike-terminal');
|
|
12
|
+
const NEW_CONFIG_DIR = join(homedir(), '.idlerpg-terminal');
|
|
13
|
+
/**
|
|
14
|
+
* Check if migration is needed and perform it
|
|
15
|
+
* Returns true if migration was performed, false otherwise
|
|
16
|
+
*/
|
|
17
|
+
export function migrateConfigDirectory() {
|
|
18
|
+
// Check if old directory exists and new one doesn't
|
|
19
|
+
if (!existsSync(OLD_CONFIG_DIR)) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
// If new directory already exists, skip migration
|
|
23
|
+
if (existsSync(NEW_CONFIG_DIR)) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
// Create new directory
|
|
28
|
+
mkdirSync(NEW_CONFIG_DIR, { recursive: true });
|
|
29
|
+
// Copy all files and subdirectories
|
|
30
|
+
copyDirectoryRecursive(OLD_CONFIG_DIR, NEW_CONFIG_DIR);
|
|
31
|
+
// Remove old directory after successful copy
|
|
32
|
+
removeDirectoryRecursive(OLD_CONFIG_DIR);
|
|
33
|
+
console.log('[Migration] Successfully migrated config from .roguelike-terminal to .idlerpg-terminal');
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.error('[Migration] Failed to migrate config directory:', error);
|
|
38
|
+
// Report migration failure to Sentry
|
|
39
|
+
Sentry.captureException(error, {
|
|
40
|
+
tags: { operation: 'config_migration', fallback: true },
|
|
41
|
+
extra: { oldDir: OLD_CONFIG_DIR, newDir: NEW_CONFIG_DIR },
|
|
42
|
+
});
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Recursively copy a directory
|
|
48
|
+
*/
|
|
49
|
+
function copyDirectoryRecursive(src, dest) {
|
|
50
|
+
const entries = readdirSync(src, { withFileTypes: true });
|
|
51
|
+
for (const entry of entries) {
|
|
52
|
+
const srcPath = join(src, entry.name);
|
|
53
|
+
const destPath = join(dest, entry.name);
|
|
54
|
+
if (entry.isDirectory()) {
|
|
55
|
+
mkdirSync(destPath, { recursive: true });
|
|
56
|
+
copyDirectoryRecursive(srcPath, destPath);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
copyFileSync(srcPath, destPath);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Recursively remove a directory
|
|
65
|
+
*/
|
|
66
|
+
function removeDirectoryRecursive(dir) {
|
|
67
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
68
|
+
for (const entry of entries) {
|
|
69
|
+
const fullPath = join(dir, entry.name);
|
|
70
|
+
if (entry.isDirectory()) {
|
|
71
|
+
removeDirectoryRecursive(fullPath);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
unlinkSync(fullPath);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
rmdirSync(dir);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get the config directory path (with auto-migration)
|
|
81
|
+
*/
|
|
82
|
+
export function getConfigDir() {
|
|
83
|
+
// Run migration check
|
|
84
|
+
migrateConfigDirectory();
|
|
85
|
+
// Ensure new directory exists
|
|
86
|
+
if (!existsSync(NEW_CONFIG_DIR)) {
|
|
87
|
+
mkdirSync(NEW_CONFIG_DIR, { recursive: true });
|
|
88
|
+
}
|
|
89
|
+
return NEW_CONFIG_DIR;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=configMigration.js.map
|
|
92
|
+
//# debugId=9cc7a756-b82f-591d-aae4-7b2e0ea3136a
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configMigration.js","sources":["utils/configMigration.ts"],"sourceRoot":"/","sourcesContent":["/**\r\n * Config Migration Utility\r\n * Handles migration from old config directory (~/.roguelike-terminal) to new (~/.idlerpg-terminal)\r\n */\r\n\r\nimport { existsSync, mkdirSync, readdirSync, copyFileSync, statSync, unlinkSync, rmdirSync } from 'fs';\r\nimport { join } from 'path';\r\nimport { homedir } from 'os';\r\nimport { Sentry } from '../instrument.js';\r\n\r\nconst OLD_CONFIG_DIR = join(homedir(), '.roguelike-terminal');\r\nconst NEW_CONFIG_DIR = join(homedir(), '.idlerpg-terminal');\r\n\r\n/**\r\n * Check if migration is needed and perform it\r\n * Returns true if migration was performed, false otherwise\r\n */\r\nexport function migrateConfigDirectory(): boolean {\r\n // Check if old directory exists and new one doesn't\r\n if (!existsSync(OLD_CONFIG_DIR)) {\r\n return false;\r\n }\r\n\r\n // If new directory already exists, skip migration\r\n if (existsSync(NEW_CONFIG_DIR)) {\r\n return false;\r\n }\r\n\r\n try {\r\n // Create new directory\r\n mkdirSync(NEW_CONFIG_DIR, { recursive: true });\r\n\r\n // Copy all files and subdirectories\r\n copyDirectoryRecursive(OLD_CONFIG_DIR, NEW_CONFIG_DIR);\r\n\r\n // Remove old directory after successful copy\r\n removeDirectoryRecursive(OLD_CONFIG_DIR);\r\n\r\n console.log('[Migration] Successfully migrated config from .roguelike-terminal to .idlerpg-terminal');\r\n return true;\r\n } catch (error) {\r\n console.error('[Migration] Failed to migrate config directory:', error);\r\n // Report migration failure to Sentry\r\n Sentry.captureException(error, {\r\n tags: { operation: 'config_migration', fallback: true },\r\n extra: { oldDir: OLD_CONFIG_DIR, newDir: NEW_CONFIG_DIR },\r\n });\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Recursively copy a directory\r\n */\r\nfunction copyDirectoryRecursive(src: string, dest: string): void {\r\n const entries = readdirSync(src, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n const srcPath = join(src, entry.name);\r\n const destPath = join(dest, entry.name);\r\n\r\n if (entry.isDirectory()) {\r\n mkdirSync(destPath, { recursive: true });\r\n copyDirectoryRecursive(srcPath, destPath);\r\n } else {\r\n copyFileSync(srcPath, destPath);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Recursively remove a directory\r\n */\r\nfunction removeDirectoryRecursive(dir: string): void {\r\n const entries = readdirSync(dir, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n const fullPath = join(dir, entry.name);\r\n if (entry.isDirectory()) {\r\n removeDirectoryRecursive(fullPath);\r\n } else {\r\n unlinkSync(fullPath);\r\n }\r\n }\r\n\r\n rmdirSync(dir);\r\n}\r\n\r\n/**\r\n * Get the config directory path (with auto-migration)\r\n */\r\nexport function getConfigDir(): string {\r\n // Run migration check\r\n migrateConfigDirectory();\r\n\r\n // Ensure new directory exists\r\n if (!existsSync(NEW_CONFIG_DIR)) {\r\n mkdirSync(NEW_CONFIG_DIR, { recursive: true });\r\n }\r\n\r\n return NEW_CONFIG_DIR;\r\n}\r\n"],"names":[],"mappings":"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","debug_id":"9cc7a756-b82f-591d-aae4-7b2e0ea3136a"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handler Utility
|
|
3
|
+
* Centralized error handling for AI/network operations
|
|
4
|
+
*
|
|
5
|
+
* Design principle: NO FALLBACKS
|
|
6
|
+
* - All AI/network errors should prompt user for retry
|
|
7
|
+
* - Errors are tracked for Sentry reporting
|
|
8
|
+
*/
|
|
9
|
+
export interface OperationResult<T> {
|
|
10
|
+
success: boolean;
|
|
11
|
+
data?: T;
|
|
12
|
+
error?: OperationError;
|
|
13
|
+
}
|
|
14
|
+
export interface OperationError {
|
|
15
|
+
code: ErrorCode;
|
|
16
|
+
message: string;
|
|
17
|
+
context?: Record<string, unknown>;
|
|
18
|
+
originalError?: unknown;
|
|
19
|
+
timestamp: number;
|
|
20
|
+
}
|
|
21
|
+
export type ErrorCode = 'NETWORK_ERROR' | 'AI_ERROR' | 'PARSE_ERROR' | 'TIMEOUT' | 'AUTH_ERROR' | 'RATE_LIMIT' | 'UNKNOWN';
|
|
22
|
+
export interface RetryOptions {
|
|
23
|
+
maxRetries: number;
|
|
24
|
+
delayMs: number;
|
|
25
|
+
backoffMultiplier: number;
|
|
26
|
+
onRetry?: (attempt: number, error: OperationError) => void;
|
|
27
|
+
}
|
|
28
|
+
export interface ErrorHandlerCallbacks {
|
|
29
|
+
onError: (error: OperationError) => void;
|
|
30
|
+
onRetryPrompt: (error: OperationError) => Promise<boolean>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create a standardized operation error
|
|
34
|
+
*/
|
|
35
|
+
export declare function createError(code: ErrorCode, message: string, context?: Record<string, unknown>, originalError?: unknown): OperationError;
|
|
36
|
+
/**
|
|
37
|
+
* Classify an unknown error into an ErrorCode
|
|
38
|
+
*/
|
|
39
|
+
export declare function classifyError(error: unknown): ErrorCode;
|
|
40
|
+
/**
|
|
41
|
+
* Execute an async operation with retry logic
|
|
42
|
+
* Does NOT fall back - throws after retries exhausted
|
|
43
|
+
*/
|
|
44
|
+
export declare function withRetry<T>(operation: () => Promise<T>, options?: Partial<RetryOptions>): Promise<OperationResult<T>>;
|
|
45
|
+
/**
|
|
46
|
+
* Execute operation with user retry prompt on failure
|
|
47
|
+
* Keeps prompting until success or user cancels
|
|
48
|
+
*/
|
|
49
|
+
export declare function withUserRetry<T>(operation: () => Promise<T>, onRetryPrompt: (error: OperationError) => Promise<boolean>, options?: Partial<RetryOptions>): Promise<OperationResult<T>>;
|
|
50
|
+
/**
|
|
51
|
+
* Centralized error handler for tracking and reporting errors
|
|
52
|
+
*/
|
|
53
|
+
export declare class ErrorHandler {
|
|
54
|
+
private errorLog;
|
|
55
|
+
private callbacks;
|
|
56
|
+
/**
|
|
57
|
+
* Set callbacks for error handling
|
|
58
|
+
*/
|
|
59
|
+
setCallbacks(callbacks: Partial<ErrorHandlerCallbacks>): void;
|
|
60
|
+
/**
|
|
61
|
+
* Log an error
|
|
62
|
+
*/
|
|
63
|
+
logError(error: OperationError): void;
|
|
64
|
+
/**
|
|
65
|
+
* Get recent errors
|
|
66
|
+
*/
|
|
67
|
+
getRecentErrors(count?: number): OperationError[];
|
|
68
|
+
/**
|
|
69
|
+
* Clear error log
|
|
70
|
+
*/
|
|
71
|
+
clearErrors(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Check if there are recent errors of a specific type
|
|
74
|
+
*/
|
|
75
|
+
hasRecentError(code: ErrorCode, withinMs?: number): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Execute operation with error handling and retry prompt
|
|
78
|
+
*/
|
|
79
|
+
executeWithRetry<T>(operation: () => Promise<T>, context: string, options?: Partial<RetryOptions>): Promise<OperationResult<T>>;
|
|
80
|
+
}
|
|
81
|
+
export declare function getErrorHandler(): ErrorHandler;
|
|
82
|
+
/**
|
|
83
|
+
* Format error for display to user
|
|
84
|
+
*/
|
|
85
|
+
export declare function formatErrorForUser(error: OperationError): string;
|
|
86
|
+
//# sourceMappingURL=errorHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"/","sources":["utils/errorHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handler Utility
|
|
3
|
+
* Centralized error handling for AI/network operations
|
|
4
|
+
*
|
|
5
|
+
* Design principle: NO FALLBACKS
|
|
6
|
+
* - All AI/network errors should prompt user for retry
|
|
7
|
+
* - Errors are tracked for Sentry reporting
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a4a39803-4e3d-5952-a2fe-cf607e7a8812")}catch(e){}}();
|
|
11
|
+
import { Sentry } from '../instrument.js';
|
|
12
|
+
const { logger } = Sentry;
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Default Configuration
|
|
15
|
+
// ============================================================================
|
|
16
|
+
const DEFAULT_RETRY_OPTIONS = {
|
|
17
|
+
maxRetries: 3,
|
|
18
|
+
delayMs: 1000,
|
|
19
|
+
backoffMultiplier: 2,
|
|
20
|
+
};
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Error Creation
|
|
23
|
+
// ============================================================================
|
|
24
|
+
/**
|
|
25
|
+
* Create a standardized operation error
|
|
26
|
+
*/
|
|
27
|
+
export function createError(code, message, context, originalError) {
|
|
28
|
+
return {
|
|
29
|
+
code,
|
|
30
|
+
message,
|
|
31
|
+
context,
|
|
32
|
+
originalError,
|
|
33
|
+
timestamp: Date.now(),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Classify an unknown error into an ErrorCode
|
|
38
|
+
*/
|
|
39
|
+
export function classifyError(error) {
|
|
40
|
+
if (error instanceof Error) {
|
|
41
|
+
const message = error.message.toLowerCase();
|
|
42
|
+
if (message.includes('network') || message.includes('fetch') || message.includes('connection')) {
|
|
43
|
+
return 'NETWORK_ERROR';
|
|
44
|
+
}
|
|
45
|
+
if (message.includes('timeout')) {
|
|
46
|
+
return 'TIMEOUT';
|
|
47
|
+
}
|
|
48
|
+
if (message.includes('auth') || message.includes('token') || message.includes('unauthorized')) {
|
|
49
|
+
return 'AUTH_ERROR';
|
|
50
|
+
}
|
|
51
|
+
if (message.includes('rate') || message.includes('limit') || message.includes('quota')) {
|
|
52
|
+
return 'RATE_LIMIT';
|
|
53
|
+
}
|
|
54
|
+
if (message.includes('parse') || message.includes('json') || message.includes('syntax')) {
|
|
55
|
+
return 'PARSE_ERROR';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return 'AI_ERROR';
|
|
59
|
+
}
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// Retry Logic
|
|
62
|
+
// ============================================================================
|
|
63
|
+
/**
|
|
64
|
+
* Execute an async operation with retry logic
|
|
65
|
+
* Does NOT fall back - throws after retries exhausted
|
|
66
|
+
*/
|
|
67
|
+
export async function withRetry(operation, options = {}) {
|
|
68
|
+
const opts = { ...DEFAULT_RETRY_OPTIONS, ...options };
|
|
69
|
+
let lastError = null;
|
|
70
|
+
for (let attempt = 1; attempt <= opts.maxRetries; attempt++) {
|
|
71
|
+
try {
|
|
72
|
+
const data = await operation();
|
|
73
|
+
return { success: true, data };
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
const code = classifyError(error);
|
|
77
|
+
lastError = createError(code, error instanceof Error ? error.message : 'Unknown error', { attempt, maxRetries: opts.maxRetries }, error);
|
|
78
|
+
// Log retry attempt to Sentry
|
|
79
|
+
logger.warn(logger.fmt `Operation retry attempt ${attempt}/${opts.maxRetries}`, {
|
|
80
|
+
attempt,
|
|
81
|
+
maxRetries: opts.maxRetries,
|
|
82
|
+
errorCode: lastError.code,
|
|
83
|
+
errorMessage: lastError.message,
|
|
84
|
+
});
|
|
85
|
+
if (attempt < opts.maxRetries) {
|
|
86
|
+
opts.onRetry?.(attempt, lastError);
|
|
87
|
+
const delay = opts.delayMs * Math.pow(opts.backoffMultiplier, attempt - 1);
|
|
88
|
+
await sleep(delay);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Log retries exhausted to Sentry
|
|
93
|
+
logger.error('Operation failed after all retries exhausted', {
|
|
94
|
+
maxRetries: opts.maxRetries,
|
|
95
|
+
errorCode: lastError.code,
|
|
96
|
+
errorMessage: lastError.message,
|
|
97
|
+
context: lastError.context,
|
|
98
|
+
});
|
|
99
|
+
Sentry.captureException(lastError.originalError || new Error(lastError.message), {
|
|
100
|
+
tags: { errorCode: lastError.code },
|
|
101
|
+
extra: { context: lastError.context },
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
success: false,
|
|
105
|
+
error: lastError,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Execute operation with user retry prompt on failure
|
|
110
|
+
* Keeps prompting until success or user cancels
|
|
111
|
+
*/
|
|
112
|
+
export async function withUserRetry(operation, onRetryPrompt, options = {}) {
|
|
113
|
+
while (true) {
|
|
114
|
+
const result = await withRetry(operation, options);
|
|
115
|
+
if (result.success) {
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
// Log operation failure before retry prompt
|
|
119
|
+
logger.warn('Operation failed, prompting user for retry', {
|
|
120
|
+
errorCode: result.error.code,
|
|
121
|
+
errorMessage: result.error.message,
|
|
122
|
+
});
|
|
123
|
+
const shouldRetry = await onRetryPrompt(result.error);
|
|
124
|
+
if (!shouldRetry) {
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// ============================================================================
|
|
130
|
+
// Error Handler Class
|
|
131
|
+
// ============================================================================
|
|
132
|
+
/**
|
|
133
|
+
* Centralized error handler for tracking and reporting errors
|
|
134
|
+
*/
|
|
135
|
+
export class ErrorHandler {
|
|
136
|
+
errorLog = [];
|
|
137
|
+
callbacks = {};
|
|
138
|
+
/**
|
|
139
|
+
* Set callbacks for error handling
|
|
140
|
+
*/
|
|
141
|
+
setCallbacks(callbacks) {
|
|
142
|
+
this.callbacks = { ...this.callbacks, ...callbacks };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Log an error
|
|
146
|
+
*/
|
|
147
|
+
logError(error) {
|
|
148
|
+
this.errorLog.push(error);
|
|
149
|
+
this.callbacks.onError?.(error);
|
|
150
|
+
// Send error to Sentry
|
|
151
|
+
logger.error(logger.fmt `Operation error: ${error.message}`, {
|
|
152
|
+
errorCode: error.code,
|
|
153
|
+
context: error.context,
|
|
154
|
+
timestamp: error.timestamp,
|
|
155
|
+
});
|
|
156
|
+
Sentry.captureException(error.originalError || new Error(error.message), {
|
|
157
|
+
tags: { errorCode: error.code },
|
|
158
|
+
extra: { context: error.context },
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get recent errors
|
|
163
|
+
*/
|
|
164
|
+
getRecentErrors(count = 10) {
|
|
165
|
+
return this.errorLog.slice(-count);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Clear error log
|
|
169
|
+
*/
|
|
170
|
+
clearErrors() {
|
|
171
|
+
this.errorLog = [];
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Check if there are recent errors of a specific type
|
|
175
|
+
*/
|
|
176
|
+
hasRecentError(code, withinMs = 60000) {
|
|
177
|
+
const now = Date.now();
|
|
178
|
+
return this.errorLog.some(e => e.code === code && (now - e.timestamp) < withinMs);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Execute operation with error handling and retry prompt
|
|
182
|
+
*/
|
|
183
|
+
async executeWithRetry(operation, context, options) {
|
|
184
|
+
const result = await withRetry(operation, options);
|
|
185
|
+
if (!result.success && result.error) {
|
|
186
|
+
result.error.context = { ...result.error.context, operationContext: context };
|
|
187
|
+
this.logError(result.error);
|
|
188
|
+
}
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// ============================================================================
|
|
193
|
+
// Singleton
|
|
194
|
+
// ============================================================================
|
|
195
|
+
let errorHandlerInstance = null;
|
|
196
|
+
export function getErrorHandler() {
|
|
197
|
+
if (!errorHandlerInstance) {
|
|
198
|
+
errorHandlerInstance = new ErrorHandler();
|
|
199
|
+
}
|
|
200
|
+
return errorHandlerInstance;
|
|
201
|
+
}
|
|
202
|
+
// ============================================================================
|
|
203
|
+
// Utility
|
|
204
|
+
// ============================================================================
|
|
205
|
+
function sleep(ms) {
|
|
206
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Format error for display to user
|
|
210
|
+
*/
|
|
211
|
+
export function formatErrorForUser(error) {
|
|
212
|
+
const messages = {
|
|
213
|
+
NETWORK_ERROR: '网络连接失败,请检查网络后重试',
|
|
214
|
+
AI_ERROR: 'AI 服务暂时不可用,请稍后重试',
|
|
215
|
+
PARSE_ERROR: 'AI 返回格式错误,请重试',
|
|
216
|
+
TIMEOUT: '请求超时,请重试',
|
|
217
|
+
AUTH_ERROR: '认证失败,请重新登录',
|
|
218
|
+
RATE_LIMIT: '请求过于频繁,请稍后再试',
|
|
219
|
+
UNKNOWN: '发生未知错误,请重试',
|
|
220
|
+
};
|
|
221
|
+
return messages[error.code] || messages.UNKNOWN;
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=errorHandler.js.map
|
|
224
|
+
//# debugId=a4a39803-4e3d-5952-a2fe-cf607e7a8812
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorHandler.js","sources":["utils/errorHandler.ts"],"sourceRoot":"/","sourcesContent":["/**\r\n * Error Handler Utility\r\n * Centralized error handling for AI/network operations\r\n *\r\n * Design principle: NO FALLBACKS\r\n * - All AI/network errors should prompt user for retry\r\n * - Errors are tracked for Sentry reporting\r\n */\r\n\r\nimport { Sentry } from '../instrument.js';\r\nconst { logger } = Sentry;\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\nexport interface OperationResult<T> {\r\n success: boolean;\r\n data?: T;\r\n error?: OperationError;\r\n}\r\n\r\nexport interface OperationError {\r\n code: ErrorCode;\r\n message: string;\r\n context?: Record<string, unknown>;\r\n originalError?: unknown;\r\n timestamp: number;\r\n}\r\n\r\nexport type ErrorCode =\r\n | 'NETWORK_ERROR'\r\n | 'AI_ERROR'\r\n | 'PARSE_ERROR'\r\n | 'TIMEOUT'\r\n | 'AUTH_ERROR'\r\n | 'RATE_LIMIT'\r\n | 'UNKNOWN';\r\n\r\nexport interface RetryOptions {\r\n maxRetries: number;\r\n delayMs: number;\r\n backoffMultiplier: number;\r\n onRetry?: (attempt: number, error: OperationError) => void;\r\n}\r\n\r\nexport interface ErrorHandlerCallbacks {\r\n onError: (error: OperationError) => void;\r\n onRetryPrompt: (error: OperationError) => Promise<boolean>; // Returns true if user wants to retry\r\n}\r\n\r\n// ============================================================================\r\n// Default Configuration\r\n// ============================================================================\r\n\r\nconst DEFAULT_RETRY_OPTIONS: RetryOptions = {\r\n maxRetries: 3,\r\n delayMs: 1000,\r\n backoffMultiplier: 2,\r\n};\r\n\r\n// ============================================================================\r\n// Error Creation\r\n// ============================================================================\r\n\r\n/**\r\n * Create a standardized operation error\r\n */\r\nexport function createError(\r\n code: ErrorCode,\r\n message: string,\r\n context?: Record<string, unknown>,\r\n originalError?: unknown\r\n): OperationError {\r\n return {\r\n code,\r\n message,\r\n context,\r\n originalError,\r\n timestamp: Date.now(),\r\n };\r\n}\r\n\r\n/**\r\n * Classify an unknown error into an ErrorCode\r\n */\r\nexport function classifyError(error: unknown): ErrorCode {\r\n if (error instanceof Error) {\r\n const message = error.message.toLowerCase();\r\n\r\n if (message.includes('network') || message.includes('fetch') || message.includes('connection')) {\r\n return 'NETWORK_ERROR';\r\n }\r\n if (message.includes('timeout')) {\r\n return 'TIMEOUT';\r\n }\r\n if (message.includes('auth') || message.includes('token') || message.includes('unauthorized')) {\r\n return 'AUTH_ERROR';\r\n }\r\n if (message.includes('rate') || message.includes('limit') || message.includes('quota')) {\r\n return 'RATE_LIMIT';\r\n }\r\n if (message.includes('parse') || message.includes('json') || message.includes('syntax')) {\r\n return 'PARSE_ERROR';\r\n }\r\n }\r\n\r\n return 'AI_ERROR';\r\n}\r\n\r\n// ============================================================================\r\n// Retry Logic\r\n// ============================================================================\r\n\r\n/**\r\n * Execute an async operation with retry logic\r\n * Does NOT fall back - throws after retries exhausted\r\n */\r\nexport async function withRetry<T>(\r\n operation: () => Promise<T>,\r\n options: Partial<RetryOptions> = {}\r\n): Promise<OperationResult<T>> {\r\n const opts = { ...DEFAULT_RETRY_OPTIONS, ...options };\r\n let lastError: OperationError | null = null;\r\n\r\n for (let attempt = 1; attempt <= opts.maxRetries; attempt++) {\r\n try {\r\n const data = await operation();\r\n return { success: true, data };\r\n } catch (error) {\r\n const code = classifyError(error);\r\n lastError = createError(\r\n code,\r\n error instanceof Error ? error.message : 'Unknown error',\r\n { attempt, maxRetries: opts.maxRetries },\r\n error\r\n );\r\n\r\n // Log retry attempt to Sentry\r\n logger.warn(logger.fmt`Operation retry attempt ${attempt}/${opts.maxRetries}`, {\r\n attempt,\r\n maxRetries: opts.maxRetries,\r\n errorCode: lastError.code,\r\n errorMessage: lastError.message,\r\n });\r\n\r\n if (attempt < opts.maxRetries) {\r\n opts.onRetry?.(attempt, lastError);\r\n const delay = opts.delayMs * Math.pow(opts.backoffMultiplier, attempt - 1);\r\n await sleep(delay);\r\n }\r\n }\r\n }\r\n\r\n // Log retries exhausted to Sentry\r\n logger.error('Operation failed after all retries exhausted', {\r\n maxRetries: opts.maxRetries,\r\n errorCode: lastError!.code,\r\n errorMessage: lastError!.message,\r\n context: lastError!.context,\r\n });\r\n Sentry.captureException(lastError!.originalError || new Error(lastError!.message), {\r\n tags: { errorCode: lastError!.code },\r\n extra: { context: lastError!.context },\r\n });\r\n\r\n return {\r\n success: false,\r\n error: lastError!,\r\n };\r\n}\r\n\r\n/**\r\n * Execute operation with user retry prompt on failure\r\n * Keeps prompting until success or user cancels\r\n */\r\nexport async function withUserRetry<T>(\r\n operation: () => Promise<T>,\r\n onRetryPrompt: (error: OperationError) => Promise<boolean>,\r\n options: Partial<RetryOptions> = {}\r\n): Promise<OperationResult<T>> {\r\n while (true) {\r\n const result = await withRetry(operation, options);\r\n\r\n if (result.success) {\r\n return result;\r\n }\r\n\r\n // Log operation failure before retry prompt\r\n logger.warn('Operation failed, prompting user for retry', {\r\n errorCode: result.error!.code,\r\n errorMessage: result.error!.message,\r\n });\r\n\r\n const shouldRetry = await onRetryPrompt(result.error!);\r\n\r\n if (!shouldRetry) {\r\n return result;\r\n }\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Error Handler Class\r\n// ============================================================================\r\n\r\n/**\r\n * Centralized error handler for tracking and reporting errors\r\n */\r\nexport class ErrorHandler {\r\n private errorLog: OperationError[] = [];\r\n private callbacks: Partial<ErrorHandlerCallbacks> = {};\r\n\r\n /**\r\n * Set callbacks for error handling\r\n */\r\n setCallbacks(callbacks: Partial<ErrorHandlerCallbacks>): void {\r\n this.callbacks = { ...this.callbacks, ...callbacks };\r\n }\r\n\r\n /**\r\n * Log an error\r\n */\r\n logError(error: OperationError): void {\r\n this.errorLog.push(error);\r\n this.callbacks.onError?.(error);\r\n\r\n // Send error to Sentry\r\n logger.error(logger.fmt`Operation error: ${error.message}`, {\r\n errorCode: error.code,\r\n context: error.context,\r\n timestamp: error.timestamp,\r\n });\r\n Sentry.captureException(error.originalError || new Error(error.message), {\r\n tags: { errorCode: error.code },\r\n extra: { context: error.context },\r\n });\r\n }\r\n\r\n /**\r\n * Get recent errors\r\n */\r\n getRecentErrors(count: number = 10): OperationError[] {\r\n return this.errorLog.slice(-count);\r\n }\r\n\r\n /**\r\n * Clear error log\r\n */\r\n clearErrors(): void {\r\n this.errorLog = [];\r\n }\r\n\r\n /**\r\n * Check if there are recent errors of a specific type\r\n */\r\n hasRecentError(code: ErrorCode, withinMs: number = 60000): boolean {\r\n const now = Date.now();\r\n return this.errorLog.some(\r\n e => e.code === code && (now - e.timestamp) < withinMs\r\n );\r\n }\r\n\r\n /**\r\n * Execute operation with error handling and retry prompt\r\n */\r\n async executeWithRetry<T>(\r\n operation: () => Promise<T>,\r\n context: string,\r\n options?: Partial<RetryOptions>\r\n ): Promise<OperationResult<T>> {\r\n const result = await withRetry(operation, options);\r\n\r\n if (!result.success && result.error) {\r\n result.error.context = { ...result.error.context, operationContext: context };\r\n this.logError(result.error);\r\n }\r\n\r\n return result;\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Singleton\r\n// ============================================================================\r\n\r\nlet errorHandlerInstance: ErrorHandler | null = null;\r\n\r\nexport function getErrorHandler(): ErrorHandler {\r\n if (!errorHandlerInstance) {\r\n errorHandlerInstance = new ErrorHandler();\r\n }\r\n return errorHandlerInstance;\r\n}\r\n\r\n// ============================================================================\r\n// Utility\r\n// ============================================================================\r\n\r\nfunction sleep(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n}\r\n\r\n/**\r\n * Format error for display to user\r\n */\r\nexport function formatErrorForUser(error: OperationError): string {\r\n const messages: Record<ErrorCode, string> = {\r\n NETWORK_ERROR: '网络连接失败,请检查网络后重试',\r\n AI_ERROR: 'AI 服务暂时不可用,请稍后重试',\r\n PARSE_ERROR: 'AI 返回格式错误,请重试',\r\n TIMEOUT: '请求超时,请重试',\r\n AUTH_ERROR: '认证失败,请重新登录',\r\n RATE_LIMIT: '请求过于频繁,请稍后再试',\r\n UNKNOWN: '发生未知错误,请重试',\r\n };\r\n\r\n return messages[error.code] || messages.UNKNOWN;\r\n}\r\n"],"names":[],"mappings":"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","debug_id":"a4a39803-4e3d-5952-a2fe-cf607e7a8812"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple file logger for debugging TUI applications
|
|
3
|
+
* Logs are written to ~/.idlerpg-terminal/debug.log
|
|
4
|
+
*/
|
|
5
|
+
export declare const logger: {
|
|
6
|
+
debug(message: string, data?: unknown): void;
|
|
7
|
+
info(message: string, data?: unknown): void;
|
|
8
|
+
warn(message: string, data?: unknown): void;
|
|
9
|
+
error(message: string, data?: unknown): void;
|
|
10
|
+
/** Get the log file path for tailing */
|
|
11
|
+
getLogPath(): string;
|
|
12
|
+
};
|
|
13
|
+
export default logger;
|
|
14
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"/","sources":["utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAyBH,eAAO,MAAM,MAAM;mBACF,MAAM,SAAS,OAAO,GAAG,IAAI;kBAI9B,MAAM,SAAS,OAAO,GAAG,IAAI;kBAI7B,MAAM,SAAS,OAAO,GAAG,IAAI;mBAI5B,MAAM,SAAS,OAAO,GAAG,IAAI;IAI5C,wCAAwC;kBAC1B,MAAM;CAGrB,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple file logger for debugging TUI applications
|
|
3
|
+
* Logs are written to ~/.idlerpg-terminal/debug.log
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b0a98fcf-9047-558b-af9c-b19ca70e081d")}catch(e){}}();
|
|
7
|
+
import { appendFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { homedir } from 'os';
|
|
10
|
+
const LOG_DIR = join(homedir(), '.idlerpg-terminal');
|
|
11
|
+
const LOG_FILE = join(LOG_DIR, 'debug.log');
|
|
12
|
+
// Ensure log directory exists
|
|
13
|
+
if (!existsSync(LOG_DIR)) {
|
|
14
|
+
mkdirSync(LOG_DIR, { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
// Clear log file on startup
|
|
17
|
+
writeFileSync(LOG_FILE, `=== IdleRPG Terminal Debug Log ===\nStarted: ${new Date().toISOString()}\n\n`);
|
|
18
|
+
function formatLog(level, message, data) {
|
|
19
|
+
const timestamp = new Date().toISOString().slice(11, 23); // HH:MM:SS.mmm
|
|
20
|
+
const dataStr = data !== undefined ? ` ${JSON.stringify(data)}` : '';
|
|
21
|
+
return `[${timestamp}] [${level}] ${message}${dataStr}\n`;
|
|
22
|
+
}
|
|
23
|
+
export const logger = {
|
|
24
|
+
debug(message, data) {
|
|
25
|
+
appendFileSync(LOG_FILE, formatLog('DEBUG', message, data));
|
|
26
|
+
},
|
|
27
|
+
info(message, data) {
|
|
28
|
+
appendFileSync(LOG_FILE, formatLog('INFO', message, data));
|
|
29
|
+
},
|
|
30
|
+
warn(message, data) {
|
|
31
|
+
appendFileSync(LOG_FILE, formatLog('WARN', message, data));
|
|
32
|
+
},
|
|
33
|
+
error(message, data) {
|
|
34
|
+
appendFileSync(LOG_FILE, formatLog('ERROR', message, data));
|
|
35
|
+
},
|
|
36
|
+
/** Get the log file path for tailing */
|
|
37
|
+
getLogPath() {
|
|
38
|
+
return LOG_FILE;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
export default logger;
|
|
42
|
+
//# sourceMappingURL=logger.js.map
|
|
43
|
+
//# debugId=b0a98fcf-9047-558b-af9c-b19ca70e081d
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sources":["utils/logger.ts"],"sourceRoot":"/","sourcesContent":["/**\r\n * Simple file logger for debugging TUI applications\r\n * Logs are written to ~/.idlerpg-terminal/debug.log\r\n */\r\n\r\nimport { appendFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';\r\nimport { join } from 'path';\r\nimport { homedir } from 'os';\r\n\r\nconst LOG_DIR = join(homedir(), '.idlerpg-terminal');\r\nconst LOG_FILE = join(LOG_DIR, 'debug.log');\r\n\r\n// Ensure log directory exists\r\nif (!existsSync(LOG_DIR)) {\r\n mkdirSync(LOG_DIR, { recursive: true });\r\n}\r\n\r\n// Clear log file on startup\r\nwriteFileSync(LOG_FILE, `=== IdleRPG Terminal Debug Log ===\\nStarted: ${new Date().toISOString()}\\n\\n`);\r\n\r\ntype LogLevel = 'DEBUG' | 'INFO' | 'WARN' | 'ERROR';\r\n\r\nfunction formatLog(level: LogLevel, message: string, data?: unknown): string {\r\n const timestamp = new Date().toISOString().slice(11, 23); // HH:MM:SS.mmm\r\n const dataStr = data !== undefined ? ` ${JSON.stringify(data)}` : '';\r\n return `[${timestamp}] [${level}] ${message}${dataStr}\\n`;\r\n}\r\n\r\nexport const logger = {\r\n debug(message: string, data?: unknown): void {\r\n appendFileSync(LOG_FILE, formatLog('DEBUG', message, data));\r\n },\r\n\r\n info(message: string, data?: unknown): void {\r\n appendFileSync(LOG_FILE, formatLog('INFO', message, data));\r\n },\r\n\r\n warn(message: string, data?: unknown): void {\r\n appendFileSync(LOG_FILE, formatLog('WARN', message, data));\r\n },\r\n\r\n error(message: string, data?: unknown): void {\r\n appendFileSync(LOG_FILE, formatLog('ERROR', message, data));\r\n },\r\n\r\n /** Get the log file path for tailing */\r\n getLogPath(): string {\r\n return LOG_FILE;\r\n },\r\n};\r\n\r\nexport default logger;\r\n"],"names":[],"mappings":"AAAA;;;GAGG;;;AAEH,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC1E,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,mBAAmB,CAAC,CAAC;AACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AAE5C,8BAA8B;AAC9B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IACzB,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED,4BAA4B;AAC5B,aAAa,CAAC,QAAQ,EAAE,gDAAgD,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAIxG,SAAS,SAAS,CAAC,KAAe,EAAE,OAAe,EAAE,IAAc;IACjE,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe;IACzE,MAAM,OAAO,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,OAAO,IAAI,SAAS,MAAM,KAAK,KAAK,OAAO,GAAG,OAAO,IAAI,CAAC;AAC5D,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,KAAK,CAAC,OAAe,EAAE,IAAc;QACnC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,IAAc;QAClC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,IAAc;QAClC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,IAAc;QACnC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,wCAAwC;IACxC,UAAU;QACR,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAC;AAEF,eAAe,MAAM,CAAC","debug_id":"b0a98fcf-9047-558b-af9c-b19ca70e081d"}
|