mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-23 08:45:50 +00:00
feat: 新增 /pokemon-battle 独立战斗命令,从 BuddyPanel 移除 Battle tab
- 新增 /pokemon-battle 命令,独立全屏战斗面板 - BattlePanel 在主 app Ink 上下文中使用 useInput,通过 inputRef 转发事件 - BuddyPanel 恢复为 Buddy/Pokédex/Egg 三 tab - BattleFlow 移除内部 useInput,改为暴露 handleInput 方法 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
15
src/commands/pokemon-battle/index.ts
Normal file
15
src/commands/pokemon-battle/index.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { Command } from '../../commands.js'
|
||||
import { isBuddyLive } from '../../buddy/useBuddyNotification.js'
|
||||
|
||||
const pokemonBattle = {
|
||||
type: 'local-jsx',
|
||||
name: 'pokemon-battle',
|
||||
description: 'Start a Pokémon battle',
|
||||
immediate: true,
|
||||
get isHidden() {
|
||||
return !isBuddyLive()
|
||||
},
|
||||
load: () => import('./pokemon-battle.js'),
|
||||
} satisfies Command
|
||||
|
||||
export default pokemonBattle
|
||||
71
src/commands/pokemon-battle/pokemon-battle.ts
Normal file
71
src/commands/pokemon-battle/pokemon-battle.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import React, { useState, useRef } from 'react'
|
||||
import { useInput } from '@anthropic/ink'
|
||||
import {
|
||||
loadBuddyData,
|
||||
saveBuddyData,
|
||||
getActiveCreature,
|
||||
BattleFlow,
|
||||
type BuddyData,
|
||||
type BattleFlowHandle,
|
||||
} from '@claude-code-best/pokemon'
|
||||
import type { ToolUseContext } from '../../Tool.js'
|
||||
import type {
|
||||
LocalJSXCommandContext,
|
||||
LocalJSXCommandOnDone,
|
||||
} from '../../types/command.js'
|
||||
|
||||
async function getOrInitBuddyData(): Promise<BuddyData> {
|
||||
let data = await loadBuddyData()
|
||||
if (!getActiveCreature(data)) {
|
||||
data = await loadBuddyData()
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
export async function call(
|
||||
onDone: LocalJSXCommandOnDone,
|
||||
_context: ToolUseContext & LocalJSXCommandContext,
|
||||
_args: string,
|
||||
): Promise<React.ReactNode> {
|
||||
const data = await getOrInitBuddyData()
|
||||
|
||||
if (!getActiveCreature(data)) {
|
||||
onDone('No companion yet · run /buddy first', { display: 'system' })
|
||||
return null
|
||||
}
|
||||
|
||||
return React.createElement(BattlePanel, {
|
||||
buddyData: data,
|
||||
onClose: () => {
|
||||
onDone('battle closed', { display: 'system' })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function BattlePanel({
|
||||
buddyData,
|
||||
onClose,
|
||||
}: {
|
||||
buddyData: BuddyData
|
||||
onClose: () => void
|
||||
}) {
|
||||
const [battleKey, setBattleKey] = useState(0)
|
||||
const inputRef = useRef<BattleFlowHandle | null>(null)
|
||||
|
||||
useInput((input, key) => {
|
||||
inputRef.current?.handleInput(input, key)
|
||||
})
|
||||
|
||||
const handleClose = async () => {
|
||||
const updated = await loadBuddyData()
|
||||
setBattleKey(k => k + 1)
|
||||
}
|
||||
|
||||
return React.createElement(BattleFlow, {
|
||||
key: battleKey,
|
||||
buddyData,
|
||||
onClose,
|
||||
isActive: true,
|
||||
inputRef,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user