feat: add kitchen and glitchtip wiring
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2026-05-10 12:03:12 -05:00
parent 4d9077d586
commit 26dd91947f
49 changed files with 470 additions and 53 deletions
+73 -1
View File
@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest'
import { dispatch, initialStateFor } from './dispatcher'
import { dispatch, getLightStatus, initialStateFor } from './dispatcher'
import type { World } from '../world/types'
import type { GameState, ParsedCommand } from './types'
import { SCHEMA_VERSION } from './types'
@@ -256,6 +256,78 @@ describe('dispatcher — inventory', () => {
})
})
describe('light status', () => {
it('shows the meter when carrying a lightable item even before it is lit', () => {
const lightWorld: World = {
...world,
items: {
...world.items,
torch: {
id: 'torch',
names: ['torch', 'lamp'],
short: 'an oil lamp',
long: 'An iron oil lamp, unlit.',
initialState: { lit: false },
takeable: true,
lightable: true,
},
},
}
const state: GameState = {
...initialStateFor(lightWorld),
inventory: [{ id: 'torch', state: { lit: false } }],
}
expect(getLightStatus(state, lightWorld)).toEqual({
itemId: 'torch',
lit: false,
turnsLeft: 0,
maxTurns: 6,
})
})
it('prefers a lit lightable item over an unlit one in inventory order', () => {
const lightWorld: World = {
...world,
items: {
...world.items,
torch: {
id: 'torch',
names: ['torch', 'lamp'],
short: 'an oil lamp',
long: 'An iron oil lamp, unlit.',
initialState: { lit: false },
takeable: true,
lightable: true,
},
candlestick: {
id: 'candlestick',
names: ['candlestick', 'candle'],
short: 'a brass candlestick',
long: 'A brass candlestick.',
initialState: { lit: false },
takeable: true,
lightable: true,
},
},
}
const state: GameState = {
...initialStateFor(lightWorld),
inventory: [
{ id: 'candlestick', state: { lit: false } },
{ id: 'torch', state: { lit: true, burn: 6 } },
],
}
expect(getLightStatus(state, lightWorld)).toEqual({
itemId: 'torch',
lit: true,
turnsLeft: 6,
maxTurns: 6,
})
})
})
describe('ambiguous → disambiguation flow', () => {
function makeAmbiguousWorld(): World {
return {
+8 -5
View File
@@ -52,19 +52,22 @@ export function initialStateFor(world: World): GameState {
}
export function getLightStatus(state: GameState, world: World): LightStatus | null {
let fallback: LightStatus | null = null
for (const inst of state.inventory) {
const def = world.items[inst.id]
if (!def?.lightable) continue
if (inst.state['lit'] !== true) continue
const turnsLeft = getLightTurnsLeft(inst)
return {
const lit = inst.state['lit'] === true
const turnsLeft = lit ? getLightTurnsLeft(inst) : 0
const status = {
itemId: inst.id,
lit: true,
lit,
turnsLeft,
maxTurns: LIGHT_TURNS_MAX,
}
if (lit) return status
fallback = fallback ?? status
}
return null
return fallback
}
function append(state: GameState, lines: TranscriptLine[]): GameState {