test: remove 69 low-value syntax, script, policy and chat tests (#34497)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
OrcaWin
2026-10-27 11:30:19 -07:00
committed by GitHub
co-authored by OrcaWin
parent 8414076859
commit 05fc67ff51
19 changed files with 2 additions and 1205 deletions
@@ -1,25 +0,0 @@
import { describe, expect, it } from 'vitest'
import {
removeDevRolldownRuntimeEnv,
withDevRolldownRuntimeEnv
} from './dev-rolldown-runtime-env.mjs'
describe('dev Rolldown runtime env', () => {
it('removes only the keys it added, keeping caller choices', () => {
const env = withDevRolldownRuntimeEnv({ RAYON_NUM_THREADS: '2', PATH: '/bin' }, 24)
expect(env).toMatchObject({
MIMALLOC_PURGE_DELAY: '0',
ROLLDOWN_WORKER_THREADS: '4',
RAYON_NUM_THREADS: '2'
})
removeDevRolldownRuntimeEnv(env)
expect(env).toEqual({ RAYON_NUM_THREADS: '2', PATH: '/bin' })
})
it('keeps Rolldown thread defaults on small hosts', () => {
expect(withDevRolldownRuntimeEnv({}, 4)).toEqual({
MIMALLOC_PURGE_DELAY: '0',
ORCA_DEV_RUNTIME_ENV_KEYS: 'MIMALLOC_PURGE_DELAY'
})
})
})
@@ -1,17 +0,0 @@
import { describe, expect, it } from 'vitest'
import { withRolldownThreadLimit } from './rolldown-thread-limit.mjs'
describe('withRolldownThreadLimit', () => {
it('caps both pools on large hosts', () => {
expect(withRolldownThreadLimit({ A: '1' }, 24)).toEqual({
A: '1',
ROLLDOWN_WORKER_THREADS: '8',
RAYON_NUM_THREADS: '8'
})
})
it('keeps Rolldown defaults on small hosts and explicit sizes everywhere', () => {
expect(withRolldownThreadLimit({}, 8)).toEqual({})
expect(withRolldownThreadLimit({ RAYON_NUM_THREADS: '2' }, 24).RAYON_NUM_THREADS).toBe('2')
})
})
@@ -2,11 +2,7 @@ import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, expect, it } from 'vitest'
import {
createRunTempDirectory,
resolveRunTempBase,
sweepStaleRunDirectories
} from './vitest-run-temp-directory.mjs'
import { createRunTempDirectory, sweepStaleRunDirectories } from './vitest-run-temp-directory.mjs'
const bases = []
@@ -51,12 +47,3 @@ it('removes the run directory and leaves an unmarked one with the same name alon
runDirectory(base, 105, false)
expect(createRunTempDirectory({ base, pid: 105 })).toBeNull()
})
it('keeps POSIX run roots no longer than the default macOS temp root', () => {
const macTemp = '/var/folders/zz/zyxvpxvq6csfxvn_n0000000000000gn/T'
expect(resolveRunTempBase(macTemp, 'ov255r', 'darwin')).toBe('/tmp')
expect(resolveRunTempBase('/tmp', 'ov255r', 'linux')).toBe('/tmp')
expect(resolveRunTempBase('C:\\Users\\a\\AppData\\Local\\Temp', 'ov255r', 'win32')).toBe(
'C:\\Users\\a\\AppData\\Local\\Temp'
)
})
@@ -1,45 +0,0 @@
import { readFileSync } from 'node:fs'
import { describe, expect, it } from 'vitest'
import { parse } from 'yaml'
// The rehearsal must sign and reseal the same template payload release-cut ships, or Windows reseal regressions only surface in a real release.
function readWorkflow(name) {
return parse(readFileSync(new URL(`../../.github/workflows/${name}`, import.meta.url), 'utf8'))
}
const RESEAL_STEP = 'Reseal the orcad template over its signed binaries'
const release = readWorkflow('release-cut.yml').jobs.build
const { jobs } = readWorkflow('windows-signing-rehearsal.yml')
const rehearse = jobs.rehearse
const stepIndex = (name) => rehearse.steps.findIndex((step) => step.name === name)
describe('Windows signing rehearsal ships the orcad template', () => {
it('packages the qualified template built from the dispatched commit', () => {
expect(jobs['orcad-template'].uses).toBe('./.github/workflows/qualified-orcad-template.yml')
expect(jobs['orcad-template'].with).toEqual({ ref: '${{ github.sha }}', fast_runners: false })
expect(rehearse.needs).toBe('orcad-template')
expect(rehearse.env.ORCA_REQUIRE_ORCAD_TEMPLATE).toBe('1')
const download = stepIndex('Download the orcad deployment template')
expect(download).toBeGreaterThan(stepIndex('Build app'))
expect(download).toBeLessThan(stepIndex('Package Windows app and export the NSIS uninstaller'))
expect(rehearse.steps[download].with).toEqual({
name: 'orcad-template',
path: 'out/orcad-template'
})
})
it('reseals the signed template exactly like release-cut, before the installer rebuild', () => {
const releaseReseal = release.steps.find((step) => step.name === RESEAL_STEP)
const reseal = stepIndex(RESEAL_STEP)
expect(rehearse.steps[reseal].run).toBe(releaseReseal.run)
expect(reseal).toBeGreaterThan(stepIndex('Restore signed inner binaries into unpacked app'))
expect(reseal).toBeLessThan(stepIndex('Build NSIS installer from signed unpacked app'))
})
it('keeps non-Windows template addons out of SignPath staging', () => {
const filter = "'^resources[\\\\/]orcad-template[\\\\/]targets[\\\\/](?!win32-)'"
const staging = (job) => job.steps.find((step) => step.id === 'stage-inner').run
expect(staging(release)).toContain(filter)
expect(staging(rehearse)).toContain(filter)
})
})
@@ -35,36 +35,6 @@ describe('createTextMateTokensProvider', () => {
expect(after.tokens.length).toBeGreaterThan(1)
})
it('tokenizes Nim with the vendored TextMate grammar', async () => {
const provider = await createTextMateTokensProvider({ loadGrammar: loadNimTextMateGrammar })
const procLine = provider.tokenize('proc greet(name: string) =', provider.getInitialState())
const procScopes = procLine.tokens.map((token) => token.scopes)
expect(procScopes).toContain('keyword.other')
expect(procScopes).toContain('entity.name.function.nim')
expect(procScopes).toContain('storage.type.concrete.nim')
const commentLine = provider.tokenize('# hello', provider.getInitialState())
expect(commentLine.tokens.map((token) => token.scopes)).toContain(
'comment.line.number-sign.nim'
)
})
it('tokenizes Typst markup, code, and math through the lazy grammar loader', async () => {
const provider = await createTextMateTokensProvider({ loadGrammar: loadTypstTextMateGrammar })
const scopesOf = (line: string) =>
provider.tokenize(line, provider.getInitialState()).tokens.map((token) => token.scopes)
expect(scopesOf('#let width = 12pt')).toEqual(
expect.arrayContaining(['keyword.other.typst', 'constant.numeric.length.typst'])
)
expect(scopesOf('#set text(font: "Inter")')).toEqual(
expect.arrayContaining(['entity.name.function.typst', 'string.quoted.double.typst'])
)
expect(scopesOf('// note')).toContain('comment.line.double-slash.typst')
expect(scopesOf('$ sum_(k=0)^n k $')).toContain('string.other.math.typst')
})
it.each([
['```rust', 'let x = 1', '```', '#let y = 2'],
['````', '```', '````', '#let y = 2']
@@ -95,31 +95,6 @@ describe('highlightSyntax', () => {
expect(find(result, 'total')).toMatchObject({ dark: '#9CDCFE' })
})
it('leaves a line too long to color plain, along with every line after it', async () => {
const typescript = await highlighterFor('typescript')
const code = ['const a = 1', `const long = "${'x'.repeat(2000)}"`, 'const b = 2'].join('\n')
const result = typescript(code)
expect(result.outcome).toBe('degraded')
expect(find(result, 'const')).toMatchObject({ dark: '#569CD6' })
expect(result.lines[1]).toEqual([expect.objectContaining({ dark: undefined })])
expect(result.lines[2]).toEqual([
{
content: 'const b = 2',
offset: code.lastIndexOf('const b'),
light: undefined,
dark: undefined,
lightFontStyle: 0,
darkFontStyle: 0
}
])
expect(typescript('const c = 3', result.state)).toMatchObject({
outcome: 'degraded',
lines: [[expect.objectContaining({ content: 'const c = 3', dark: undefined })]]
})
})
it('leaves a line that runs out of time plain instead of guessing the rest', async () => {
const typescript = await highlighterFor('typescript')
let now = 0
@@ -143,16 +118,6 @@ describe('highlightSyntax', () => {
})
describe('loadSyntaxLanguage', () => {
it('reports a language without a grammar as unsupported', async () => {
await expect(loadSyntaxLanguage('not-a-real-language')).resolves.toBe('unsupported')
expect(loadedSyntaxHighlighter('not-a-real-language')).toBeNull()
})
it('accepts aliases and any letter case', async () => {
await expect(loadSyntaxLanguage('PS1')).resolves.toBe('ready')
expect(loadedSyntaxHighlighter('ps1')).not.toBeNull()
})
it('retries a failed load after a pause', async () => {
const { loadSyntaxLanguage, loadedSyntaxHighlighter } = await freshHighlighterModule()
let now = 0
@@ -31,9 +31,4 @@ describe('readableMermaidFlowchartSvg', () => {
)
expect(labelFill(readableMermaidFlowchartSvg(stadium, '#e0e0e0', '#111111'))).toBe('#e0e0e0')
})
it('leaves a label that already reads on its fill', () => {
const svg = readableMermaidFlowchartSvg(flowchart('#1e3a8a', '#e0e0e0'), '#e0e0e0', '#111111')
expect(labelFill(svg)).toBe('#e0e0e0')
})
})
@@ -1,60 +0,0 @@
import { describe, it, expect } from 'vitest'
import { canToggleNativeChat } from './native-chat-availability'
import { isNativeChatTranscriptLocalReadable } from './native-chat-transcript-readability'
describe('canToggleNativeChat', () => {
// omp exposes no hook transcript path; its session file requires readable agent storage.
it('rejects Model-A SSH omp but accepts it local and runtime-owned', () => {
const forConnection = (connectionId: string | null): boolean =>
canToggleNativeChat({
contentType: 'terminal',
launchAgent: 'omp',
nativeChatTranscriptIsLocalReadable: isNativeChatTranscriptLocalReadable(connectionId)
})
expect(forConnection('ssh-target-1')).toBe(false)
expect(forConnection(null)).toBe(true)
expect(forConnection('runtime-ssh-env-1')).toBe(true)
})
it('lets an existing Model-A SSH Grok chat toggle back to terminal', () => {
expect(
canToggleNativeChat({
contentType: 'terminal',
launchAgent: 'grok',
nativeChatTranscriptIsLocalReadable: false,
isChatViewMode: true
})
).toBe(true)
})
it('rejects a stale supported title when live detection found an unsupported agent', () => {
expect(
canToggleNativeChat({
contentType: 'terminal',
launchAgent: null,
detectedAgent: 'gemini',
resolvedAgent: 'codex'
})
).toBe(false)
})
it('rejects stale launch metadata when live detection found an unsupported agent', () => {
expect(
canToggleNativeChat({
contentType: 'terminal',
launchAgent: 'codex',
detectedAgent: 'gemini'
})
).toBe(false)
})
it('rejects a stale supported title when launch metadata names an unsupported agent', () => {
expect(
canToggleNativeChat({
contentType: 'terminal',
launchAgent: 'gemini',
resolvedAgent: 'claude'
})
).toBe(false)
})
})
@@ -1,9 +1,6 @@
import { describe, expect, it } from 'vitest'
import { nativeChatMessageCopyText } from './native-chat-message-copy-text'
import {
NATIVE_CHAT_STOPPED_BEFORE_START_PRESENTATION,
NATIVE_CHAT_STOPPED_BEFORE_START_TEXT
} from './native-chat-stopped-before-start'
import { subagentGroupFallbackText } from './native-chat-subagent-summary'
import type { NativeChatSubagentEntry } from './native-chat-types'
@@ -29,15 +26,4 @@ describe('nativeChatMessageCopyText', () => {
)
expect(nativeChatMessageCopyText({ role: 'user', blocks: [{ type: 'text', text }] })).toBe(text)
})
it('copies the stopped-before-start notice in the caller’s words', () => {
const blocks = [
{
type: 'text' as const,
text: NATIVE_CHAT_STOPPED_BEFORE_START_TEXT,
presentation: NATIVE_CHAT_STOPPED_BEFORE_START_PRESENTATION
}
]
expect(nativeChatMessageCopyText({ role: 'assistant', blocks }, 'Arrêté')).toBe('Arrêté')
})
})
@@ -1,38 +0,0 @@
import { describe, expect, it } from 'vitest'
import {
nativeChatModelPillLabel,
sayNativeChatSessionOptionEnglish as say
} from './native-chat-session-option-labels'
import type { SessionOptionDescriptor } from './native-chat/input/native-chat-session-options'
function modelDescriptor(
valueSource: SessionOptionDescriptor['valueSource'],
currentValue?: string
): SessionOptionDescriptor {
return {
id: 'model',
label: 'Model',
valueSource,
transport: 'catalog',
settable: true,
kind: {
type: 'select',
...(currentValue ? { currentValue } : {}),
choices: [{ value: 'grok-4.5', label: 'Grok 4.5' }]
}
}
}
describe('nativeChatModelPillLabel', () => {
it('withholds a value it has no evidence for', () => {
expect(nativeChatModelPillLabel(modelDescriptor('unknown', 'grok-4.5'), say)).toBe('Model')
expect(nativeChatModelPillLabel(modelDescriptor('default'), say)).toBe('Model')
})
it('falls back to the raw id when the list no longer offers it', () => {
// Keep naming a tracked model after discovery drops it; the running selection is still known.
expect(nativeChatModelPillLabel(modelDescriptor('reported', 'grok-build'), say)).toBe(
'grok-build'
)
})
})
@@ -36,34 +36,6 @@ function discovery(owner: string | null, rootPath = '/Users/test/.agents/skills'
}
describe('isNativeChatSkillForAgent', () => {
it('shows Codex-native and generic agent skills for Codex chat', () => {
expect(isNativeChatSkillForAgent('codex', skill({ providers: ['codex'] }))).toBe(true)
expect(isNativeChatSkillForAgent('codex', skill({ providers: ['agent-skills'] }))).toBe(true)
})
it('keeps Claude skills out of the Codex skill picker', () => {
expect(isNativeChatSkillForAgent('codex', skill({ providers: ['claude'] }))).toBe(false)
})
it('does not enable skill autocomplete for other agents yet', () => {
expect(isNativeChatSkillForAgent('claude', skill({ providers: ['agent-skills'] }))).toBe(false)
})
it('uses explicit source ownership and keeps shared roots visible', () => {
const shared = discovery(null)
expect(isNativeChatSkillForAgent('codex', skill({}), shared)).toBe(true)
expect(isNativeChatSkillForAgent('claude', skill({}), shared)).toBe(true)
expect(isNativeChatSkillForAgent('grok', skill({}), shared)).toBe(true)
})
it('aliases OpenClaude to Claude roots without exposing them to other agents', () => {
const claude = discovery('claude')
expect(isNativeChatSkillForAgent('claude', skill({}), claude)).toBe(true)
expect(isNativeChatSkillForAgent('openclaude', skill({}), claude)).toBe(true)
expect(isNativeChatSkillForAgent('codex', skill({}), claude)).toBe(false)
expect(isNativeChatSkillForAgent('grok', skill({}), claude)).toBe(false)
})
it('shows OpenCode the Claude skill folders it reads, and not Claude plugins', () => {
const claude = discovery('claude')
expect(isNativeChatSkillForAgent('opencode', skill({}), claude)).toBe(true)
@@ -7,15 +7,6 @@ import {
} from './structured-agent-session-option-pick-book'
describe('structured option pick commits', () => {
it('commits all returned values for the latest write', () => {
const book = createStructuredOptionPickBook()
const pick = beginStructuredOptionPick(book, 'model', 'opus', false)
expect(structuredOptionPickCommit(book, pick, { model: 'opus', effort: 'high' })).toEqual({
model: 'opus',
effort: 'high'
})
})
it('commits only its own option when another option was picked since', () => {
const book = createStructuredOptionPickBook()
const model = beginStructuredOptionPick(book, 'model', 'opus', false)
@@ -125,33 +125,6 @@ describe('structured agent session options', () => {
expect(model.kind.type === 'select' ? model.kind.currentValue : null).toBe('persisted-unknown')
})
it('projects live options as directly settable descriptors', () => {
const state = applyStructuredAgentSessionOptions(
createStructuredAgentSessionOptionState('codex'),
CODEX_SESSION_OPTION_CATALOG,
{
models: [
{
id: 'account-model',
label: 'Account Model',
isDefault: true,
defaultEffort: 'medium',
efforts: [
{ value: 'medium', label: 'Medium' },
{ value: 'high', label: 'High' }
]
}
],
current: { model: 'account-model', effort: 'medium' }
}
)
const snapshot = structuredAgentSessionOptionSnapshot(state)
expect(snapshot.map((descriptor) => descriptor.id)).toEqual(['model', 'effort'])
expect(snapshot.every((descriptor) => descriptor.settable)).toBe(true)
expect(snapshot.every((descriptor) => descriptor.action === undefined)).toBe(true)
})
it('projects Fast mode only from positive session and model capability', () => {
const supported = applyStructuredAgentSessionOptions(
createStructuredAgentSessionOptionState('codex'),
@@ -3,8 +3,6 @@ import type { AgentSessionOptionsResult } from './agent-session-wire'
import { sortNativeChatSessionOptions } from './native-chat/input/native-chat-session-option-snapshot'
import {
applyStructuredAgentSessionOptions,
commitStructuredAgentSessionOption,
commitStructuredAgentSessionOptionValues,
createStructuredAgentSessionOptionState,
structuredAgentSessionOptionPicks,
structuredAgentSessionOptionSnapshot
@@ -75,45 +73,6 @@ describe('the permission mode picker', () => {
})
})
it('shows nothing for a host that states no mode, or an agent with none', () => {
expect(permission(live('codex', {}))).toBeUndefined()
expect(permission(live('pi', { permissionMode: 'ask' }))).toBeUndefined()
})
it("offers Codex's three modes with its own descriptions", () => {
const descriptor = permission(live('codex', { permissionMode: 'ask' }))
expect(descriptor?.kind.type === 'select' && descriptor.kind.choices).toEqual([
{
value: 'ask',
label: 'Ask for approval',
description: "Asks before edits or commands it isn't already allowed to make"
},
{ value: 'auto', label: 'Approve for me', description: 'Reviews approval requests for you' },
{
value: 'full-access',
label: 'Full access',
description: 'Never asks; can edit any file and use the network'
}
])
})
it('offers all Claude modes regardless of catalog support, and shows the host mode as stated', () => {
const unsupported = permission(live('claude', { permissionMode: 'ask' }, false))
expect(
unsupported?.kind.type === 'select' && unsupported.kind.choices.map((c) => c.value)
).toEqual(['ask', 'accept-edits', 'auto', 'full-access'])
expect(permission(live('claude', { permissionMode: 'auto' }, false))).toMatchObject({
kind: { currentValue: 'auto' }
})
const state = createStructuredAgentSessionOptionState('claude')
const descriptor = permission(
structuredAgentSessionOptionView(state, { permissionMode: 'ask' }, {})
)
expect(
descriptor?.kind.type === 'select' && descriptor.kind.choices.map((c) => c.value)
).toContain('auto')
})
it("shows a held pick over the host's value, and the host's over the seed", () => {
const state = live('codex', { permissionMode: 'auto' })
const seed = { permissionMode: 'ask' }
@@ -125,19 +84,6 @@ describe('the permission mode picker', () => {
).toMatchObject({ kind: { currentValue: 'full-access' } })
})
it('takes a settled pick, and the record a write answers with', () => {
const state = live('codex', { permissionMode: 'ask' })
expect(commitStructuredAgentSessionOption(state, 'permissionMode', 'auto').permissionMode).toBe(
'auto'
)
expect(
commitStructuredAgentSessionOptionValues(state, {
model: 'model-a',
permissionMode: 'full-access'
}).permissionMode
).toBe('full-access')
})
it('stays out of the per-model option pill and out of the saved selection', () => {
const state = live('codex', { permissionMode: 'ask' })
expect(
@@ -1,37 +0,0 @@
import { describe, expect, it } from 'vitest'
import { structuredConversationCommandHold } from './structured-conversation-command-hold'
describe('a conversation command held on this side', () => {
const idle = {
waitsInLine: false,
agentWorking: false,
promptPending: false,
backgroundTasksRunning: false,
sendPending: false
}
it('is held here only by a message the host does not have yet, or background work', () => {
const inLine = { ...idle, waitsInLine: true }
expect(
structuredConversationCommandHold({
...inLine,
agentWorking: true,
promptPending: true
})
).toBeNull()
expect(structuredConversationCommandHold({ ...inLine, sendPending: true })).toBe('ahead')
expect(structuredConversationCommandHold({ ...inLine, backgroundTasksRunning: true })).toBe(
'background'
)
})
it('against a host that cannot hold it, and for /clear, keeps every check in true words', () => {
expect(structuredConversationCommandHold(idle)).toBeNull()
expect(structuredConversationCommandHold({ ...idle, agentWorking: true })).toBe('working')
expect(structuredConversationCommandHold({ ...idle, sendPending: true })).toBe('sending')
expect(
structuredConversationCommandHold({ ...idle, agentWorking: true, sendPending: true })
).toBe('working')
expect(structuredConversationCommandHold({ ...idle, promptPending: true })).toBe('prompt')
})
})
@@ -1,196 +0,0 @@
import { writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { describe, expect, it } from 'vitest'
import {
resolveCanonicalPaneAgentIdentity,
type CanonicalPaneAgentIdentity
} from './pane-agent-identity-adapter'
import { resolveTabAgentFromSignals } from './tab-agent-from-signals'
import type { TuiAgent } from './tui-agent'
const AGENTS: readonly TuiAgent[] = ['claude', 'codex']
const SLOT_COUNT = 7
const COMBINATION_COUNT = 3 ** SLOT_COUNT * 4 * 2
const TITLES: readonly string[] = ['', 'zsh', 'Task - claude', 'Task - codex']
type Breakdown = Record<
'launch' | 'completed-hook' | 'sleeping-session' | 'process' | 'sibling' | 'title',
number
>
function slotValues(mask: number): (TuiAgent | null)[] {
let remaining = mask
return Array.from({ length: SLOT_COUNT }, () => {
const value = remaining % 3
remaining = Math.floor(remaining / 3)
return value === 0 ? null : AGENTS[value - 1]
})
}
function canonicalResult(
values: readonly (TuiAgent | null)[],
title: string,
withProof: boolean
): CanonicalPaneAgentIdentity {
const [hook, siblingHook, completed, siblingCompleted, process, sleeping, launch] = values
return resolveCanonicalPaneAgentIdentity({
hookAgent: hook,
hookIsLive: hook !== null,
completedHookAgent: completed,
launchAgent: launch,
foregroundAgent: process,
processProof:
withProof && process
? {
agent: process,
processIncarnation: 'fixture-process',
authorityId: 'fixture-authority',
capturedAgeMs: 10,
validForMs: 1_000
}
: undefined,
sleepingSessionAgent: sleeping,
siblingAgents: [siblingHook, siblingCompleted].filter(
(agent): agent is TuiAgent => agent !== null
),
allowSibling: true,
title
})
}
function realResult(values: readonly (TuiAgent | null)[], title: string, remote: boolean) {
const [hook, siblingHook, completed, siblingCompleted, process, sleeping, launch] = values
// Hold the runtime memory bit true; the approved 17,496 steady-state shapes cover seven other slots.
return resolveTabAgentFromSignals({
hasObservedAgentSignal: true,
isRemote: remote,
title,
hookAgent: hook,
siblingHookAgent: siblingHook,
focusedCompletedHookAgent: completed,
siblingCompletedHookAgent: siblingCompleted,
processAgent: process,
processShellForeground: false,
sleepingSessionAgent: sleeping,
launchAgent: launch ?? undefined
})
}
function runDecisionTable(withProof: boolean) {
let disagreements = 0
let flipped = 0
const breakdown: Breakdown = {
launch: 0,
'completed-hook': 0,
'sleeping-session': 0,
process: 0,
sibling: 0,
title: 0
}
for (let mask = 0; mask < 3 ** SLOT_COUNT; mask += 1) {
const values = slotValues(mask)
for (const title of TITLES) {
for (const remote of [false, true]) {
const real = realResult(values, title, remote)
const canonical = canonicalResult(values, title, withProof)
if (real !== canonical.agent) {
disagreements += 1
if (canonical.source !== null) {
breakdown[canonical.source] += 1
}
}
if (!withProof) {
const proven = canonicalResult(values, title, true)
if (
canonical.agent !== proven.agent &&
proven.source === 'process' &&
(canonical.source === 'launch' ||
canonical.source === 'completed-hook' ||
canonical.source === 'sleeping-session')
) {
flipped += 1
}
}
}
}
}
return { disagreements, flipped, breakdown }
}
describe('renderer ladder decision table', () => {
it('replays the real shipping ladder and records all rung disagreements', () => {
const proofFree = runDecisionTable(false)
const freshProof = runDecisionTable(true)
const result = {
combinations: COMBINATION_COUNT,
proofOmitted: proofFree,
freshProof,
flippedByAddingProof: proofFree.flipped
}
writeFileSync(
join(tmpdir(), 'orca-pane-agent-identity-decision-table-real.json'),
`${JSON.stringify(result, null, 2)}\n`
)
// Re-derived against resolveTabAgentFromSignals (not a hand-written model).
expect(proofFree).toEqual({
disagreements: 2_622,
flipped: 1_872,
breakdown: {
launch: 1_884,
'completed-hook': 478,
'sleeping-session': 144,
process: 0,
sibling: 54,
title: 6
}
})
expect(freshProof).toEqual({
disagreements: 658,
flipped: 0,
breakdown: {
launch: 588,
'completed-hook': 46,
'sleeping-session': 0,
process: 0,
sibling: 6,
title: 2
}
})
expect(proofFree.flipped).toBe(1_872)
})
it('requires both freshness fields before process evidence can change the no-proof result', () => {
const values = [null, null, null, null, 'codex', null, 'claude'] as const
expect(canonicalResult(values, '', false)).toMatchObject({
agent: 'claude',
source: 'launch'
})
expect(
resolveCanonicalPaneAgentIdentity({
foregroundAgent: 'codex',
processProof: {
agent: 'codex',
processIncarnation: 'fixture-process',
authorityId: 'fixture-authority',
capturedAgeMs: undefined as unknown as number,
validForMs: 1_000
},
launchAgent: 'claude'
})
).toMatchObject({ agent: 'claude', source: 'launch' })
expect(
resolveCanonicalPaneAgentIdentity({
foregroundAgent: 'codex',
processProof: {
agent: 'codex',
processIncarnation: 'fixture-process',
authorityId: 'fixture-authority',
capturedAgeMs: 10,
validForMs: undefined as unknown as number
},
launchAgent: 'claude'
})
).toMatchObject({ agent: 'claude', source: 'launch' })
})
})
@@ -2,7 +2,6 @@ import { describe, expect, it } from 'vitest'
import { getAgentLabel as getSharedAgentLabel } from './agent-title-identity'
import { isOpenCodeNativeTitle } from './opencode-terminal-title'
import {
isClaudeAgent,
isClaudeIdentityFrameTitle,
isGrokRotatingWorkingTitle,
resolveExplicitTerminalTitleAgentType,
@@ -37,20 +36,6 @@ describe('isGrokRotatingWorkingTitle', () => {
})
describe('resolveExplicitTerminalTitleAgentType', () => {
it('maps explicit product-name titles to their TuiAgent id', () => {
expect(resolveExplicitTerminalTitleAgentType('✳ Claude Code')).toBe('claude')
expect(resolveExplicitTerminalTitleAgentType('⠋ Codex')).toBe('codex')
expect(resolveExplicitTerminalTitleAgentType('✦ Gemini CLI')).toBe('gemini')
expect(resolveExplicitTerminalTitleAgentType('MiMo Code')).toBe('mimo-code')
expect(resolveExplicitTerminalTitleAgentType('⠋ OpenClaude')).toBe('openclaude')
expect(resolveExplicitTerminalTitleAgentType('OMP')).toBe('omp')
})
it('reads Pi/OMP identity only from the leading brand', () => {
expect(resolveExplicitTerminalTitleAgentType('⠂ OMP: fix title detection')).toBeNull()
expect(resolveExplicitTerminalTitleAgentType('Fix Pi > OMP routing - grok')).toBe('grok')
})
it('treats Claude generic status prefixes as activity-only, not identity', () => {
expect(resolveExplicitTerminalTitleAgentType('✳ investigating startup')).toBeNull()
expect(resolveExplicitTerminalTitleAgentType('⠸ investigating startup')).toBeNull()
@@ -77,22 +62,6 @@ describe('resolveExplicitTerminalTitleAgentType', () => {
expect(resolveExplicitTerminalTitleAgentType('⠋ Fix foo | OC | bar')).toBeNull()
})
it('keeps other agents classified correctly alongside OpenCode native titles', () => {
expect(resolveExplicitTerminalTitleAgentType('✳ Claude Code')).toBe('claude')
expect(resolveExplicitTerminalTitleAgentType('⠋ Codex')).toBe('codex')
expect(resolveExplicitTerminalTitleAgentType('✦ Gemini CLI')).toBe('gemini')
expect(resolveExplicitTerminalTitleAgentType('Cursor Agent')).toBe('cursor')
expect(resolveExplicitTerminalTitleAgentType('Pi ready')).toBe('pi')
expect(resolveExplicitTerminalTitleAgentType('OpenCode ready')).toBe('opencode')
expect(resolveTerminalTitleAgentType('OC | ⠋ implementing the feature')).toBe('opencode')
expect(isClaudeAgent('OC | ⠋ implementing the feature')).toBe(false)
expect(isClaudeAgent('OC | Understand about the plugin')).toBe(false)
})
it('still resolves Claude when the title explicitly names Claude', () => {
expect(resolveExplicitTerminalTitleAgentType('. Claude Code compare Opencode')).toBe('claude')
})
// Only explicit Claude identity may replace the owner; task-text mentions do not prove identity (#8940).
it('separates Claude identity frames from an incidental claude token', () => {
for (const title of [
@@ -123,11 +92,6 @@ describe('resolveExplicitTerminalTitleAgentType', () => {
}
})
it('returns null for plain shell and unknown titles', () => {
expect(resolveExplicitTerminalTitleAgentType('Terminal 1')).toBeNull()
expect(resolveExplicitTerminalTitleAgentType('zsh')).toBeNull()
})
// cursor is ordinary task vocabulary; only Cursor’s identity frames can claim the pane.
it('resolves Cursor by its identity titles, never a bare cursor token', () => {
expect(resolveExplicitTerminalTitleAgentType('Cursor Agent')).toBe('cursor')
@@ -155,13 +119,3 @@ describe('resolveTerminalTitleAgentType', () => {
expect(resolveTerminalTitleAgentType('⠋ Codex: fix cursor offsets')).toBe('codex')
})
})
// Pin this module’s parallel isClaudeAgent guard directly so it cannot drift from agent-title-identity.ts.
describe('isClaudeAgent', () => {
it('excludes real Cursor identity titles, keeps cursor-mentioning Claude braille titles', () => {
expect(isClaudeAgent('⠋ Cursor Agent')).toBe(false)
expect(isClaudeAgent('Cursor ready')).toBe(false)
expect(isClaudeAgent('⠋ preserve cursor visibility across replays')).toBe(true)
expect(isClaudeAgent('⠋ OpenClaude')).toBe(false)
})
})
-391
View File
@@ -1,7 +1,6 @@
import { describe, expect, it } from 'vitest'
import {
isRecentTabSwitcherCommitRelease,
isWindowShortcutModifierChord,
matchesRecentTabSwitcherChord,
resolveWindowShortcutAction,
type WindowShortcutAction,
@@ -59,59 +58,6 @@ describe('resolveWindowShortcutAction', () => {
}
)
it('resolves the explicit window shortcut allowlist on macOS', () => {
expect(
resolveWindowShortcutAction(
{ code: 'KeyJ', key: 'j', meta: true, control: false, alt: false, shift: false },
'darwin'
)
).toEqual({ type: 'toggleWorktreePalette' })
expect(
resolveWindowShortcutAction(
{ code: 'KeyP', key: 'p', meta: true, control: false, alt: false, shift: false },
'darwin'
)
).toEqual({ type: 'openQuickOpen' })
expect(
resolveWindowShortcutAction(
{ code: 'Digit3', key: '3', meta: true, control: false, alt: false, shift: false },
'darwin'
)
).toEqual({ type: 'jumpToWorktreeIndex', index: 2 })
expect(
resolveWindowShortcutAction(
{ code: 'Digit3', key: '3', meta: false, control: true, alt: false, shift: false },
'darwin'
)
).toEqual({ type: 'jumpToTabIndex', index: 2 })
})
it('uses Alt+number for tab jumps on Windows/Linux without stealing workspace jumps', () => {
expect(
resolveWindowShortcutAction(
{ code: 'Digit4', key: '4', meta: false, control: true, alt: false, shift: false },
'linux'
)
).toEqual({ type: 'jumpToWorktreeIndex', index: 3 })
expect(
resolveWindowShortcutAction(
{ code: 'Digit4', key: '4', meta: false, control: false, alt: true, shift: false },
'linux'
)
).toEqual({ type: 'jumpToTabIndex', index: 3 })
expect(
resolveWindowShortcutAction(
{ code: 'Digit4', key: '4', meta: false, control: false, alt: true, shift: true },
'win32'
)
).toBeNull()
})
it('resolves customized quick-command menu shortcuts with terminal policy gating', () => {
const input: WindowShortcutInput = {
code: 'KeyQ',
@@ -273,82 +219,6 @@ describe('resolveWindowShortcutAction', () => {
).toEqual({ type: 'jumpToTabIndex', index: 2 })
})
it('does not resolve the removed PDF export shortcut globally', () => {
expect(
resolveWindowShortcutAction(
{ code: 'KeyE', key: 'e', meta: true, control: false, alt: false, shift: true },
'darwin'
)
).toBeNull()
})
it('routes menu-backed actions through the same window shortcut policy', () => {
expect(
resolveWindowShortcutAction(
{ code: 'KeyR', key: 'r', meta: false, control: true, alt: false, shift: true },
'linux'
)
).toEqual({ type: 'forceReload' })
expect(
resolveWindowShortcutAction(
{ code: 'KeyR', key: 'r', meta: false, control: true, alt: false, shift: true },
'linux',
undefined,
{ context: 'terminal', terminalShortcutPolicy: 'terminal-first' }
)
).toBeNull()
})
it('requires shift for the non-mac worktree palette shortcut', () => {
expect(
resolveWindowShortcutAction(
{ code: 'KeyJ', key: 'j', meta: false, control: true, alt: false, shift: false },
'win32'
)
).toBeNull()
expect(
resolveWindowShortcutAction(
{ code: 'KeyJ', key: 'j', meta: false, control: true, alt: false, shift: true },
'win32'
)
).toEqual({ type: 'toggleWorktreePalette' })
})
it('resolves dictation using the layout-aware key value', () => {
expect(
resolveWindowShortcutAction(
{ code: 'KeyD', key: 'e', meta: true, control: false, alt: false, shift: false },
'darwin'
)
).toEqual({ type: 'dictationKeyDown' })
expect(
resolveWindowShortcutAction(
{ code: 'KeyE', key: 'd', meta: true, control: false, alt: false, shift: false },
'darwin'
)
).toBeNull()
})
it('applies custom keybinding overrides to dictation and main-process shortcuts', () => {
expect(
resolveWindowShortcutAction(
{ code: 'KeyE', key: 'e', meta: false, control: true, alt: false, shift: false },
'linux',
{ 'voice.dictation': [] }
)
).toBeNull()
expect(
resolveWindowShortcutAction(
{ code: 'KeyY', key: 'y', meta: false, control: true, alt: false, shift: true },
'linux',
{ 'voice.dictation': ['Mod+Shift+Y'] }
)
).toEqual({ type: 'dictationKeyDown' })
})
it('applies custom keybinding overrides to main-process shortcuts', () => {
const overrides: KeybindingOverrides = {
'worktree.quickOpen': ['Mod+Shift+O'],
@@ -413,15 +283,6 @@ describe('resolveWindowShortcutAction', () => {
).toEqual({ type: 'deleteCurrentWorkspace' })
})
it('resolves the MRU tab quick-toggle chord', () => {
expect(
resolveWindowShortcutAction(
{ code: 'Tab', key: 'Tab', meta: false, control: true, alt: false, shift: false },
'linux'
)
).toEqual({ type: 'switchRecentTab' })
})
it('gates the held Ctrl+Tab switcher on the configurable binding', () => {
const input = { code: 'Tab', key: 'Tab', meta: false, control: true, alt: false, shift: true }
const domInput = {
@@ -540,80 +401,6 @@ describe('resolveWindowShortcutAction', () => {
).toBeNull()
})
it('resolves the worktree-history chord despite carrying Alt', () => {
expect(
resolveWindowShortcutAction(
{
code: 'ArrowLeft',
key: 'ArrowLeft',
meta: true,
control: false,
alt: true,
shift: false
},
'darwin'
)
).toEqual({ type: 'worktreeHistoryNavigate', direction: 'back' })
expect(
resolveWindowShortcutAction(
{
code: 'ArrowRight',
key: 'ArrowRight',
meta: true,
control: false,
alt: true,
shift: false
},
'darwin'
)
).toEqual({ type: 'worktreeHistoryNavigate', direction: 'forward' })
expect(
resolveWindowShortcutAction(
{
code: 'ArrowLeft',
key: 'ArrowLeft',
meta: false,
control: true,
alt: true,
shift: false
},
'linux'
)
).toEqual({ type: 'worktreeHistoryNavigate', direction: 'back' })
})
it('resolves the floating terminal chord despite carrying Alt', () => {
expect(
resolveWindowShortcutAction(
{
code: 'KeyA',
key: 'a',
meta: true,
control: false,
alt: true,
shift: false
},
'darwin'
)
).toEqual({ type: 'toggleFloatingTerminal' })
expect(
resolveWindowShortcutAction(
{
code: 'KeyA',
key: 'a',
meta: false,
control: true,
alt: true,
shift: false
},
'linux'
)
).toEqual({ type: 'toggleFloatingTerminal' })
})
it('resolves the floating terminal chord when macOS Option composes the letter', () => {
expect(
resolveWindowShortcutAction(
@@ -630,172 +417,6 @@ describe('resolveWindowShortcutAction', () => {
).toEqual({ type: 'toggleFloatingTerminal' })
})
it('rejects floating terminal chord variants with Shift or opposite primary modifier', () => {
expect(
resolveWindowShortcutAction(
{
code: 'KeyA',
key: 'a',
meta: true,
control: false,
alt: true,
shift: true
},
'darwin'
)
).toBeNull()
expect(
resolveWindowShortcutAction(
{
code: 'KeyA',
key: 'a',
meta: true,
control: true,
alt: true,
shift: false
},
'linux'
)
).toBeNull()
})
it('rejects the history chord when Shift is also held', () => {
expect(
resolveWindowShortcutAction(
{
code: 'ArrowLeft',
key: 'ArrowLeft',
meta: true,
control: false,
alt: true,
shift: true
},
'darwin'
)
).toBeNull()
})
it('leaves Alt+Arrow without a primary modifier untouched (word-nav territory)', () => {
expect(
resolveWindowShortcutAction(
{
code: 'ArrowLeft',
key: 'ArrowLeft',
meta: false,
control: false,
alt: true,
shift: false
},
'darwin'
)
).toBeNull()
})
it('ignores Cmd/Ctrl+Alt combined with ArrowUp or ArrowDown', () => {
// Leave primary+Alt+Up/Down to renderer/PTTY shell handling; history claims only Left/Right.
expect(
resolveWindowShortcutAction(
{
code: 'ArrowUp',
key: 'ArrowUp',
meta: true,
control: false,
alt: true,
shift: false
},
'darwin'
)
).toBeNull()
expect(
resolveWindowShortcutAction(
{
code: 'ArrowDown',
key: 'ArrowDown',
meta: false,
control: true,
alt: true,
shift: false
},
'linux'
)
).toBeNull()
})
it('rejects the history chord when the opposite primary modifier is also held', () => {
// Do not intercept Cmd+Ctrl+Alt on macOS or Ctrl+Meta+Alt on Linux: they collide with OS workspace switching.
expect(
resolveWindowShortcutAction(
{
code: 'ArrowLeft',
key: 'ArrowLeft',
meta: true,
control: true,
alt: true,
shift: false
},
'darwin'
)
).toBeNull()
expect(
resolveWindowShortcutAction(
{
code: 'ArrowRight',
key: 'ArrowRight',
meta: true,
control: true,
alt: true,
shift: false
},
'linux'
)
).toBeNull()
})
it('still returns null for other Cmd/Ctrl+Alt combos (not an allowlist escape)', () => {
// History’s special branch must not claim unrelated primary+Alt chords without an explicit new action.
expect(
resolveWindowShortcutAction(
{
code: 'KeyY',
key: 'y',
meta: true,
control: false,
alt: true,
shift: false
},
'darwin'
)
).toBeNull()
})
it('routes Cmd/Ctrl+Shift+N to the unified new-workspace composer', () => {
// Preserve the old Create-from chord; the unified composer now switches sources in its name field.
expect(
resolveWindowShortcutAction(
{ code: 'KeyN', key: 'n', meta: true, control: false, alt: false, shift: true },
'darwin'
)
).toEqual({ type: 'openNewWorkspace' })
expect(
resolveWindowShortcutAction(
{ code: 'KeyN', key: 'n', meta: false, control: true, alt: false, shift: true },
'linux'
)
).toEqual({ type: 'openNewWorkspace' })
// Keep Alt chords unclaimed for future actions.
expect(
resolveWindowShortcutAction(
{ code: 'KeyN', key: 'n', meta: true, control: false, alt: true, shift: true },
'darwin'
)
).toBeNull()
})
it('resolves letter shortcuts by layout-aware key, with code as fallback', () => {
// Prefer layout-aware letter keys over physical QWERTY codes; only empty/nonletter IME/dead-key values need code fallback.
@@ -848,18 +469,6 @@ describe('resolveWindowShortcutAction', () => {
}
})
it('exposes the shared platform modifier gate used by browser guests', () => {
expect(
isWindowShortcutModifierChord({ meta: true, control: false, alt: false }, 'darwin')
).toBe(true)
expect(isWindowShortcutModifierChord({ meta: false, control: true, alt: false }, 'linux')).toBe(
true
)
expect(isWindowShortcutModifierChord({ meta: false, control: true, alt: true }, 'linux')).toBe(
false
)
})
it('resolves an allowlisted action from a synthetic double-tap input', () => {
const overrides: KeybindingOverrides = { 'worktree.quickOpen': ['DoubleTap+Shift'] }
expect(
-133
View File
@@ -1,9 +1,5 @@
import { describe, expect, it } from 'vitest'
import {
WORKSPACE_BOARD_COLUMN_WIDTH_DEFAULT,
WORKSPACE_BOARD_COLUMN_WIDTH_MAX,
WORKSPACE_BOARD_COLUMN_WIDTH_MIN,
clampWorkspaceBoardColumnWidth,
cloneDefaultWorkspaceStatuses,
normalizePersistedWorkspaceStatuses,
normalizeWorkspaceStatuses
@@ -21,17 +17,6 @@ describe('workspace status visuals', () => {
)
})
it('keeps the default workflow order', () => {
expect(cloneDefaultWorkspaceStatuses().map((status) => status.id)).toEqual([
'todo',
'in-progress',
'in-review',
'completed'
])
expect(cloneDefaultWorkspaceStatuses()[0]).toMatchObject({ id: 'todo', label: 'Todo' })
expect(cloneDefaultWorkspaceStatuses().at(-1)).toMatchObject({ id: 'completed', label: 'Done' })
})
it('migrates legacy default statuses to the default workflow order', () => {
const statuses = normalizePersistedWorkspaceStatuses(
[
@@ -56,31 +41,6 @@ describe('workspace status visuals', () => {
expect(statuses).toEqual(cloneDefaultWorkspaceStatuses())
})
it('migrates the old default status visuals without reordering the board', () => {
const statuses = normalizePersistedWorkspaceStatuses(
[
{ id: 'todo', label: 'Todo', color: 'neutral', icon: 'circle' },
{ id: 'in-progress', label: 'In progress', color: 'blue', icon: 'circle-dot' },
{ id: 'in-review', label: 'In review', color: 'violet', icon: 'git-pull-request' },
{ id: 'completed', label: 'Completed', color: 'emerald', icon: 'circle-check' }
],
{ migrateLegacyDefaultStatusVisuals: true }
)
expect(statuses.map((status) => status.id)).toEqual([
'todo',
'in-progress',
'in-review',
'completed'
])
expect(statuses.map((status) => status.color)).toEqual([
'neutral',
'conductor-progress',
'conductor-review',
'conductor-done'
])
})
it('preserves explicit status order while migrating default visuals', () => {
const statuses = normalizePersistedWorkspaceStatuses(
[
@@ -104,27 +64,6 @@ describe('workspace status visuals', () => {
})
})
it('preserves default-label reordered statuses unless a default migration is requested', () => {
const statuses = normalizePersistedWorkspaceStatuses([
{ id: 'completed', label: 'Completed', color: 'conductor-done', icon: 'conductor-done' },
{ id: 'in-review', label: 'In review', color: 'conductor-review', icon: 'conductor-review' },
{
id: 'in-progress',
label: 'In progress',
color: 'conductor-progress',
icon: 'conductor-progress'
},
{ id: 'todo', label: 'Todo', color: 'neutral', icon: 'circle' }
])
expect(statuses.map((status) => status.id)).toEqual([
'completed',
'in-review',
'in-progress',
'todo'
])
})
it('migrates exact reordered default statuses to the new Done label when requested', () => {
const statuses = normalizePersistedWorkspaceStatuses(
[
@@ -173,30 +112,6 @@ describe('workspace status visuals', () => {
expect(statuses).toEqual(cloneDefaultWorkspaceStatuses())
})
it('repairs the exact reordered default status payload with the Done label', () => {
const statuses = normalizePersistedWorkspaceStatuses(
[
{ id: 'completed', label: 'Done', color: 'conductor-done', icon: 'conductor-done' },
{
id: 'in-review',
label: 'In review',
color: 'conductor-review',
icon: 'conductor-review'
},
{
id: 'in-progress',
label: 'In progress',
color: 'conductor-progress',
icon: 'conductor-progress'
},
{ id: 'todo', label: 'Todo', color: 'neutral', icon: 'circle' }
],
{ repairReorderedDefaultStatuses: true }
)
expect(statuses).toEqual(cloneDefaultWorkspaceStatuses())
})
it('does not repair reordered default-label statuses with a different raw shape', () => {
const statuses = normalizePersistedWorkspaceStatuses(
[
@@ -216,47 +131,6 @@ describe('workspace status visuals', () => {
])
})
it('leaves custom persisted status layouts in their saved order', () => {
const statuses = normalizePersistedWorkspaceStatuses([
{ id: 'completed', label: 'Shipped', color: 'conductor-done', icon: 'conductor-done' },
{ id: 'todo', label: 'Todo', color: 'neutral', icon: 'circle' }
])
expect(statuses.map((status) => status.id)).toEqual(['completed', 'todo'])
})
it('uses Conductor-style visuals for the default status icons', () => {
const statuses = cloneDefaultWorkspaceStatuses()
const inProgress = statuses.find((status) => status.id === 'in-progress')
const inReview = statuses.find((status) => status.id === 'in-review')
const completed = statuses.find((status) => status.id === 'completed')
expect(inProgress).toMatchObject({
color: 'conductor-progress',
icon: 'conductor-progress'
})
expect(inReview).toMatchObject({
color: 'conductor-review',
icon: 'conductor-review'
})
expect(completed).toMatchObject({
color: 'conductor-done',
icon: 'conductor-done'
})
})
it('migrates the old in-progress blue dot default only when requested', () => {
const statuses = normalizePersistedWorkspaceStatuses(
[{ id: 'in-progress', label: 'In progress', color: 'blue', icon: 'circle-dot' }],
{ migrateLegacyDefaultStatusVisuals: true }
)
expect(statuses[0]).toMatchObject({
color: 'conductor-progress',
icon: 'conductor-progress'
})
})
it('preserves valid legacy visuals for default-label statuses at runtime', () => {
const statuses = normalizeWorkspaceStatuses([
{ id: 'in-progress', label: 'In progress', color: 'blue', icon: 'circle-dot' }
@@ -275,11 +149,4 @@ describe('workspace status visuals', () => {
expect(status.label).toBe('a'.repeat(31))
})
it('clamps workspace board column widths to resizable bounds', () => {
expect(clampWorkspaceBoardColumnWidth(undefined)).toBe(WORKSPACE_BOARD_COLUMN_WIDTH_DEFAULT)
expect(clampWorkspaceBoardColumnWidth(100)).toBe(WORKSPACE_BOARD_COLUMN_WIDTH_MIN)
expect(clampWorkspaceBoardColumnWidth(321.6)).toBe(322)
expect(clampWorkspaceBoardColumnWidth(900)).toBe(WORKSPACE_BOARD_COLUMN_WIDTH_MAX)
})
})