Hoist turn state from a 286-line hook into $turnState atom + turnController
singleton. createGatewayEventHandler becomes a typed dispatch over the
controller; its ctx shrinks from 30 fields to 5. Event-handler refs and 16
threaded actions are gone.
Fold three createSlash*Handler factories into a data-driven SlashCommand[]
registry under slash/commands/{core,session,ops}.ts. Aliases are data;
findSlashCommand does name+alias lookup. Shared guarded/guardedErr combinator
in slash/guarded.ts.
Split constants.ts + app/helpers.ts into config/ (timing/limits/env),
content/ (faces/placeholders/hotkeys/verbs/charms/fortunes), domain/ (roles/
details/messages/paths/slash/viewport/usage), protocol/ (interpolation/paste).
Type every RPC response in gatewayTypes.ts (26 new interfaces); drop all
`(r: any)` across slash + main app.
Shrink useMainApp from 1216 -> 646 lines by extracting useSessionLifecycle,
useSubmission, useConfigSync. Add <Fg> themed primitive and strip ~50
`as any` color casts.
Tests: 50 passing. Build + type-check clean.
48 lines
1.1 KiB
TypeScript
48 lines
1.1 KiB
TypeScript
import { atom } from 'nanostores'
|
|
|
|
import type { ActiveTool, ActivityItem, SubagentProgress } from '../types.js'
|
|
|
|
export interface TurnState {
|
|
activity: ActivityItem[]
|
|
reasoning: string
|
|
reasoningActive: boolean
|
|
reasoningStreaming: boolean
|
|
reasoningTokens: number
|
|
streaming: string
|
|
subagents: SubagentProgress[]
|
|
toolTokens: number
|
|
tools: ActiveTool[]
|
|
turnTrail: string[]
|
|
}
|
|
|
|
function buildTurnState(): TurnState {
|
|
return {
|
|
activity: [],
|
|
reasoning: '',
|
|
reasoningActive: false,
|
|
reasoningStreaming: false,
|
|
reasoningTokens: 0,
|
|
streaming: '',
|
|
subagents: [],
|
|
toolTokens: 0,
|
|
tools: [],
|
|
turnTrail: []
|
|
}
|
|
}
|
|
|
|
export const $turnState = atom<TurnState>(buildTurnState())
|
|
|
|
export const getTurnState = () => $turnState.get()
|
|
|
|
export const patchTurnState = (next: Partial<TurnState> | ((state: TurnState) => TurnState)) => {
|
|
if (typeof next === 'function') {
|
|
$turnState.set(next($turnState.get()))
|
|
|
|
return
|
|
}
|
|
|
|
$turnState.set({ ...$turnState.get(), ...next })
|
|
}
|
|
|
|
export const resetTurnState = () => $turnState.set(buildTurnState())
|