@alumbwe/anvil 1.0.42 → 1.0.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/anvil.js +18 -0
- package/package.json +13 -6
- package/src/agents/bundled-agents.generated.ts +1 -1
- package/src/index.tsx +27 -4
- package/src/login/plain-login.ts +60 -0
- package/src/login/supabase-auth.ts +346 -0
- package/src/utils/anvil-client.ts +4 -0
- package/src/utils/auth.ts +16 -4
- package/src/utils/config-dir.ts +1 -1
- package/vendor/@anvil/common/src/constants/deepseek-direct.ts +30 -1
- package/vendor/@anvil/common/src/util/project-ignore.ts +4 -3
- package/vendor/@anvil/sdk/dist/index.cjs +46 -10
- package/vendor/@anvil/sdk/dist/index.mjs +46 -10
- package/src/commands/__tests__/anvil-command-aliases.test.ts +0 -56
- package/src/commands/__tests__/bash-command.test.ts +0 -445
- package/src/commands/__tests__/command-args.test.ts +0 -349
- package/src/commands/__tests__/copy-conversation-clipboard.test.ts +0 -108
- package/src/commands/__tests__/copy-conversation.test.ts +0 -226
- package/src/commands/__tests__/diagnostics-command.test.ts +0 -35
- package/src/commands/__tests__/image.test.ts +0 -99
- package/src/commands/__tests__/init.test.ts +0 -456
- package/src/commands/__tests__/new-command-rotates-chat.test.ts +0 -91
- package/src/commands/__tests__/process-diagnostics.test.ts +0 -54
- package/src/commands/__tests__/prompt-builders.test.ts +0 -28
- package/src/commands/__tests__/router-input.test.ts +0 -298
- package/src/components/__tests__/ad-banner.test.tsx +0 -83
- package/src/components/__tests__/anvil-landing-heading-row.test.tsx +0 -91
- package/src/components/__tests__/anvil-model-selector.test.tsx +0 -519
- package/src/components/__tests__/anvil-offer-invariants.test.ts +0 -54
- package/src/components/__tests__/anvil-takeover-prompt.test.tsx +0 -212
- package/src/components/__tests__/chat-input-bar.test.tsx +0 -130
- package/src/components/__tests__/grid-layout.integration.test.tsx +0 -304
- package/src/components/__tests__/grid-layout.test.tsx +0 -1051
- package/src/components/__tests__/message-block.completion.test.tsx +0 -104
- package/src/components/__tests__/message-block.streaming.test.tsx +0 -78
- package/src/components/__tests__/message-with-agents.test.tsx +0 -579
- package/src/components/__tests__/multiline-input.test.tsx +0 -1132
- package/src/components/__tests__/queue-panel.test.tsx +0 -398
- package/src/components/__tests__/selectable-list.test.ts +0 -232
- package/src/components/__tests__/status-bar.test.tsx +0 -44
- package/src/components/__tests__/status-indicator.test.tsx +0 -204
- package/src/components/__tests__/terminal-thinking-orb.test.tsx +0 -111
- package/src/components/__tests__/user-error-banner.test.tsx +0 -102
- package/src/components/ask-user/__tests__/multiple-choice-form.test.ts +0 -432
- package/src/components/ask-user/__tests__/validation.test.ts +0 -213
- package/src/components/tools/__tests__/apply-patch.test.tsx +0 -84
- package/src/components/tools/__tests__/code-search.test.tsx +0 -45
- package/src/components/tools/__tests__/gravity-index.test.ts +0 -76
- package/src/components/tools/__tests__/render-ui.test.tsx +0 -92
- package/src/components/tools/__tests__/run-terminal-command.test.ts +0 -233
- package/src/contexts/__tests__/chat-runtime-context.test.tsx +0 -149
- package/src/data/slash-commands.test.ts +0 -24
- package/src/hooks/__tests__/holds-live-anvil-slot.test.ts +0 -49
- package/src/hooks/__tests__/session-fetch-signal.test.ts +0 -63
- package/src/hooks/__tests__/use-activity-query.test.ts +0 -1000
- package/src/hooks/__tests__/use-ask-user-bridge.test.ts +0 -176
- package/src/hooks/__tests__/use-auth-query.test.ts +0 -21
- package/src/hooks/__tests__/use-chat-input-remount.test.tsx +0 -66
- package/src/hooks/__tests__/use-clipboard.test.tsx +0 -73
- package/src/hooks/__tests__/use-connection-status.test.ts +0 -112
- package/src/hooks/__tests__/use-directory-browser.test.ts +0 -203
- package/src/hooks/__tests__/use-gravity-ad.test.ts +0 -73
- package/src/hooks/__tests__/use-grid-layout.test.ts +0 -349
- package/src/hooks/__tests__/use-input-history.test.ts +0 -699
- package/src/hooks/__tests__/use-message-queue-editing.test.tsx +0 -209
- package/src/hooks/__tests__/use-message-queue.test.tsx +0 -71
- package/src/hooks/__tests__/use-path-tab-completion.test.ts +0 -315
- package/src/hooks/__tests__/use-queue-controls.test.ts +0 -68
- package/src/hooks/__tests__/use-queue-ui.test.tsx +0 -83
- package/src/hooks/__tests__/use-searchable-list.test.ts +0 -359
- package/src/hooks/__tests__/use-send-message-timer.test.ts +0 -146
- package/src/hooks/__tests__/use-suggestion-engine-mention.test.ts +0 -361
- package/src/hooks/__tests__/use-suggestion-engine.test.ts +0 -485
- package/src/hooks/__tests__/use-terminal-focus.test.ts +0 -66
- package/src/hooks/__tests__/use-terminal-layout.test.ts +0 -675
- package/src/hooks/__tests__/use-timeout.test.ts +0 -330
- package/src/hooks/__tests__/use-usage-query.test.ts +0 -502
- package/src/hooks/__tests__/use-user-details-query.test.ts +0 -195
- package/src/hooks/helpers/__tests__/send-message.test.ts +0 -1918
- package/src/init/__tests__/init-direnv.test.ts +0 -526
- package/src/state/__tests__/chat-store-focus.test.ts +0 -22
- package/src/state/__tests__/feedback-store.test.ts +0 -257
- package/src/utils/__tests__/active-run.test.ts +0 -140
- package/src/utils/__tests__/activity-tracker.test.ts +0 -440
- package/src/utils/__tests__/agent-display.test.ts +0 -139
- package/src/utils/__tests__/analytics-client.test.ts +0 -262
- package/src/utils/__tests__/anonymous-id.test.ts +0 -74
- package/src/utils/__tests__/anvil-api.test.ts +0 -578
- package/src/utils/__tests__/anvil-instance-owner.test.ts +0 -69
- package/src/utils/__tests__/anvil-model-navigation.test.ts +0 -102
- package/src/utils/__tests__/anvil-premium-reset.test.ts +0 -79
- package/src/utils/__tests__/anvil-referral-cache.test.ts +0 -116
- package/src/utils/__tests__/anvil-session-api.test.ts +0 -215
- package/src/utils/__tests__/anvil-session-display.test.ts +0 -23
- package/src/utils/__tests__/anvil-streak-line.test.ts +0 -217
- package/src/utils/__tests__/arrays.test.ts +0 -264
- package/src/utils/__tests__/bash-context-processor.test.ts +0 -38
- package/src/utils/__tests__/block-processor.test.ts +0 -810
- package/src/utils/__tests__/chat-history.test.ts +0 -203
- package/src/utils/__tests__/chat-input-key-intercept.test.ts +0 -40
- package/src/utils/__tests__/chat-meta.test.ts +0 -130
- package/src/utils/__tests__/clipboard-linux.test.ts +0 -359
- package/src/utils/__tests__/clipboard.test.ts +0 -910
- package/src/utils/__tests__/code-search-summary.test.ts +0 -84
- package/src/utils/__tests__/collapse-helpers.test.ts +0 -1109
- package/src/utils/__tests__/error-handling.test.ts +0 -658
- package/src/utils/__tests__/exit-cleanly.test.ts +0 -110
- package/src/utils/__tests__/feedback-helpers.test.ts +0 -444
- package/src/utils/__tests__/feedback-submission.test.ts +0 -26
- package/src/utils/__tests__/fetch-usage.test.ts +0 -355
- package/src/utils/__tests__/fingerprint.test.ts +0 -144
- package/src/utils/__tests__/fixtures/terminal-command-broker-child.ts +0 -7
- package/src/utils/__tests__/fixtures/terminal-command-broker-entry.ts +0 -3
- package/src/utils/__tests__/fixtures/terminal-command-broker-owner.ts +0 -33
- package/src/utils/__tests__/format-elapsed-time.test.ts +0 -103
- package/src/utils/__tests__/format-timeout.test.ts +0 -87
- package/src/utils/__tests__/image-dimensions.test.ts +0 -249
- package/src/utils/__tests__/image-processor.test.ts +0 -209
- package/src/utils/__tests__/implementor-helpers.test.ts +0 -1458
- package/src/utils/__tests__/keyboard-actions.test.ts +0 -660
- package/src/utils/__tests__/layout-helpers.test.ts +0 -36
- package/src/utils/__tests__/lazy-response-ads.test.ts +0 -167
- package/src/utils/__tests__/log-shipper.test.ts +0 -53
- package/src/utils/__tests__/markdown-renderer.test.tsx +0 -421
- package/src/utils/__tests__/message-block-helpers.test.ts +0 -1263
- package/src/utils/__tests__/message-updater.test.ts +0 -645
- package/src/utils/__tests__/osc-timeout-scenarios.test.ts +0 -172
- package/src/utils/__tests__/pending-attachments.test.ts +0 -277
- package/src/utils/__tests__/polling-backoff.test.ts +0 -51
- package/src/utils/__tests__/queue-panel-actions.test.ts +0 -148
- package/src/utils/__tests__/run-state-storage.test.ts +0 -919
- package/src/utils/__tests__/safe-json.test.ts +0 -77
- package/src/utils/__tests__/sdk-event-handlers.test.ts +0 -685
- package/src/utils/__tests__/send-message-helpers.test.ts +0 -1898
- package/src/utils/__tests__/send-message-timer.test.ts +0 -64
- package/src/utils/__tests__/settings.test.ts +0 -99
- package/src/utils/__tests__/strings.test.ts +0 -192
- package/src/utils/__tests__/terminal-color-detection.test.ts +0 -425
- package/src/utils/__tests__/terminal-command-broker.test.ts +0 -528
- package/src/utils/__tests__/terminal-enter-detection.test.ts +0 -77
- package/src/utils/__tests__/terminal-io.test.ts +0 -137
- package/src/utils/__tests__/terminal-protocol-controller.test.ts +0 -119
- package/src/utils/__tests__/text-layout.test.ts +0 -82
- package/src/utils/__tests__/theme-platform-detection.test.ts +0 -125
- package/src/utils/__tests__/think-tag-parser.test.ts +0 -159
- package/src/utils/__tests__/trace-writer.test.ts +0 -223
- package/src/utils/__tests__/trim-chat-logs.test.ts +0 -78
- package/src/utils/__tests__/usage-banner-state.test.ts +0 -298
- package/src/utils/__tests__/validation-error-formatting.test.ts +0 -126
- package/src/utils/__tests__/windows-terminal-health.test.ts +0 -101
- package/src/utils/__tests__/write-file-atomic.test.ts +0 -127
- package/vendor/@anvil/common/src/__tests__/agent-validation.test.ts +0 -846
- package/vendor/@anvil/common/src/__tests__/anvil-model-availability.test.ts +0 -101
- package/vendor/@anvil/common/src/__tests__/anvil-models.test.ts +0 -1408
- package/vendor/@anvil/common/src/__tests__/anvil-public-data-use-copy.test.ts +0 -258
- package/vendor/@anvil/common/src/__tests__/anvil-referral-tiers.test.ts +0 -48
- package/vendor/@anvil/common/src/__tests__/anvil-spend-ceilings.test.ts +0 -282
- package/vendor/@anvil/common/src/__tests__/anvil-trust.test.ts +0 -526
- package/vendor/@anvil/common/src/__tests__/deepseek-direct.test.ts +0 -68
- package/vendor/@anvil/common/src/__tests__/disposable-email.test.ts +0 -132
- package/vendor/@anvil/common/src/__tests__/dynamic-agent-template-schema.test.ts +0 -422
- package/vendor/@anvil/common/src/__tests__/env-ci.test.ts +0 -167
- package/vendor/@anvil/common/src/__tests__/env-process.test.ts +0 -145
- package/vendor/@anvil/common/src/__tests__/foreign-client-shipped-agents.test.ts +0 -234
- package/vendor/@anvil/common/src/__tests__/foreign-client-signals.test.ts +0 -379
- package/vendor/@anvil/common/src/__tests__/free-agents.test.ts +0 -807
- package/vendor/@anvil/common/src/__tests__/gravity-capi.test.ts +0 -154
- package/vendor/@anvil/common/src/__tests__/handlesteps-parsing.test.ts +0 -246
- package/vendor/@anvil/common/src/__tests__/kimi-k3-god-only.test.ts +0 -77
- package/vendor/@anvil/common/src/__tests__/model-config.test.ts +0 -89
- package/vendor/@anvil/common/src/__tests__/project-file-tree.test.ts +0 -298
- package/vendor/@anvil/common/src/__tests__/provisioned-model-tiers.test.ts +0 -116
- package/vendor/@anvil/common/src/__tests__/reasoning-effort.test.ts +0 -167
- package/vendor/@anvil/common/src/__tests__/reddit-capi.test.ts +0 -132
- package/vendor/@anvil/common/src/__tests__/response-ad-positions.test.ts +0 -72
- package/vendor/@anvil/common/src/__tests__/user-state.test.ts +0 -30
- package/vendor/@anvil/common/src/constants/__tests__/anvil-onboarding-gate.test.ts +0 -63
- package/vendor/@anvil/common/src/constants/__tests__/anvil-onboarding.test.ts +0 -246
- package/vendor/@anvil/common/src/constants/__tests__/cf-worker-signals.test.ts +0 -106
- package/vendor/@anvil/common/src/testing/TESTING_PATTERNS.md +0 -351
- package/vendor/@anvil/common/src/testing/anvil-offer-invariants.ts +0 -169
- package/vendor/@anvil/common/src/testing/errors.ts +0 -33
- package/vendor/@anvil/common/src/testing/fixtures/agent-runtime.ts +0 -334
- package/vendor/@anvil/common/src/testing/impl/agent-runtime.ts +0 -6
- package/vendor/@anvil/common/src/testing/index.ts +0 -84
- package/vendor/@anvil/common/src/testing/mock-modules.ts +0 -53
- package/vendor/@anvil/common/src/testing/mock-types.ts +0 -123
- package/vendor/@anvil/common/src/testing/mocks/analytics.ts +0 -261
- package/vendor/@anvil/common/src/testing/mocks/child-process.ts +0 -93
- package/vendor/@anvil/common/src/testing/mocks/crypto.ts +0 -218
- package/vendor/@anvil/common/src/testing/mocks/database.ts +0 -337
- package/vendor/@anvil/common/src/testing/mocks/fetch.ts +0 -219
- package/vendor/@anvil/common/src/testing/mocks/filesystem.ts +0 -166
- package/vendor/@anvil/common/src/testing/mocks/index.ts +0 -101
- package/vendor/@anvil/common/src/testing/mocks/logger.ts +0 -135
- package/vendor/@anvil/common/src/testing/mocks/stream.ts +0 -313
- package/vendor/@anvil/common/src/testing/mocks/timers.ts +0 -132
- package/vendor/@anvil/common/src/testing/mocks/tree-sitter.ts +0 -127
- package/vendor/@anvil/common/src/testing/setup.ts +0 -282
- package/vendor/@anvil/common/src/tools/__tests__/compile-tool-definitions.test.ts +0 -34
- package/vendor/@anvil/common/src/tools/params/__tests__/coerce-to-array.test.ts +0 -213
- package/vendor/@anvil/common/src/tools/params/__tests__/read-docs.test.ts +0 -47
- package/vendor/@anvil/common/src/tools/params/__tests__/render-ui.test.ts +0 -65
- package/vendor/@anvil/common/src/tools/params/tool/__tests__/run-terminal-command-timeout.test.ts +0 -49
- package/vendor/@anvil/common/src/types/__tests__/dynamic-agent-template.test.ts +0 -20
- package/vendor/@anvil/common/src/util/__tests__/ad-user-agent.test.ts +0 -26
- package/vendor/@anvil/common/src/util/__tests__/analytics-dispatcher.test.ts +0 -122
- package/vendor/@anvil/common/src/util/__tests__/analytics-log.test.ts +0 -102
- package/vendor/@anvil/common/src/util/__tests__/analytics-sampling.test.ts +0 -143
- package/vendor/@anvil/common/src/util/__tests__/anvil-streak.test.ts +0 -202
- package/vendor/@anvil/common/src/util/__tests__/anvil-usage-summary.test.ts +0 -193
- package/vendor/@anvil/common/src/util/__tests__/axiom-only-log.test.ts +0 -140
- package/vendor/@anvil/common/src/util/__tests__/client-user-agent.test.ts +0 -148
- package/vendor/@anvil/common/src/util/__tests__/engagement-tracker.test.ts +0 -115
- package/vendor/@anvil/common/src/util/__tests__/env-file-path.test.ts +0 -57
- package/vendor/@anvil/common/src/util/__tests__/error-abort.test.ts +0 -774
- package/vendor/@anvil/common/src/util/__tests__/error-api-details.test.ts +0 -206
- package/vendor/@anvil/common/src/util/__tests__/file-read-limits.test.ts +0 -173
- package/vendor/@anvil/common/src/util/__tests__/format-code-search.test.ts +0 -60
- package/vendor/@anvil/common/src/util/__tests__/log-mirror.test.ts +0 -31
- package/vendor/@anvil/common/src/util/__tests__/messages.test.ts +0 -1252
- package/vendor/@anvil/common/src/util/__tests__/partial-json-delta.test.ts +0 -505
- package/vendor/@anvil/common/src/util/__tests__/path.test.ts +0 -22
- package/vendor/@anvil/common/src/util/__tests__/project-ignore.test.ts +0 -90
- package/vendor/@anvil/common/src/util/__tests__/promise.test.ts +0 -325
- package/vendor/@anvil/common/src/util/__tests__/rate-limit.test.ts +0 -28
- package/vendor/@anvil/common/src/util/__tests__/reddit-anvil-retention.test.ts +0 -130
- package/vendor/@anvil/common/src/util/__tests__/saxy.test.ts +0 -1008
- package/vendor/@anvil/common/src/util/__tests__/split-data.test.ts +0 -289
- package/vendor/@anvil/common/src/util/__tests__/string.test.ts +0 -239
- package/vendor/@anvil/common/src/util/__tests__/thread-title.test.ts +0 -70
- package/vendor/@anvil/common/src/util/__tests__/tool-result-media-order.test.ts +0 -108
- package/vendor/@anvil/common/src/util/__tests__/ttft-histogram.test.ts +0 -180
- package/vendor/@anvil/common/src/util/__tests__/with-timeout.test.ts +0 -24
- package/vendor/@anvil/common/src/util/__tests__/zoned-time.test.ts +0 -88
- package/vendor/@anvil/common/src/util/skills.test.ts +0 -44
- package/vendor/@anvil/sdk/dist/index.cjs.map +0 -440
- package/vendor/@anvil/sdk/dist/index.mjs.map +0 -440
|
@@ -1,579 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import { renderToStaticMarkup } from 'react-dom/server'
|
|
4
|
-
|
|
5
|
-
import { initializeThemeStore } from '../../hooks/use-theme'
|
|
6
|
-
import { useChatStore } from '../../state/chat-store'
|
|
7
|
-
import { useMessageBlockStore } from '../../state/message-block-store'
|
|
8
|
-
import { chatThemes, createMarkdownPalette } from '../../utils/theme-system'
|
|
9
|
-
import { MessageWithAgents } from '../message-with-agents'
|
|
10
|
-
|
|
11
|
-
import type { ChatMessage } from '../../types/chat'
|
|
12
|
-
import type { MarkdownPalette } from '../../utils/markdown-renderer'
|
|
13
|
-
|
|
14
|
-
initializeThemeStore()
|
|
15
|
-
|
|
16
|
-
const theme = chatThemes.light
|
|
17
|
-
const basePalette: MarkdownPalette = createMarkdownPalette(theme)
|
|
18
|
-
|
|
19
|
-
// -----------------------------------------------------------------------------
|
|
20
|
-
// Helper factory functions for creating test messages
|
|
21
|
-
// -----------------------------------------------------------------------------
|
|
22
|
-
|
|
23
|
-
const createUserMessage = (id: string, content: string): ChatMessage => ({
|
|
24
|
-
id,
|
|
25
|
-
variant: 'user',
|
|
26
|
-
content,
|
|
27
|
-
timestamp: new Date().toISOString(),
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
const createAiMessage = (id: string, content: string): ChatMessage => ({
|
|
31
|
-
id,
|
|
32
|
-
variant: 'ai',
|
|
33
|
-
content,
|
|
34
|
-
timestamp: new Date().toISOString(),
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
const createAgentMessage = (
|
|
38
|
-
id: string,
|
|
39
|
-
content: string,
|
|
40
|
-
agentName: string,
|
|
41
|
-
options: Partial<ChatMessage> = {},
|
|
42
|
-
): ChatMessage => ({
|
|
43
|
-
id,
|
|
44
|
-
variant: 'agent',
|
|
45
|
-
content,
|
|
46
|
-
timestamp: new Date().toISOString(),
|
|
47
|
-
agent: {
|
|
48
|
-
agentName,
|
|
49
|
-
agentType: 'test-agent',
|
|
50
|
-
responseCount: 1,
|
|
51
|
-
},
|
|
52
|
-
...options,
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
const createErrorMessage = (id: string, content: string): ChatMessage => ({
|
|
56
|
-
id,
|
|
57
|
-
variant: 'error',
|
|
58
|
-
content,
|
|
59
|
-
timestamp: new Date().toISOString(),
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
// Creates an agent message without the required agent info (for error testing)
|
|
63
|
-
const createMalformedAgentMessage = (id: string, content: string): ChatMessage => ({
|
|
64
|
-
id,
|
|
65
|
-
variant: 'agent',
|
|
66
|
-
content,
|
|
67
|
-
timestamp: new Date().toISOString(),
|
|
68
|
-
// Intentionally missing agent property
|
|
69
|
-
} as ChatMessage)
|
|
70
|
-
|
|
71
|
-
const createModeDividerMessage = (id: string, mode: string): ChatMessage => ({
|
|
72
|
-
id,
|
|
73
|
-
variant: 'ai',
|
|
74
|
-
content: 'this content should be ignored',
|
|
75
|
-
timestamp: new Date().toISOString(),
|
|
76
|
-
blocks: [
|
|
77
|
-
{
|
|
78
|
-
type: 'mode-divider',
|
|
79
|
-
mode,
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
const defaultCallbacks = {
|
|
85
|
-
onToggleCollapsed: () => {},
|
|
86
|
-
onBuildFast: () => {},
|
|
87
|
-
onBuildMax: () => {},
|
|
88
|
-
onBuildLite: () => {},
|
|
89
|
-
onFeedback: () => {},
|
|
90
|
-
onCloseFeedback: () => {},
|
|
91
|
-
onAdClick: () => {},
|
|
92
|
-
onAdImpression: () => {},
|
|
93
|
-
onResponseAdsNeeded: () => {},
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const initializeStore = (overrides: {
|
|
97
|
-
messageTree?: Map<string, ChatMessage[]>
|
|
98
|
-
isWaitingForResponse?: boolean
|
|
99
|
-
timerStartTime?: number | null
|
|
100
|
-
availableWidth?: number
|
|
101
|
-
} = {}) => {
|
|
102
|
-
useMessageBlockStore.setState({
|
|
103
|
-
context: {
|
|
104
|
-
theme,
|
|
105
|
-
markdownPalette: basePalette,
|
|
106
|
-
messageTree: overrides.messageTree ?? new Map<string, ChatMessage[]>(),
|
|
107
|
-
isWaitingForResponse: overrides.isWaitingForResponse ?? false,
|
|
108
|
-
timerStartTime: overrides.timerStartTime ?? null,
|
|
109
|
-
availableWidth: overrides.availableWidth ?? 80,
|
|
110
|
-
responseAds: {},
|
|
111
|
-
},
|
|
112
|
-
callbacks: defaultCallbacks,
|
|
113
|
-
})
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
beforeEach(() => {
|
|
117
|
-
initializeStore()
|
|
118
|
-
useChatStore.setState({ streamingAgents: new Set<string>() })
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
afterEach(() => {
|
|
122
|
-
useMessageBlockStore.getState().reset()
|
|
123
|
-
useChatStore.setState({ streamingAgents: new Set<string>() })
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
const baseMessageWithAgentsProps = {
|
|
127
|
-
depth: 0,
|
|
128
|
-
isLastMessage: false,
|
|
129
|
-
availableWidth: 80,
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// =============================================================================
|
|
133
|
-
// MessageBlockStore Tests - store behavior, not JS built-ins
|
|
134
|
-
// =============================================================================
|
|
135
|
-
|
|
136
|
-
describe('MessageBlockStore', () => {
|
|
137
|
-
describe('setContext', () => {
|
|
138
|
-
test('performs partial merge, preserving unspecified values', () => {
|
|
139
|
-
// Set initial state with specific values
|
|
140
|
-
initializeStore({
|
|
141
|
-
isWaitingForResponse: true,
|
|
142
|
-
timerStartTime: 12345,
|
|
143
|
-
availableWidth: 100,
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
// Update only one value
|
|
147
|
-
useMessageBlockStore.getState().setContext({
|
|
148
|
-
isWaitingForResponse: false,
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
const state = useMessageBlockStore.getState()
|
|
152
|
-
// Updated value should change
|
|
153
|
-
expect(state.context.isWaitingForResponse).toBe(false)
|
|
154
|
-
// Other values should be preserved
|
|
155
|
-
expect(state.context.timerStartTime).toBe(12345)
|
|
156
|
-
expect(state.context.availableWidth).toBe(100)
|
|
157
|
-
expect(state.context.theme).toBe(theme)
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
test('updates messageTree without affecting other context values', () => {
|
|
161
|
-
const child1 = createAgentMessage('child-1', 'Content 1', 'Agent One')
|
|
162
|
-
const child2 = createAgentMessage('child-2', 'Content 2', 'Agent Two')
|
|
163
|
-
const newTree = new Map<string, ChatMessage[]>([
|
|
164
|
-
['parent-1', [child1, child2]],
|
|
165
|
-
])
|
|
166
|
-
|
|
167
|
-
useMessageBlockStore.getState().setContext({
|
|
168
|
-
messageTree: newTree,
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
const state = useMessageBlockStore.getState()
|
|
172
|
-
expect(state.context.messageTree).toBe(newTree)
|
|
173
|
-
expect(state.context.messageTree?.get('parent-1')).toHaveLength(2)
|
|
174
|
-
// Theme should be unchanged
|
|
175
|
-
expect(state.context.theme).toBe(theme)
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
test('can update multiple context values at once', () => {
|
|
179
|
-
useMessageBlockStore.getState().setContext({
|
|
180
|
-
isWaitingForResponse: true,
|
|
181
|
-
timerStartTime: 99999,
|
|
182
|
-
availableWidth: 200,
|
|
183
|
-
})
|
|
184
|
-
|
|
185
|
-
const state = useMessageBlockStore.getState()
|
|
186
|
-
expect(state.context.isWaitingForResponse).toBe(true)
|
|
187
|
-
expect(state.context.timerStartTime).toBe(99999)
|
|
188
|
-
expect(state.context.availableWidth).toBe(200)
|
|
189
|
-
})
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
describe('setCallbacks', () => {
|
|
193
|
-
test('replaces entire callbacks object', () => {
|
|
194
|
-
const mockToggle = () => {}
|
|
195
|
-
const mockBuildFast = () => {}
|
|
196
|
-
const mockBuildMax = () => {}
|
|
197
|
-
const mockBuildFree = () => {}
|
|
198
|
-
const mockFeedback = () => {}
|
|
199
|
-
const mockCloseFeedback = () => {}
|
|
200
|
-
|
|
201
|
-
useMessageBlockStore.getState().setCallbacks({
|
|
202
|
-
onToggleCollapsed: mockToggle,
|
|
203
|
-
onBuildFast: mockBuildFast,
|
|
204
|
-
onBuildMax: mockBuildMax,
|
|
205
|
-
onBuildLite: mockBuildFree,
|
|
206
|
-
onFeedback: mockFeedback,
|
|
207
|
-
onCloseFeedback: mockCloseFeedback,
|
|
208
|
-
onAdClick: () => {},
|
|
209
|
-
onAdImpression: () => {},
|
|
210
|
-
onResponseAdsNeeded: () => {},
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
const state = useMessageBlockStore.getState()
|
|
214
|
-
expect(state.callbacks.onToggleCollapsed).toBe(mockToggle)
|
|
215
|
-
expect(state.callbacks.onBuildFast).toBe(mockBuildFast)
|
|
216
|
-
expect(state.callbacks.onBuildMax).toBe(mockBuildMax)
|
|
217
|
-
expect(state.callbacks.onBuildLite).toBe(mockBuildFree)
|
|
218
|
-
expect(state.callbacks.onFeedback).toBe(mockFeedback)
|
|
219
|
-
expect(state.callbacks.onCloseFeedback).toBe(mockCloseFeedback)
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
test('callbacks are independent from context', () => {
|
|
223
|
-
const originalTheme = useMessageBlockStore.getState().context.theme
|
|
224
|
-
|
|
225
|
-
useMessageBlockStore.getState().setCallbacks({
|
|
226
|
-
...defaultCallbacks,
|
|
227
|
-
onToggleCollapsed: () => console.log('new toggle'),
|
|
228
|
-
})
|
|
229
|
-
|
|
230
|
-
// Context should be unchanged
|
|
231
|
-
expect(useMessageBlockStore.getState().context.theme).toBe(originalTheme)
|
|
232
|
-
})
|
|
233
|
-
})
|
|
234
|
-
|
|
235
|
-
describe('reset', () => {
|
|
236
|
-
test('restores context to initial state', () => {
|
|
237
|
-
// Modify state significantly
|
|
238
|
-
useMessageBlockStore.getState().setContext({
|
|
239
|
-
isWaitingForResponse: true,
|
|
240
|
-
timerStartTime: 12345,
|
|
241
|
-
availableWidth: 200,
|
|
242
|
-
messageTree: new Map([['key', [createAgentMessage('a', 'b', 'c')]]]),
|
|
243
|
-
})
|
|
244
|
-
|
|
245
|
-
useMessageBlockStore.getState().reset()
|
|
246
|
-
|
|
247
|
-
const state = useMessageBlockStore.getState()
|
|
248
|
-
expect(state.context.theme).toBeNull()
|
|
249
|
-
expect(state.context.isWaitingForResponse).toBe(false)
|
|
250
|
-
expect(state.context.timerStartTime).toBeNull()
|
|
251
|
-
expect(state.context.availableWidth).toBe(80)
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
test('restores callbacks to noop functions', () => {
|
|
255
|
-
const mockFn = () => console.log('test')
|
|
256
|
-
useMessageBlockStore.getState().setCallbacks({
|
|
257
|
-
onToggleCollapsed: mockFn,
|
|
258
|
-
onBuildFast: mockFn,
|
|
259
|
-
onBuildMax: mockFn,
|
|
260
|
-
onBuildLite: mockFn,
|
|
261
|
-
onFeedback: mockFn,
|
|
262
|
-
onCloseFeedback: mockFn,
|
|
263
|
-
onAdClick: mockFn,
|
|
264
|
-
onAdImpression: mockFn,
|
|
265
|
-
onResponseAdsNeeded: mockFn,
|
|
266
|
-
})
|
|
267
|
-
|
|
268
|
-
useMessageBlockStore.getState().reset()
|
|
269
|
-
|
|
270
|
-
const state = useMessageBlockStore.getState()
|
|
271
|
-
// Callbacks should be noop functions (not undefined)
|
|
272
|
-
expect(typeof state.callbacks.onToggleCollapsed).toBe('function')
|
|
273
|
-
expect(typeof state.callbacks.onBuildFast).toBe('function')
|
|
274
|
-
expect(typeof state.callbacks.onBuildLite).toBe('function')
|
|
275
|
-
// They should not throw when called
|
|
276
|
-
expect(() => state.callbacks.onToggleCollapsed('test-id')).not.toThrow()
|
|
277
|
-
})
|
|
278
|
-
})
|
|
279
|
-
})
|
|
280
|
-
|
|
281
|
-
// =============================================================================
|
|
282
|
-
// MessageWithAgents Component Tests - behavior across variants
|
|
283
|
-
// =============================================================================
|
|
284
|
-
|
|
285
|
-
describe('MessageWithAgents', () => {
|
|
286
|
-
describe('message variant rendering', () => {
|
|
287
|
-
test('renders user message content', () => {
|
|
288
|
-
const message = createUserMessage('user-1', 'Hello from user')
|
|
289
|
-
|
|
290
|
-
const markup = renderToStaticMarkup(
|
|
291
|
-
<MessageWithAgents
|
|
292
|
-
{...baseMessageWithAgentsProps}
|
|
293
|
-
message={message}
|
|
294
|
-
/>,
|
|
295
|
-
)
|
|
296
|
-
|
|
297
|
-
expect(markup).toContain('Hello from user')
|
|
298
|
-
})
|
|
299
|
-
|
|
300
|
-
test('renders AI message content', () => {
|
|
301
|
-
const message = createAiMessage('ai-1', 'Hello from AI')
|
|
302
|
-
|
|
303
|
-
const markup = renderToStaticMarkup(
|
|
304
|
-
<MessageWithAgents
|
|
305
|
-
{...baseMessageWithAgentsProps}
|
|
306
|
-
message={message}
|
|
307
|
-
/>,
|
|
308
|
-
)
|
|
309
|
-
|
|
310
|
-
expect(markup).toContain('Hello from AI')
|
|
311
|
-
})
|
|
312
|
-
|
|
313
|
-
test('renders error message content', () => {
|
|
314
|
-
const message = createErrorMessage('error-1', 'An error occurred')
|
|
315
|
-
|
|
316
|
-
const markup = renderToStaticMarkup(
|
|
317
|
-
<MessageWithAgents
|
|
318
|
-
{...baseMessageWithAgentsProps}
|
|
319
|
-
message={message}
|
|
320
|
-
/>,
|
|
321
|
-
)
|
|
322
|
-
|
|
323
|
-
expect(markup).toContain('An error occurred')
|
|
324
|
-
})
|
|
325
|
-
|
|
326
|
-
test('renders agent message with agent name displayed', () => {
|
|
327
|
-
const message = createAgentMessage('agent-1', 'Agent response', 'Code Searcher')
|
|
328
|
-
|
|
329
|
-
const markup = renderToStaticMarkup(
|
|
330
|
-
<MessageWithAgents
|
|
331
|
-
{...baseMessageWithAgentsProps}
|
|
332
|
-
message={message}
|
|
333
|
-
/>,
|
|
334
|
-
)
|
|
335
|
-
|
|
336
|
-
expect(markup).toContain('Code Searcher')
|
|
337
|
-
expect(markup).toContain('Agent response')
|
|
338
|
-
})
|
|
339
|
-
|
|
340
|
-
test('handles message with markdown content', () => {
|
|
341
|
-
const message = createAiMessage('ai-md', '**Bold** and *italic*')
|
|
342
|
-
|
|
343
|
-
const markup = renderToStaticMarkup(
|
|
344
|
-
<MessageWithAgents
|
|
345
|
-
{...baseMessageWithAgentsProps}
|
|
346
|
-
message={message}
|
|
347
|
-
/>,
|
|
348
|
-
)
|
|
349
|
-
|
|
350
|
-
// Content should be present (markdown rendering may transform it)
|
|
351
|
-
expect(markup).toContain('Bold')
|
|
352
|
-
expect(markup).toContain('italic')
|
|
353
|
-
})
|
|
354
|
-
|
|
355
|
-
test('handles empty content without crashing', () => {
|
|
356
|
-
const message = createAiMessage('ai-empty', '')
|
|
357
|
-
|
|
358
|
-
const markup = renderToStaticMarkup(
|
|
359
|
-
<MessageWithAgents
|
|
360
|
-
{...baseMessageWithAgentsProps}
|
|
361
|
-
message={message}
|
|
362
|
-
/>,
|
|
363
|
-
)
|
|
364
|
-
|
|
365
|
-
expect(markup).toBeDefined()
|
|
366
|
-
})
|
|
367
|
-
})
|
|
368
|
-
|
|
369
|
-
describe('mode divider block rendering', () => {
|
|
370
|
-
test('renders ModeDivider when message contains only a mode-divider block and ignores content', () => {
|
|
371
|
-
const message = createModeDividerMessage('mode-1', 'Edit Mode')
|
|
372
|
-
|
|
373
|
-
const markup = renderToStaticMarkup(
|
|
374
|
-
<MessageWithAgents
|
|
375
|
-
{...baseMessageWithAgentsProps}
|
|
376
|
-
message={message}
|
|
377
|
-
/>,
|
|
378
|
-
)
|
|
379
|
-
|
|
380
|
-
// Mode text should appear
|
|
381
|
-
expect(markup).toContain('Edit Mode')
|
|
382
|
-
// Original message content should not be rendered
|
|
383
|
-
expect(markup).not.toContain('this content should be ignored')
|
|
384
|
-
})
|
|
385
|
-
})
|
|
386
|
-
|
|
387
|
-
describe('error handling', () => {
|
|
388
|
-
test('shows error message when agent message is missing agent info', () => {
|
|
389
|
-
const malformedMessage = createMalformedAgentMessage(
|
|
390
|
-
'bad-agent',
|
|
391
|
-
'This should fail',
|
|
392
|
-
)
|
|
393
|
-
|
|
394
|
-
const markup = renderToStaticMarkup(
|
|
395
|
-
<MessageWithAgents
|
|
396
|
-
{...baseMessageWithAgentsProps}
|
|
397
|
-
message={malformedMessage}
|
|
398
|
-
/>,
|
|
399
|
-
)
|
|
400
|
-
|
|
401
|
-
expect(markup).toContain('Error')
|
|
402
|
-
expect(markup).toContain('Missing agent info')
|
|
403
|
-
})
|
|
404
|
-
})
|
|
405
|
-
|
|
406
|
-
describe('collapsed vs expanded agent state', () => {
|
|
407
|
-
test('renders collapsed agent with preview and collapsed indicator', () => {
|
|
408
|
-
const collapsedMessage = createAgentMessage(
|
|
409
|
-
'collapsed-agent',
|
|
410
|
-
'This is the full content\nwith multiple lines\nand the last line is shown',
|
|
411
|
-
'Collapsed Agent',
|
|
412
|
-
{
|
|
413
|
-
metadata: { isCollapsed: true },
|
|
414
|
-
},
|
|
415
|
-
)
|
|
416
|
-
|
|
417
|
-
const markup = renderToStaticMarkup(
|
|
418
|
-
<MessageWithAgents
|
|
419
|
-
{...baseMessageWithAgentsProps}
|
|
420
|
-
message={collapsedMessage}
|
|
421
|
-
/>,
|
|
422
|
-
)
|
|
423
|
-
|
|
424
|
-
expect(markup).toContain('Collapsed Agent')
|
|
425
|
-
// When collapsed, should show the collapsed indicator
|
|
426
|
-
expect(markup).toContain('▸')
|
|
427
|
-
// Preview should be the last line
|
|
428
|
-
expect(markup).toContain('and the last line is shown')
|
|
429
|
-
// First line of full content should not be present as a full block
|
|
430
|
-
expect(markup).not.toContain('This is the full content')
|
|
431
|
-
})
|
|
432
|
-
|
|
433
|
-
test('renders expanded agent with full content and expanded indicator', () => {
|
|
434
|
-
const expandedMessage = createAgentMessage(
|
|
435
|
-
'expanded-agent',
|
|
436
|
-
'Full expanded content here',
|
|
437
|
-
'Expanded Agent',
|
|
438
|
-
{
|
|
439
|
-
metadata: { isCollapsed: false },
|
|
440
|
-
},
|
|
441
|
-
)
|
|
442
|
-
|
|
443
|
-
const markup = renderToStaticMarkup(
|
|
444
|
-
<MessageWithAgents
|
|
445
|
-
{...baseMessageWithAgentsProps}
|
|
446
|
-
message={expandedMessage}
|
|
447
|
-
/>,
|
|
448
|
-
)
|
|
449
|
-
|
|
450
|
-
expect(markup).toContain('Expanded Agent')
|
|
451
|
-
expect(markup).toContain('Full expanded content here')
|
|
452
|
-
// When expanded, should show the expanded indicator
|
|
453
|
-
expect(markup).toContain('▾')
|
|
454
|
-
})
|
|
455
|
-
})
|
|
456
|
-
})
|
|
457
|
-
|
|
458
|
-
// =============================================================================
|
|
459
|
-
// Callback Integration Tests
|
|
460
|
-
// =============================================================================
|
|
461
|
-
|
|
462
|
-
describe('callback invocation', () => {
|
|
463
|
-
test('callbacks are retrievable from store and callable', () => {
|
|
464
|
-
let toggleCalledWith: string | undefined
|
|
465
|
-
const mockToggle = (id: string) => {
|
|
466
|
-
toggleCalledWith = id
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
useMessageBlockStore.getState().setCallbacks({
|
|
470
|
-
...defaultCallbacks,
|
|
471
|
-
onToggleCollapsed: mockToggle,
|
|
472
|
-
})
|
|
473
|
-
|
|
474
|
-
// Verify callback is stored and retrievable
|
|
475
|
-
const storedCallback = useMessageBlockStore.getState().callbacks
|
|
476
|
-
.onToggleCollapsed
|
|
477
|
-
storedCallback('test-message-id')
|
|
478
|
-
|
|
479
|
-
expect(toggleCalledWith).toBe('test-message-id')
|
|
480
|
-
})
|
|
481
|
-
|
|
482
|
-
test('onFeedback callback receives messageId and options', () => {
|
|
483
|
-
let feedbackMessageId: string | undefined
|
|
484
|
-
let feedbackOptions: object | undefined
|
|
485
|
-
const mockFeedback = (messageId: string, options?: object) => {
|
|
486
|
-
feedbackMessageId = messageId
|
|
487
|
-
feedbackOptions = options
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
useMessageBlockStore.getState().setCallbacks({
|
|
491
|
-
...defaultCallbacks,
|
|
492
|
-
onFeedback: mockFeedback,
|
|
493
|
-
})
|
|
494
|
-
|
|
495
|
-
const storedCallback = useMessageBlockStore.getState().callbacks.onFeedback
|
|
496
|
-
storedCallback('msg-123', { category: 'app_bug' })
|
|
497
|
-
|
|
498
|
-
expect(feedbackMessageId).toBe('msg-123')
|
|
499
|
-
expect(feedbackOptions).toEqual({ category: 'app_bug' })
|
|
500
|
-
})
|
|
501
|
-
})
|
|
502
|
-
|
|
503
|
-
// =============================================================================
|
|
504
|
-
// Layout and visual structure tests
|
|
505
|
-
// =============================================================================
|
|
506
|
-
|
|
507
|
-
describe('layout handling', () => {
|
|
508
|
-
test('renders correctly across different terminal widths', () => {
|
|
509
|
-
const widths = [20, 80, 120, 300]
|
|
510
|
-
|
|
511
|
-
for (const width of widths) {
|
|
512
|
-
const message = createAiMessage(`width-${width}`, `Content at width ${width}`)
|
|
513
|
-
const markup = renderToStaticMarkup(
|
|
514
|
-
<MessageWithAgents
|
|
515
|
-
message={message}
|
|
516
|
-
depth={0}
|
|
517
|
-
isLastMessage={false}
|
|
518
|
-
availableWidth={width}
|
|
519
|
-
/>,
|
|
520
|
-
)
|
|
521
|
-
expect(markup).toContain(`Content at width ${width}`)
|
|
522
|
-
}
|
|
523
|
-
})
|
|
524
|
-
|
|
525
|
-
test('renders correctly with isLastMessage true and false', () => {
|
|
526
|
-
const message = createAiMessage('last-msg-test', 'Test content')
|
|
527
|
-
|
|
528
|
-
const lastMarkup = renderToStaticMarkup(
|
|
529
|
-
<MessageWithAgents
|
|
530
|
-
message={message}
|
|
531
|
-
depth={0}
|
|
532
|
-
isLastMessage={true}
|
|
533
|
-
availableWidth={80}
|
|
534
|
-
/>,
|
|
535
|
-
)
|
|
536
|
-
|
|
537
|
-
const notLastMarkup = renderToStaticMarkup(
|
|
538
|
-
<MessageWithAgents
|
|
539
|
-
message={message}
|
|
540
|
-
depth={0}
|
|
541
|
-
isLastMessage={false}
|
|
542
|
-
availableWidth={80}
|
|
543
|
-
/>,
|
|
544
|
-
)
|
|
545
|
-
|
|
546
|
-
expect(lastMarkup).toContain('Test content')
|
|
547
|
-
expect(notLastMarkup).toContain('Test content')
|
|
548
|
-
})
|
|
549
|
-
})
|
|
550
|
-
|
|
551
|
-
describe('vertical line for user messages', () => {
|
|
552
|
-
test('renders vertical line box for user messages only', () => {
|
|
553
|
-
const userMessage = createUserMessage('user-line', 'User content')
|
|
554
|
-
const aiMessage = createAiMessage('ai-no-line', 'AI content')
|
|
555
|
-
|
|
556
|
-
const userMarkup = renderToStaticMarkup(
|
|
557
|
-
<MessageWithAgents
|
|
558
|
-
message={userMessage}
|
|
559
|
-
depth={0}
|
|
560
|
-
isLastMessage={false}
|
|
561
|
-
availableWidth={80}
|
|
562
|
-
/>,
|
|
563
|
-
)
|
|
564
|
-
|
|
565
|
-
const aiMarkup = renderToStaticMarkup(
|
|
566
|
-
<MessageWithAgents
|
|
567
|
-
message={aiMessage}
|
|
568
|
-
depth={0}
|
|
569
|
-
isLastMessage={false}
|
|
570
|
-
availableWidth={80}
|
|
571
|
-
/>,
|
|
572
|
-
)
|
|
573
|
-
|
|
574
|
-
// Vertical line uses style={{ width: 1, backgroundColor: lineColor }}
|
|
575
|
-
// which becomes width:1px in the style string.
|
|
576
|
-
expect(userMarkup).toContain('width:1px')
|
|
577
|
-
expect(aiMarkup).not.toContain('width:1px')
|
|
578
|
-
})
|
|
579
|
-
})
|