test: remove 88 low-value test declarations (#37280)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
OrcaWin
2026-11-01 18:47:57 -08:00
committed by GitHub
co-authored by OrcaWin
parent bf0f819a31
commit a29461bc15
30 changed files with 2 additions and 951 deletions
@@ -138,10 +138,6 @@ describe.runIf(process.platform === 'darwin')(
return failures
}
it('finds the holder on its terminal', () => {
expect(holderTty).toMatch(/^ttys\d+$/)
})
it.each([
['full snapshot', PS_ARGS, UTF8],
['full snapshot (tdev)', ['-axo', PS_ARGS[1].replace('tty=', 'tdev=')], UTF8],
@@ -2,15 +2,11 @@ import { describe, expect, it } from 'vitest'
import {
applyMentionSuggestion,
applyPickerSuggestion,
applySlashSuggestion,
buildNativeChatPickerItems,
classifyNativeChatSend,
deriveComposerAutocomplete,
editReplacesTriggerToken,
filterSlashCommands,
isSkillPickerTriggered,
isSlashCommandDraft,
slashCommandDispatchText,
type SlashCommandSuggestion
} from './native-chat-composer-autocomplete'
import { sessionSlashCommandSuggestions } from './native-chat/input/native-chat-slash-commands'
@@ -252,29 +248,7 @@ describe('deriveComposerAutocomplete — one grammar for every agent', () => {
})
})
describe('filterSlashCommands', () => {
it('is case-insensitive prefix match', () => {
expect(filterSlashCommands(COMMANDS, 'C').map((c) => c.name)).toEqual(['clear', 'compact'])
})
})
describe('isSlashCommandDraft', () => {
it('treats leading slash drafts as TUI commands, not chat prompts', () => {
expect(isSlashCommandDraft('/clear')).toBe(true)
expect(isSlashCommandDraft(' /compact')).toBe(true)
expect(isSlashCommandDraft('please run /clear')).toBe(false)
})
})
describe('apply suggestions', () => {
it('applySlashSuggestion replaces the token with a trailing space', () => {
expect(applySlashSuggestion({ name: 'clear' })).toBe('/clear ')
})
it('slashCommandDispatchText returns the command without completion whitespace', () => {
expect(slashCommandDispatchText({ name: 'clear' })).toBe('/clear')
})
it('applyMentionSuggestion replaces the active @token at the caret', () => {
const result = applyMentionSuggestion('open @sr more', 8, 'src/app.ts')
expect(result.draft).toBe('open @src/app.ts more')
@@ -433,22 +407,6 @@ describe('native skill and command picker', () => {
expect(result.caret).toBe('validate it with /electron '.length)
})
it('groups Claude commands and skills under slash', () => {
const result = deriveComposerAutocomplete(
'/',
1,
COMMANDS,
[skill({ name: 'browser' })],
getNativeChatAgentProfile('claude')
)
expect(result.mode).toBe('slash')
if (result.mode === 'slash') {
expect(result.grouped).toBe(true)
expect(result.items.map((item) => item.kind)).toContain('command')
expect(result.items.map((item) => item.kind)).toContain('skill')
}
})
it('lets a session report replace the disk scan and enrich the names it knows', () => {
const items = buildNativeChatPickerItems(
[],
@@ -1,7 +1,6 @@
import { describe, expect, it } from 'vitest'
import type { NativeChatMessage } from './native-chat/native-chat-types'
import {
isPendingMessageId,
pendingSendsAsMessages,
prunePendingSends,
type NativeChatPendingSend
@@ -527,19 +526,6 @@ describe('pendingSendsAsMessages', () => {
expect(pendingSendsAsMessages(pending, unreadableHistory)).toEqual([])
})
it('maps pending sends to prefixed scrape-source user messages sorted by sentAt', () => {
const messages = pendingSendsAsMessages([{ id: 'p1', text: 'queued text', sentAt: 42 }])
expect(messages).toEqual([
{
id: 'pending:p1',
role: 'user',
blocks: [{ type: 'text', text: 'queued text' }],
timestamp: 42,
source: 'scrape'
}
])
})
it('includes image refs for pending attachment sends', () => {
const messages = pendingSendsAsMessages([
{ id: 'p1', text: 'what do you see?', imagePaths: ['/tmp/shot.png'], sentAt: 42 }
@@ -638,10 +624,3 @@ describe('pendingSendsAsMessages', () => {
)
})
})
describe('isPendingMessageId', () => {
it('recognizes the pending id prefix', () => {
expect(isPendingMessageId('pending:p1')).toBe(true)
expect(isPendingMessageId('transcript-123')).toBe(false)
})
})
@@ -28,29 +28,6 @@ describe('native chat PTY session options', () => {
expect(surface.getSnapshot()).toEqual([])
})
it('renders the version-neutral seed picker before any host catalog arrives', () => {
const surface = createNativeChatPtySessionOptions({
agent: 'claude',
scopeKey: 'pty-1',
mode: 'live',
modelLabel: 'Model',
dispatchCommand: vi.fn()
})!
expect(surface.getSnapshot()[0]).toMatchObject({
id: 'model',
valueSource: 'unknown',
kind: {
choices: [
expect.objectContaining({ value: 'fable', label: 'Fable' }),
expect.objectContaining({ value: 'opus', label: 'Opus' }),
expect.objectContaining({ value: 'sonnet', label: 'Sonnet' }),
expect.objectContaining({ value: 'haiku', label: 'Haiku' })
]
}
})
})
it('uses model and effort reported by the live Claude terminal', () => {
const surface = createNativeChatPtySessionOptions({
agent: 'claude',
@@ -23,51 +23,6 @@ function claudeRecord(model?: string): NativeChatSessionOptionRecord {
}
describe('buildNativeChatSessionOptionCommand', () => {
it('builds the catalog midSession command for model and options', () => {
expect(
buildNativeChatSessionOptionCommand({
optionId: 'model',
value: 'opus',
apply: CLAUDE_SESSION_OPTION_CATALOG.modelApply,
modelId: null,
catalog: CLAUDE_SESSION_OPTION_CATALOG,
models: CLAUDE_SESSION_OPTION_CATALOG.models,
record: claudeRecord()
})
).toBe('/model opus')
const effortApply = CLAUDE_SESSION_OPTION_CATALOG.models
.find((model) => model.id === 'sonnet')!
.options.find((option) => option.id === 'effort')!.apply
expect(
buildNativeChatSessionOptionCommand({
optionId: 'effort',
value: 'high',
apply: effortApply,
modelId: 'sonnet',
catalog: CLAUDE_SESSION_OPTION_CATALOG,
models: CLAUDE_SESSION_OPTION_CATALOG.models,
record: claudeRecord('sonnet')
})
).toBe('/effort high')
})
it('returns the bare toggle command for flip-only options', () => {
const fastModeApply = CLAUDE_SESSION_OPTION_CATALOG.models
.find((model) => model.id === 'opus')!
.options.find((option) => option.id === 'fastMode')!.apply
expect(
buildNativeChatSessionOptionCommand({
optionId: 'fastMode',
value: true,
apply: fastModeApply,
modelId: 'opus',
catalog: CLAUDE_SESSION_OPTION_CATALOG,
models: CLAUDE_SESSION_OPTION_CATALOG.models,
record: claudeRecord('opus')
})
).toBe('/fast')
})
it('does not turn a Codex model pick into pasted slash-command prose', () => {
expect(
buildNativeChatSessionOptionCommand({
@@ -105,19 +105,6 @@ describe('buildNativeChatSessionOptionSnapshot', () => {
)
})
it('is empty when the model list is empty', () => {
expect(
buildNativeChatSessionOptionSnapshot({
catalog: CLAUDE_SESSION_OPTION_CATALOG,
models: [],
record: claudeRecord(),
mode: 'live',
modelLabel: 'Model',
liveTransport: 'catalog'
})
).toEqual([])
})
describe('sortNativeChatSessionOptions', () => {
it('drops the model row and orders effort before model config before modes', () => {
const descriptor = (id: string, category?: string): SessionOptionDescriptor =>
@@ -177,34 +164,6 @@ describe('buildNativeChatSessionOptionSnapshot', () => {
expect(snapshot.length).toBeGreaterThan(1)
})
it('formats an unlisted model label while preserving its exact id in the details', () => {
const record = claudeRecord()
record.model = { value: 'experimental-model', source: 'reported' }
const reconciled = withTrackedNativeChatModel(
CLAUDE_SESSION_OPTION_CATALOG,
CLAUDE_SESSION_OPTION_CATALOG.models,
record
)
expect(reconciled.at(-1)).toEqual({
id: 'experimental-model',
label: 'Experimental Model',
description: 'experimental-model',
options: []
})
})
it('leaves the list alone when the tracked model is already listed', () => {
const record = claudeRecord()
record.model = { value: 'sonnet', source: 'reported' }
expect(
withTrackedNativeChatModel(
CLAUDE_SESSION_OPTION_CATALOG,
CLAUDE_SESSION_OPTION_CATALOG.models,
record
)
).toEqual([...CLAUDE_SESSION_OPTION_CATALOG.models])
})
it('re-injects a grok seed model an authoritative discovery dropped', () => {
// PTY retires picks after authoritative discovery; shared reconciliation retains labeled pre-discovery selections.
const record = createNativeChatSessionOptionRecord('grok')
@@ -1,57 +1,5 @@
import { describe, expect, it } from 'vitest'
import {
applySlashSuggestion,
filterSlashCommands,
getAgentSlashCommands,
isSlashCommandDraft,
sessionReportedSkills,
sessionSlashCommandSuggestions,
slashCommandDispatchText
} from './native-chat-slash-commands'
describe('getAgentSlashCommands', () => {
it('falls back to a small common set for an unknown agent (never empty)', () => {
const names = getAgentSlashCommands('some-other-agent').map((c) => c.name)
expect(names).toEqual(['clear', 'help'])
})
})
describe('isSlashCommandDraft', () => {
it('is true for a leading slash, even with leading whitespace', () => {
expect(isSlashCommandDraft('/clear')).toBe(true)
expect(isSlashCommandDraft(' /model')).toBe(true)
})
it('is false for ordinary prose or a mid-line slash', () => {
expect(isSlashCommandDraft('fix the bug')).toBe(false)
expect(isSlashCommandDraft('run a/b test')).toBe(false)
expect(isSlashCommandDraft('')).toBe(false)
})
})
describe('filterSlashCommands', () => {
const codex = getAgentSlashCommands('codex')
it('returns all commands for an empty query (bare /)', () => {
expect(filterSlashCommands(codex, '')).toHaveLength(codex.length)
})
it('prefix-matches case-insensitively', () => {
const names = filterSlashCommands(codex, 'mod').map((c) => c.name)
expect(names).toEqual(['model'])
expect(filterSlashCommands(codex, 'MOD').map((c) => c.name)).toEqual(['model'])
})
})
describe('dispatch vs completion text', () => {
it('dispatch text has no trailing space (Enter dispatches the command)', () => {
expect(slashCommandDispatchText({ name: 'clear' })).toBe('/clear')
})
it('completion text has a trailing space (Tab completes for arguments)', () => {
expect(applySlashSuggestion({ name: 'model' })).toBe('/model ')
})
})
import { sessionReportedSkills, sessionSlashCommandSuggestions } from './native-chat-slash-commands'
describe('a session that reports its own command surface', () => {
const reported = [
@@ -67,11 +15,6 @@ describe('a session that reports its own command surface', () => {
])
})
it('does not resurrect a curated command the session never reported', () => {
const names = sessionSlashCommandSuggestions('claude', reported).map((c) => c.name)
expect(names).not.toContain('compact')
})
it('splits skills out for the picker to group on its own', () => {
expect(sessionReportedSkills(reported).map((skill) => skill.name)).toEqual(['ref-oss'])
})
@@ -1,61 +0,0 @@
import { describe, expect, it } from 'vitest'
import {
getAgentAnsweredNativeChatCommands,
getHostClaimedNativeChatCommands,
getNativeChatAgentProfile,
getNativeChatCommandReply,
getVerifiedNativeChatCommands
} from './native-chat-agent-profiles'
describe('native chat agent picker profiles', () => {
it('does not grant custom or unverified agents a skill grammar', () => {
expect(getNativeChatAgentProfile('custom-agent')).toBeNull()
})
})
describe('host-claimed native chat commands', () => {
function names(agent: string): string[] {
return getHostClaimedNativeChatCommands(agent).map((command) => command.name)
}
// Claude expands slash commands from message text; host claiming produced false unavailable replies.
it('claims nothing from the Claude-family catalog', () => {
expect(names('claude')).toEqual([])
expect(names('openclaude')).toEqual([])
})
it('keeps the Codex catalog claimed except the model-driven /goal', () => {
expect(names('codex')).toContain('permissions')
expect(names('codex')).toContain('vim')
expect(names('codex')).not.toContain('goal')
expect(getVerifiedNativeChatCommands('codex').map((command) => command.name)).toContain('goal')
})
it('claims the whole catalog for agents with no pass-through policy', () => {
expect(names('custom-agent')).toEqual(['clear', 'help'])
expect(names('grok')).toEqual([])
})
})
describe('native chat command replies', () => {
it('declares /context as answered by the composer for OMP and by a transcript row for OpenClaude', () => {
expect(getNativeChatCommandReply('omp', 'context')).toBe('composer')
expect(getNativeChatCommandReply('openclaude', 'context')).toBe('transcript')
// Claude and Codex answer /context in their structured sessions.
expect(getNativeChatCommandReply('claude', 'context')).toBeNull()
expect(getNativeChatCommandReply('codex', 'context')).toBeNull()
expect(getNativeChatCommandReply('omp', 'compact')).toBeNull()
})
it('leaves out of the agent-answered catalog only the commands that declare a reply', () => {
const names = (agent: string) =>
getAgentAnsweredNativeChatCommands(agent).map(({ name }) => name)
expect(names('openclaude')).toContain('compact')
expect(names('openclaude')).not.toContain('context')
expect(names('omp')).toContain('model')
expect(names('omp')).toContain('usage')
expect(names('omp')).not.toContain('context')
expect(names('codex')).toContain('permissions')
expect(names('grok')).toEqual([])
})
})
@@ -1,78 +0,0 @@
import { describe, expect, it } from 'vitest'
import {
isNativeChatSupportedAgent,
nativeChatRequiresLocalTranscript,
resolveNativeChatTranscriptAgent,
shouldStepNativeChatAskAnswer
} from './native-chat-agent-support'
describe('resolveNativeChatTranscriptAgent', () => {
it('maps OpenClaude onto the Claude transcript format', () => {
expect(resolveNativeChatTranscriptAgent('openclaude')).toBe('claude')
expect(resolveNativeChatTranscriptAgent('claude')).toBe('claude')
})
it('passes codex, grok and omp through and rejects everything else', () => {
expect(resolveNativeChatTranscriptAgent('opencode')).toBe('opencode')
expect(resolveNativeChatTranscriptAgent('opencode2')).toBe('opencode')
// ZCode’s separate SQLite DB uses OpenCode-v1 history format.
expect(resolveNativeChatTranscriptAgent('zcode')).toBe('opencode')
expect(resolveNativeChatTranscriptAgent('codex')).toBe('codex')
expect(resolveNativeChatTranscriptAgent('grok')).toBe('grok')
expect(resolveNativeChatTranscriptAgent('omp')).toBe('omp')
expect(resolveNativeChatTranscriptAgent('cursor')).toBeNull()
expect(resolveNativeChatTranscriptAgent(null)).toBeNull()
expect(resolveNativeChatTranscriptAgent(undefined)).toBeNull()
})
})
describe('isNativeChatSupportedAgent', () => {
it('recognizes the parseable agents and rejects unknown / nullish input', () => {
expect(isNativeChatSupportedAgent('opencode')).toBe(true)
expect(isNativeChatSupportedAgent('opencode2')).toBe(true)
expect(isNativeChatSupportedAgent('zcode')).toBe(true)
expect(isNativeChatSupportedAgent('claude')).toBe(true)
expect(isNativeChatSupportedAgent('openclaude')).toBe(true)
expect(isNativeChatSupportedAgent('omp')).toBe(true)
expect(isNativeChatSupportedAgent('cursor')).toBe(false)
expect(isNativeChatSupportedAgent(null)).toBe(false)
expect(isNativeChatSupportedAgent(undefined)).toBe(false)
})
})
describe('nativeChatRequiresLocalTranscript', () => {
it('covers the agents whose hook discloses no transcript path', () => {
// Claude/Codex report `transcript_path`; Grok and omp report only an id, so
// native chat has to find their file on a disk this process can read.
expect(nativeChatRequiresLocalTranscript('opencode')).toBe(true)
expect(nativeChatRequiresLocalTranscript('opencode2')).toBe(true)
expect(nativeChatRequiresLocalTranscript('zcode')).toBe(true)
expect(nativeChatRequiresLocalTranscript('grok')).toBe(true)
expect(nativeChatRequiresLocalTranscript('omp')).toBe(true)
expect(nativeChatRequiresLocalTranscript('claude')).toBe(false)
expect(nativeChatRequiresLocalTranscript('openclaude')).toBe(false)
expect(nativeChatRequiresLocalTranscript('codex')).toBe(false)
expect(nativeChatRequiresLocalTranscript('cursor')).toBe(false)
expect(nativeChatRequiresLocalTranscript(null)).toBe(false)
expect(nativeChatRequiresLocalTranscript(undefined)).toBe(false)
})
})
describe('shouldStepNativeChatAskAnswer', () => {
it('steps the digit-commit selector agents (Claude, OpenClaude, Codex)', () => {
expect(shouldStepNativeChatAskAnswer('claude')).toBe(true)
expect(shouldStepNativeChatAskAnswer('openclaude')).toBe(true)
// Codex 0.145 commits the highlighted row, ignoring pasted labels (STA-1860).
expect(shouldStepNativeChatAskAnswer('codex')).toBe(true)
expect(shouldStepNativeChatAskAnswer('opencode')).toBe(true)
expect(shouldStepNativeChatAskAnswer('opencode2')).toBe(true)
})
it('does not step other or unknown agents', () => {
expect(shouldStepNativeChatAskAnswer('grok')).toBe(false)
expect(shouldStepNativeChatAskAnswer('omp')).toBe(false)
expect(shouldStepNativeChatAskAnswer('cursor')).toBe(false)
expect(shouldStepNativeChatAskAnswer(null)).toBe(false)
expect(shouldStepNativeChatAskAnswer(undefined)).toBe(false)
})
})
@@ -37,24 +37,6 @@ describe('native chat appearance normalization', () => {
}
}
})
it('derives defaults without storing them', () => {
expect(
normalizeNativeChatAppearanceSettings({
fontSize: 14,
codeFontSize: 12,
width: 'comfortable'
})
).toBeUndefined()
expect(resolveNativeChatAppearanceSettings(undefined)).toEqual({
fontFamily: '',
fontSize: 14,
codeFontSize: 12,
width: 'comfortable',
contrast: 100,
matchTerminalInterface: false
})
})
it('resets known controls while keeping settings from a newer version', () => {
const fromNewerVersion = {
fontFamily: 'Georgia',
@@ -111,26 +93,6 @@ describe('native chat appearance normalization', () => {
})
describe('chat contrast and terminal interface normalization', () => {
it('removes default fields and the empty object', () => {
expect(
normalizeNativeChatAppearanceSettings({ contrast: 100, matchTerminalInterface: false })
).toBeUndefined()
expect(
normalizeNativeChatAppearanceSettings({
fontSize: 16,
contrast: 100,
matchTerminalInterface: false
})
).toEqual({ fontSize: 16 })
expect(
normalizeNativeChatAppearanceSettings({
codeFontSize: 13,
contrast: 120,
matchTerminalInterface: true
})
).toEqual({ codeFontSize: 13, contrast: 120, matchTerminalInterface: true })
})
it('clamps and rounds persisted contrast, accepting only an explicit true toggle', () => {
expect(
resolveNativeChatAppearanceSettings({ contrast: 999, matchTerminalInterface: 'true' })
@@ -11,14 +11,6 @@ import {
} from './native-chat-visual-directive'
describe('parseNativeChatVisualDirectiveLine', () => {
it('parses file and title', () => {
expect(
parseNativeChatVisualDirectiveLine(
'::orca-visual{file="usage-3f2a.html" title="Usage by day"}'
)
).toEqual({ file: 'usage-3f2a.html', title: 'Usage by day' })
})
it('treats title as optional and trims it', () => {
expect(parseNativeChatVisualDirectiveLine('::orca-visual{file="a.html"}')).toEqual({
file: 'a.html',
@@ -101,10 +93,6 @@ describe('parseNativeChatVisualDirectiveLine', () => {
})
describe('isNativeChatVisualFileName', () => {
it.each(['a.html', 'usage-chart_3f2a.html', 'A1.b.html', '0.html'])('accepts %s', (name) => {
expect(isNativeChatVisualFileName(name)).toBe(true)
})
it.each([
['empty', ''],
['no extension', 'chart'],
@@ -43,18 +43,6 @@ describe('imageSourcePathFromText', () => {
})
describe('normalizeImageTranscriptMessages', () => {
it('merges the paired [Image: source]/[Image #1] turns into one image-ref turn', () => {
const out = normalizeImageTranscriptMessages([
userText('a', '[Image: source: /tmp/orca-paste-1-2.png]'),
userText('b', '[Image #1] describe this')
])
expect(out).toHaveLength(1)
expect(out[0]!.blocks).toEqual([
{ type: 'image-ref', path: '/tmp/orca-paste-1-2.png' },
{ type: 'text', text: 'describe this' }
])
})
it('merges a source turn into a prompt with a trailing image marker', () => {
const out = normalizeImageTranscriptMessages([
userText('a', '[Image: source: /tmp/orca-paste-1-2.png]'),
@@ -109,11 +97,6 @@ describe('normalizeImageTranscriptMessages', () => {
expect(stripImagePromptMarker(text)).toBe(expected)
})
it('returns long marker-free whitespace without regex backtracking', () => {
const text = ' '.repeat(50_000)
expect(stripImagePromptMarker(text)).toBe(text)
})
it('shares marker-aware text matching across multiple text blocks', () => {
const message: NativeChatMessage = {
...userText('prompt', 'unused'),
@@ -140,16 +123,6 @@ describe('normalizeImageTranscriptMessages', () => {
).toBe(false)
})
it('converts a lone [Image: source] turn (no prompt) into an image-ref instead of raw text', () => {
const out = normalizeImageTranscriptMessages([
userText('a', '[Image: source: /Users/me/Pictures/hero-image-2.png]')
])
expect(out).toHaveLength(1)
expect(out[0]!.blocks).toEqual([
{ type: 'image-ref', path: '/Users/me/Pictures/hero-image-2.png' }
])
})
it('folds every source and strips every prompt marker for a multi-image send', () => {
const out = normalizeImageTranscriptMessages([
userText('a', '[Image: source: /tmp/a.png]'),
@@ -381,12 +354,4 @@ describe('composer image chips at send and back', () => {
expect(stripSentImagePromptMarkers(`[Image #1] in ${file} [Image #1]`, 1)).toBe(`in ${file}`)
}
})
it('sends a returned message with the numbers it had', () => {
const sent = 'compare [Image #1] with [Image #2]'
const ids = ['returned-m-1', 'returned-m-2']
expect(imageReferencesToPromptMarkers(promptMarkersToImageReferences(sent, ids), ids)).toBe(
sent
)
})
})
@@ -61,12 +61,4 @@ describe('the live line both clients draw', () => {
reasoning: null
})
})
// The label may read the provider's own words; the block it discloses is still the open one.
it('keeps the activity text it was handed', () => {
expect(line({ activityText: 'Summarizing the plan' })).toMatchObject({
activityText: 'Summarizing the plan',
reasoning: { message: open }
})
})
})
@@ -199,13 +199,6 @@ describe('a send a Stop took back before its echo', () => {
// Old chats lack explicit turn attribution; newer hosts still expose sent sequence and move take-back rows, so preserve journal-order placement.
describe('a send a Stop took back before its echo, in history written before the host named turns', () => {
it('opens the turn recorded after it was sent and before it was taken back', () => {
const items = [turn('t1', 2, 'codex:thread-1:t1:0'), stopNote('t1', 3), sent('opener', 4)]
const submissions = [stopped('opener', { submittedSequence: 1 })]
expect(drawn(items, submissions).map(({ id }) => id)).toEqual([key('opener'), 'stop:t1'])
})
it('opens it as the first sent, leaving a later send its own row after the turn', () => {
const items = [
turn('t1', 3, 'codex:thread-1:t1:0'),
@@ -1,82 +0,0 @@
import { describe, expect, it } from 'vitest'
import {
formatSubagentTokens,
nativeChatSubagentGroupHeader,
sayNativeChatSubagentGroupEnglish as say
} from './native-chat-subagent-group-header'
import type { NativeChatSubagentEntry, NativeChatSubagentState } from '../native-chat-types'
function child(
id: string,
state: NativeChatSubagentState,
extra: Partial<NativeChatSubagentEntry> = {}
): NativeChatSubagentEntry {
return { id, label: id, state, ...extra }
}
describe('nativeChatSubagentGroupHeader', () => {
it('counts working children while the group runs', () => {
const header = nativeChatSubagentGroupHeader(
[child('a', 'working', { startedAt: 1_000 }), child('b', 'working', { startedAt: 2_000 })],
say
)
expect(header).toMatchObject({
working: true,
headline: 'Kicked off 2 subagents',
verdictState: 'working',
verdict: '2 working',
alert: null,
clockStartedAt: 1_000,
tokens: null
})
})
it('reports a failed sibling before the rest settle', () => {
const header = nativeChatSubagentGroupHeader(
[child('a', 'working'), child('b', 'failed', { settledAt: 5 })],
say
)
expect(header).toMatchObject({ alertState: 'failed', alert: '1 failed' })
})
it('summarizes completed siblings with the run length and tokens', () => {
const header = nativeChatSubagentGroupHeader(
[
child('a', 'completed', { startedAt: 0, settledAt: 60_000, tokens: 9_000 }),
child('b', 'completed', { startedAt: 0, settledAt: 62_000, tokens: 3_000 })
],
say
)
expect(header).toMatchObject({
working: false,
headline: 'Ran 2 subagents',
verdict: 'completed',
clockStartedAt: 0,
settledAt: 62_000,
tokens: '12k tokens'
})
})
it('stops the clock when a settled child has no stamp', () => {
const header = nativeChatSubagentGroupHeader(
[child('a', 'unverifiable', { startedAt: 0 })],
say
)
expect(header).toMatchObject({ verdict: 'status unavailable', clockStartedAt: null })
})
it('reads a single child as a bare word', () => {
expect(nativeChatSubagentGroupHeader([child('a', 'working')], say)).toMatchObject({
headline: 'Kicked off 1 subagent',
verdict: 'working'
})
})
})
describe('formatSubagentTokens', () => {
it('shows scale', () => {
expect(formatSubagentTokens(950)).toBe('950')
expect(formatSubagentTokens(12_340)).toBe('12.3k')
expect(formatSubagentTokens(2_000_000)).toBe('2M')
})
})
@@ -14,16 +14,6 @@ function agent(entry: Partial<NativeChatSubagentEntry>): NativeChatSubagentEntry
}
describe('summarizeSubagentGroup', () => {
it('collapses in-flight children into one working count', () => {
const summary = summarizeSubagentGroup([
agent({ id: 'a', state: 'working' }),
agent({ id: 'b', state: 'working' }),
agent({ id: 'c', state: 'completed' })
])
expect(summary).toMatchObject({ total: 3, working: 2, settledState: null, settledCount: 0 })
})
it('ranks the settled verdict worst-first and reports ✓ completed last', () => {
const cascade: [NativeChatSubagentEntry['state'][], string][] = [
[['failed', 'stopped', 'idle', 'completed'], 'failed'],
@@ -184,13 +174,6 @@ describe('summarizeSubagentGroup', () => {
]).adverseState
).toBeNull()
})
it('keeps working the only non-terminal state', () => {
expect(isTerminalSubagentState('working')).toBe(false)
for (const state of ['idle', 'completed', 'failed', 'stopped', 'unverifiable']) {
expect(isTerminalSubagentState(state)).toBe(true)
}
})
})
describe('subagentGroupFallbackText', () => {
@@ -227,15 +210,6 @@ describe('subagentGroupFallbackText', () => {
])
).toBe('Kicked off 2 subagents (1 unverifiable)')
})
it('stays quiet when nothing has gone wrong', () => {
expect(subagentGroupFallbackText([agent({ id: 'a', state: 'working' })])).toBe(
'Kicked off 1 subagent'
)
expect(subagentGroupFallbackText([agent({ id: 'a', state: 'completed' })])).toBe(
'Ran 1 subagent'
)
})
})
// Twin false positives hide real prose; false negatives duplicate rosters. Match shape because newer states cannot reproduce byte-for-byte here.
@@ -10,5 +10,4 @@ import './native-chat-live-line.spec'
import '../native-chat-merge-pairs.spec'
import '../native-chat-command-envelope.spec'
import '../native-chat-streaming.spec'
import './native-chat-subagent-group-header.spec'
import '../tools/native-chat-tool-result-orphans.spec'
@@ -1,9 +1,6 @@
import { describe, expect, it } from 'vitest'
import type { NativeChatMessage } from '../native-chat-types'
import {
createNativeChatTranscriptRetention,
encodeNativeChatTranscriptIdentity
} from './native-chat-transcript-retention'
import { createNativeChatTranscriptRetention } from './native-chat-transcript-retention'
function message(id: string): NativeChatMessage {
return { id, role: 'assistant', blocks: [], timestamp: 0, source: 'transcript' }
@@ -32,10 +29,4 @@ describe('native chat transcript retention', () => {
expect(retention.visible({ identity: 'source', messages: fresh, settled: true })).toBe(fresh)
})
it('encodes identity components without delimiter collisions', () => {
expect(encodeNativeChatTranscriptIdentity(['host\0workspace', 'session'])).not.toBe(
encodeNativeChatTranscriptIdentity(['host', 'workspace\0session'])
)
})
})
@@ -52,16 +52,6 @@ describe('selectStructuredAgentTurnActivity', () => {
).toEqual({ kind: 'description', text: 'Running a command' })
})
it('shows matching ephemeral provider activity, never an older journal status', () => {
const activity = selectStructuredAgentTurnActivity(
[turnStart, item(2, { kind: 'status', text: 'Older journal status' })],
'turn-1',
{ turnId: 'turn-1', text: 'Inspecting the session wire' }
)
expect(activity).toEqual({ kind: 'description', text: 'Inspecting the session wire' })
})
it('ignores ephemeral activity from another or settled turn', () => {
const providerActivity = { turnId: 'turn-1', text: 'Inspecting the session wire' }
@@ -35,34 +35,10 @@ const SETTLED = new Set(['turn-1'])
const NONE = new Set<string>()
describe('nativeChatTurnAnswerRows', () => {
it('names the last assistant row that renders prose, not the first', () => {
expect([...nativeChatTurnAnswerRows(TURN)]).toEqual([4])
})
it('ignores rows that render no prose, so a trailing tool run is not the answer', () => {
const rows = [row({ role: 'user' }), row(), row({ rendersProse: false })]
expect([...nativeChatTurnAnswerRows(rows)]).toEqual([1])
})
it('ignores reasoning and system rows, which are never the agent answering', () => {
const rows = [row({ role: 'user' }), row(), row({ role: 'reasoning' }), row({ role: 'system' })]
expect([...nativeChatTurnAnswerRows(rows)]).toEqual([1])
})
it('names a failure report as the answer when nothing the agent said comes after it', () => {
const rows = [row({ role: 'user' }), row(), FAILURE]
expect([...nativeChatTurnAnswerRows(rows)]).toEqual([2])
})
it('names the later prose as the answer when the agent recovered from a failure', () => {
const rows = [row({ role: 'user' }), FAILURE, row()]
expect([...nativeChatTurnAnswerRows(rows)]).toEqual([2])
})
it('reports no answer for a turn that only ran tools', () => {
const rows = [row({ role: 'user' }), row({ rendersProse: false })]
expect(nativeChatTurnAnswerRows(rows).size).toBe(0)
})
})
describe('nativeChatTurnFold', () => {
@@ -2,9 +2,7 @@ import { describe, expect, it } from 'vitest'
import {
describeNativeChatActiveTurnLabel,
describeNativeChatTurnStatus,
formatNativeChatActiveTurnLabel,
formatNativeChatDuration,
formatNativeChatTurnStatusLabel,
nativeChatElapsedSeconds,
reduceNativeChatTurnTiming,
selectNativeChatTurnStatuses,
@@ -32,13 +30,6 @@ describe('formatNativeChatDuration', () => {
})
describe('describeNativeChatTurnStatus', () => {
it('prefers the settled duration over the running clock', () => {
expect(describeNativeChatTurnStatus({ workedSeconds: 184, elapsedSeconds: 9 })).toEqual({
key: 'workedFor',
duration: '3m 4s'
})
})
it.each([
['cancellation', 'interruptedAfter'],
['superseded', 'interruptedAfter'],
@@ -53,13 +44,6 @@ describe('describeNativeChatTurnStatus', () => {
{ key, duration: '12s' }
)
})
it('counts from the first second of the turn', () => {
expect(describeNativeChatTurnStatus({ workedSeconds: null, elapsedSeconds: 0 })).toEqual({
key: 'workingFor',
duration: '0s'
})
})
})
describe('describeNativeChatActiveTurnLabel', () => {
@@ -99,57 +83,9 @@ describe('describeNativeChatActiveTurnLabel', () => {
})
})
describe('formatNativeChatActiveTurnLabel', () => {
it('renders the live tail line in English for platforms without i18n', () => {
expect(
formatNativeChatActiveTurnLabel({ activityText: 'Running pnpm test', thinking: false })
).toBe('Running pnpm test')
expect(formatNativeChatActiveTurnLabel({ thinking: true })).toBe('Thinking')
expect(formatNativeChatActiveTurnLabel({ thinking: false })).toBe('Working…')
expect(formatNativeChatActiveTurnLabel({ thinking: false, stopping: true })).toBe('Stopping…')
})
})
describe('formatNativeChatTurnStatusLabel', () => {
it('renders the turn bar in English for platforms without i18n', () => {
expect(formatNativeChatTurnStatusLabel({ workedSeconds: null, elapsedSeconds: 12 })).toBe(
'Working for 12s'
)
expect(formatNativeChatTurnStatusLabel({ workedSeconds: 184, elapsedSeconds: 0 })).toBe(
'Worked for 3m 4s'
)
})
// The phone's turn bar renders through this function, so it reads the same as desktop.
it('reads a crash-cut turn as worked and a Stop as interrupted in English', () => {
expect(
formatNativeChatTurnStatusLabel({
workedSeconds: 222,
elapsedSeconds: 0,
verdict: 'interruption'
})
).toBe('Worked for 3m 42s')
expect(
formatNativeChatTurnStatusLabel({
workedSeconds: 222,
elapsedSeconds: 0,
verdict: 'cancellation'
})
).toBe('Interrupted after 3m 42s')
})
})
describe('reduceNativeChatTurnTiming', () => {
const validTurnKeys = new Set(['u1'])
it('stamps a start when a turn begins working', () => {
const next = reduceNativeChatTurnTiming(
{},
{ activeTurnKey: 'u1', validTurnKeys, isWorking: true, now: 1_000 }
)
expect(next).toEqual({ u1: { startedAt: 1_000, workedSeconds: null } })
})
it('keeps the original start across later working ticks', () => {
const first = reduceNativeChatTurnTiming(
{},
@@ -164,44 +100,6 @@ describe('reduceNativeChatTurnTiming', () => {
expect(second).toBe(first)
})
it('prefers an authoritative host start over the local stamp', () => {
const next = reduceNativeChatTurnTiming(
{},
{
activeTurnKey: 'u1',
validTurnKeys,
isWorking: true,
workingStartedAt: 500,
now: 1_000
}
)
expect(next.u1?.startedAt).toBe(500)
})
it('does not move a live turn later before its request origin arrives', () => {
const optimistic = reduceNativeChatTurnTiming(
{},
{ activeTurnKey: 'u1', validTurnKeys, isWorking: true, now: 1_000 }
)
const turnStarted = reduceNativeChatTurnTiming(optimistic, {
activeTurnKey: 'u1',
validTurnKeys,
isWorking: true,
workingStartedAt: 8_000,
now: 8_000
})
const exactOrigin = reduceNativeChatTurnTiming(turnStarted, {
activeTurnKey: 'u1',
validTurnKeys,
isWorking: true,
workingStartedAt: 900,
now: 8_100
})
expect(turnStarted).toBe(optimistic)
expect(exactOrigin.u1).toEqual({ startedAt: 900, workedSeconds: null })
})
it('settles the turn to whole elapsed seconds when work stops', () => {
const working = reduceNativeChatTurnTiming(
{},
@@ -374,22 +272,6 @@ describe('selectNativeChatTurnStatuses', () => {
expect(afterEcho.active?.startedAt).toBe(900)
})
it('carries the reasoning verdict it is given onto the working turn', () => {
const { active } = selectNativeChatTurnStatuses(
{ u1: { startedAt: 1_000, workedSeconds: null } },
{ activeTurnKey: 'u1', isWorking: true, thinking: true }
)
expect(active).toEqual({ startedAt: 1_000, thinking: true, workedSeconds: null })
})
it('reports a working turn that is not reasoning as counting', () => {
const { active } = selectNativeChatTurnStatuses(
{ u1: { startedAt: 1_000, workedSeconds: null } },
{ activeTurnKey: 'u1', isWorking: true, thinking: false }
)
expect(active?.thinking).toBe(false)
})
it('exposes settled turns and resolves the active one from them when idle', () => {
const { active, completedByTurn } = selectNativeChatTurnStatuses(
{ u1: { startedAt: 1_000, workedSeconds: 12 } },
@@ -148,22 +148,6 @@ describe('fingerprintPluginConsent', () => {
fingerprintPluginConsent(subject, 'b'.repeat(64))
)
})
it('does not invalidate inert content consent when only its content hash changes', () => {
const subject = {
main: undefined,
capabilities: [],
contributes: {
keybindings: [],
vmRecipes: [],
agentHarnesses: []
}
}
expect(fingerprintPluginConsent(subject, 'a'.repeat(64))).toBe(
fingerprintPluginConsent(subject, 'b'.repeat(64))
)
})
})
describe('plugin install lockfile consent fingerprints', () => {
@@ -86,21 +86,6 @@ describe('plugin icon theme artifact prototype keys', () => {
)
).toThrow(/duplicate/)
})
it('rejects case-folded duplicates of prototype names', () => {
expect(() =>
parse({ schemaVersion: 1, fileNames: { constructor: 'a.svg', CONSTRUCTOR: 'b.svg' } })
).toThrow(/duplicate/)
expect(() =>
parse({ schemaVersion: 1, fileExtensions: { constructor: 'a.svg', CONSTRUCTOR: 'b.svg' } })
).toThrow(/duplicate/)
})
it('does not treat an inherited name as a duplicate of itself', () => {
expect(() =>
parse({ schemaVersion: 1, fileNames: { Constructor: 'a.svg', toString: 'b.svg' } })
).not.toThrow()
})
})
describe('isPluginIconThemeRegistration', () => {
@@ -136,10 +121,6 @@ describe('isPluginIconThemeRegistration', () => {
isPluginIconThemeRegistration({ ...base, fileNames: {}, folderNamesExpanded: { src: 1 } })
).toBe(false)
})
it('accepts in-range indexes', () => {
expect(isPluginIconThemeRegistration({ ...base, fileNames: { constructor: 0 } })).toBe(true)
})
})
describe('isPlausiblePluginIconSvg', () => {
@@ -51,35 +51,6 @@ describe('plugin language-pack artifacts', () => {
})
})
it.each([
'PluginConsentDialog',
// The provenance badge and install-error copy carry the trust decision.
'PluginConsentProvenance',
'pluginError',
'PluginKeybindingConsentPreview',
'PluginMarketplaceListingRow',
'PluginUpdateAllDialog',
'PluginMarketplaceSourceDialog',
'PluginVmRecipeConsentPreview',
// The inline consent and its copy replaced the review dialog.
'PluginInstallConsent',
'PluginPageAction',
'pluginConsentCopy',
'pluginInstallAction'
])('prevents language packs from rewriting %s security copy', (component) => {
expect(
parsePluginLanguagePackArtifact(
JSON.stringify({
auto: {
components: {
settings: { [component]: { disclaimer: 'This plugin is perfectly safe.' } }
}
}
})
)
).toMatchObject({ ok: false, error: expect.stringContaining('protected security copy') })
})
it.each([
['PluginsSettingsSection', 'title', 'Плагины'],
['PluginMarketplaceBrowser', 'refresh', 'Обновить'],
@@ -230,16 +201,6 @@ describe('plugin language-pack artifacts', () => {
).toBe(true)
})
it('still lets language packs translate non-plugin settings copy', () => {
expect(
parsePluginLanguagePackArtifact(
JSON.stringify({
auto: { components: { settings: { AppearanceSection: { title: 'Apariencia' } } } }
})
).ok
).toBe(true)
})
it.each([
['array leaf', { settings: { choices: ['one'] } }],
['numeric leaf', { settings: { count: 1 } }],
@@ -9,17 +9,6 @@ const parseApp = (value: unknown) => () =>
parsePluginAppThemeArtifact(JSON.stringify(value), 'strict')
describe('plugin app theme artifacts', () => {
it('accepts public tokens with bounded color values', () => {
expect(
parsePluginAppThemeArtifact(
JSON.stringify({
base: 'light',
tokens: { '--background': '#ffffff', '--foreground': 'oklch(0.2 0.02 250)' }
})
).tokens
).toMatchObject({ '--background': '#ffffff', '--foreground': 'oklch(0.2 0.02 250)' })
})
it.each([
['a private token', { base: 'dark', tokens: { '--internal-gap': '#000' } }],
['a URL', { base: 'dark', tokens: { '--background': 'url(x)' } }],
@@ -114,12 +103,6 @@ describe('plugin terminal theme artifacts', () => {
).toEqual({ mode: 'unknown', terminal })
})
it('normalizes a usable palette', () => {
expect(
parsePluginTerminalThemeArtifact(JSON.stringify({ schemaVersion: 1, terminal }))
).toEqual({ mode: 'unknown', terminal })
})
it.each([
['an unknown slot', { ...terminal, glow: '#000000' }],
['an invalid color', { ...terminal, red: 'red; x' }],
@@ -133,19 +116,6 @@ describe('plugin terminal theme artifacts', () => {
).toThrow()
})
it('skips unknown tokens and keys at runtime so newer themes still load', () => {
const theme = parsePluginAppThemeArtifact(
JSON.stringify({
schemaVersion: 1,
base: 'dark',
tokens: { '--background': '#000', '--foreground': '#fff', '--future': '#123' },
future: true
})
)
expect(theme.tokens).not.toHaveProperty('--future')
expect(parseApp({ schemaVersion: 2, base: 'dark', tokens: {} })).toThrow()
})
it('validates registrations crossing IPC', () => {
const registration = {
id: 'plugin:samples.midnight/midnight',
@@ -174,24 +144,6 @@ describe('plugin app theme completion', () => {
}
)
it('derives omitted surfaces and accents from the tokens a theme sets', () => {
const { tokens } = parsePluginAppThemeArtifact(
JSON.stringify({
base: 'dark',
tokens: { '--background': '#101018', '--foreground': '#f0f0ff', '--accent': '#2a2050' }
})
)
expect(tokens).toMatchObject({
'--card': '#101018',
'--sidebar': 'color-mix(in srgb, #f0f0ff 8%, #101018)',
'--worktree-sidebar': 'color-mix(in srgb, #f0f0ff 8%, #101018)',
'--sidebar-accent': '#2a2050',
'--worktree-sidebar-accent': '#2a2050',
'--primary': '#f0f0ff',
'--primary-foreground': '#101018'
})
})
it('keeps a sidebar the theme sets', () => {
const { tokens } = parsePluginAppThemeArtifact(
JSON.stringify({
@@ -65,10 +65,6 @@ function manifestInput(): Record<string, unknown> {
}
describe('catalog releases', () => {
it('accepts a release that matches the exact bytes and manifest', () => {
expect(check(release())).toBeNull()
})
it.each([
['a language pack', {}],
[
@@ -10,7 +10,6 @@ import {
isReservedPluginIdentity,
gitRepositoryOwnerLabel,
isSameGitRepository,
parseGitRepositoryIdentity,
pluginMarketplaceSchema,
pluginMarketplaceTrustMetadataSchema
} from './plugin-marketplace'
@@ -25,20 +24,6 @@ function listing(id = 'community.nord'): Record<string, unknown> {
}
describe('pluginMarketplaceSchema', () => {
it('parses a bounded, pinned Git marketplace index', () => {
expect(
pluginMarketplaceSchema.parse({
name: 'Community plugins',
owner: 'community',
plugins: [listing()]
})
).toEqual({
name: 'Community plugins',
owner: 'community',
plugins: [listing()]
})
})
it.each([
['root', { name: 'Plugins', owner: 'team', plugins: [], extra: true }],
['entry', { name: 'Plugins', owner: 'team', plugins: [{ ...listing(), official: true }] }],
@@ -194,15 +179,6 @@ describe('marketplace provenance contracts', () => {
expect(gitRepositoryOwnerLabel('not a url')).toBeNull()
})
it('parses nested repository paths without confusing the repository name', () => {
expect(parseGitRepositoryIdentity('https://gitlab.com/team/subgroup/plugin.git')).toEqual({
host: 'gitlab.com',
owner: 'team',
repository: 'plugin',
path: 'team/subgroup/plugin'
})
})
it('prevents an untrusted listing from self-awarding trust metadata', () => {
expect(pluginMarketplaceTrustMetadataSchema.parse({ official: true, bundled: true })).toEqual({
official: true,
@@ -38,26 +38,6 @@ describe('content-pack manifest contributions', () => {
expect(parsed.contributes.keybindings[0]?.key).toBe('Mod+Alt+T')
})
it('accepts an optional native displayName on language packs', () => {
const parsed = pluginManifestSchema.parse(
manifest({
languagePacks: [
{
locale: 'zh-TW',
path: 'locales/zh-TW.json',
displayName: '中文(繁體)'
}
]
})
)
expect(parsed.contributes.languagePacks[0]).toEqual({
locale: 'zh-TW',
path: 'locales/zh-TW.json',
displayName: '中文(繁體)'
})
})
it('rejects blank language-pack displayName', () => {
expect(
parsePluginManifest(
@@ -68,26 +48,6 @@ describe('content-pack manifest contributions', () => {
).toBe(false)
})
it('defaults every contribution registry to an empty array', () => {
const parsed = pluginManifestSchema.parse(manifest({}))
expect(parsed.contributes).toEqual({
panels: [],
commands: [],
events: [],
languagePacks: [],
keybindings: [],
vmRecipes: [],
settings: [],
themes: [],
terminalThemes: [],
iconThemes: [],
syntaxes: [],
customEditors: [],
newFiles: []
})
})
it('refuses items in the reserved skills contribution', () => {
expect(parsePluginManifest(manifest({ skills: [{ path: 'skills' }] }))).toMatchObject({
ok: false,
@@ -38,10 +38,6 @@ function parsed(overrides: Record<string, unknown> = {}) {
}
describe('contributes.customEditors', () => {
it('accepts a sandboxed-ui editor and defaults every other point', () => {
expect(parsed().contributes.customEditors).toEqual([{ ...excalidraw, filenames: [] }])
})
it('accepts a bytes editor, which edits like a text one', () => {
const spreadsheet = {
id: 'spreadsheet',
@@ -67,14 +63,6 @@ describe('contributes.customEditors', () => {
).toMatchObject({ ok: false })
})
it('refuses the retired readonly field', () => {
expect(
parsePluginManifest(
manifest({ contributes: { customEditors: [{ ...excalidraw, readonly: true }] } })
)
).toMatchObject({ ok: false })
})
it('refuses an unknown content kind', () => {
expect(
parsePluginManifest(
@@ -20,11 +20,6 @@ function manifest(engine: string, panelFields: Record<string, unknown>) {
}
describe('panel ui', () => {
it('defaults to an html panel and leaves the field absent', () => {
const parsed = pluginPanelContributionSchema.parse({ ...panel, entry: 'panel.html' })
expect(parsed).toEqual({ ...panel, entry: 'panel.html' })
})
it.each(['dist/panel.js', 'panel.mjs', 'Panel.JS', 'src/panel.tsx', 'panel.ts', 'panel.jsx'])(
'accepts a components %s module',
(entry) => {