@alumbwe/anvil 1.0.41 → 1.0.49
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/entry.ts +5 -0
- package/src/index.tsx +27 -4
- package/src/login/plain-login.ts +60 -0
- package/src/login/supabase-auth.ts +346 -0
- package/src/pre-init/client-env.ts +17 -0
- package/src/utils/anvil-client.ts +4 -0
- package/src/utils/auth.ts +16 -4
- package/src/utils/client-env-defaults.ts +28 -0
- 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,445 +0,0 @@
|
|
|
1
|
-
import { describe, test, expect, mock, beforeEach } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { useChatStore } from '../../state/chat-store'
|
|
4
|
-
import { INPUT_MODE_CONFIGS, getInputModeConfig } from '../../utils/input-modes'
|
|
5
|
-
import { findCommand } from '../command-registry'
|
|
6
|
-
|
|
7
|
-
import type { RouterParams } from '../command-registry'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Tests for bash command execution logic.
|
|
11
|
-
*
|
|
12
|
-
* These tests cover:
|
|
13
|
-
* 1. runBashCommand - ghost vs direct mode selection based on store state
|
|
14
|
-
* 2. /bash slash command handler - immediate execution vs entering bash mode
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
describe('bash command', () => {
|
|
18
|
-
// Reset store state before each test
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
useChatStore.getState().reset()
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
describe('/bash slash command handler', () => {
|
|
24
|
-
const createMockParams = (
|
|
25
|
-
overrides: Partial<RouterParams> = {},
|
|
26
|
-
): RouterParams => ({
|
|
27
|
-
agentMode: 'DEFAULT',
|
|
28
|
-
inputRef: { current: null },
|
|
29
|
-
inputValue: '/bash',
|
|
30
|
-
isChainInProgressRef: { current: false },
|
|
31
|
-
isStreaming: false,
|
|
32
|
-
logoutMutation: {} as RouterParams['logoutMutation'],
|
|
33
|
-
streamMessageIdRef: { current: null },
|
|
34
|
-
addToQueue: mock(() => {}),
|
|
35
|
-
clearMessages: mock(() => {}),
|
|
36
|
-
saveToHistory: mock(() => {}),
|
|
37
|
-
scrollToLatest: mock(() => {}),
|
|
38
|
-
sendMessage: mock(async () => {}),
|
|
39
|
-
setCanProcessQueue: mock(() => {}),
|
|
40
|
-
setInputFocused: mock(() => {}),
|
|
41
|
-
setInputValue: mock(() => {}),
|
|
42
|
-
setIsAuthenticated: mock(() => {}),
|
|
43
|
-
setMessages: mock(() => {}),
|
|
44
|
-
setUser: mock(() => {}),
|
|
45
|
-
...overrides,
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
test('/bash command exists in registry', () => {
|
|
49
|
-
const bashCommand = findCommand('bash')
|
|
50
|
-
expect(bashCommand).toBeDefined()
|
|
51
|
-
expect(bashCommand?.name).toBe('bash')
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
test('/bash with no args enters bash mode', () => {
|
|
55
|
-
const bashCommand = findCommand('bash')
|
|
56
|
-
const params = createMockParams()
|
|
57
|
-
|
|
58
|
-
// Execute with empty args
|
|
59
|
-
bashCommand?.handler(params, '')
|
|
60
|
-
|
|
61
|
-
// Should enter bash mode
|
|
62
|
-
expect(useChatStore.getState().inputMode).toBe('bash')
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
test('/bash with args does NOT enter bash mode', () => {
|
|
66
|
-
const bashCommand = findCommand('bash')
|
|
67
|
-
const params = createMockParams()
|
|
68
|
-
|
|
69
|
-
// Execute with args - this will call runBashCommand which tries to run a real command
|
|
70
|
-
// We just verify it doesn't enter bash mode
|
|
71
|
-
bashCommand?.handler(params, 'echo test')
|
|
72
|
-
|
|
73
|
-
// Should NOT enter bash mode - command is executed immediately
|
|
74
|
-
expect(useChatStore.getState().inputMode).toBe('default')
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
test('/bash with args saves command WITH ! prefix to history', () => {
|
|
78
|
-
const saveToHistory = mock(() => {})
|
|
79
|
-
const bashCommand = findCommand('bash')
|
|
80
|
-
const params = createMockParams({ saveToHistory })
|
|
81
|
-
|
|
82
|
-
bashCommand?.handler(params, 'ls -la')
|
|
83
|
-
|
|
84
|
-
// Should save with ! prefix
|
|
85
|
-
expect(saveToHistory).toHaveBeenCalledWith('!ls -la')
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
test('/bash with no args saves original input to history', () => {
|
|
89
|
-
const saveToHistory = mock(() => {})
|
|
90
|
-
const bashCommand = findCommand('bash')
|
|
91
|
-
const params = createMockParams({
|
|
92
|
-
inputValue: '/bash',
|
|
93
|
-
saveToHistory,
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
bashCommand?.handler(params, '')
|
|
97
|
-
|
|
98
|
-
// Should save the original input
|
|
99
|
-
expect(saveToHistory).toHaveBeenCalledWith('/bash')
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
test('/bash with args clears input', () => {
|
|
103
|
-
const setInputValue = mock(() => {})
|
|
104
|
-
const bashCommand = findCommand('bash')
|
|
105
|
-
const params = createMockParams({ setInputValue })
|
|
106
|
-
|
|
107
|
-
bashCommand?.handler(params, 'pwd')
|
|
108
|
-
|
|
109
|
-
expect(setInputValue).toHaveBeenCalledWith({
|
|
110
|
-
text: '',
|
|
111
|
-
cursorPosition: 0,
|
|
112
|
-
lastEditDueToNav: false,
|
|
113
|
-
})
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
test('/bash with whitespace-only args enters bash mode', () => {
|
|
117
|
-
const bashCommand = findCommand('bash')
|
|
118
|
-
const params = createMockParams()
|
|
119
|
-
|
|
120
|
-
bashCommand?.handler(params, ' ')
|
|
121
|
-
|
|
122
|
-
// Whitespace-only should be treated as no args
|
|
123
|
-
expect(useChatStore.getState().inputMode).toBe('bash')
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
test('"!" is an alias for /bash', () => {
|
|
127
|
-
const bangCommand = findCommand('!')
|
|
128
|
-
expect(bangCommand).toBeDefined()
|
|
129
|
-
expect(bangCommand?.name).toBe('bash')
|
|
130
|
-
})
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
describe('runBashCommand mode selection', () => {
|
|
134
|
-
test('uses direct mode when not busy (no streaming agents, no chain in progress)', () => {
|
|
135
|
-
// Ensure store is in non-busy state
|
|
136
|
-
const state = useChatStore.getState()
|
|
137
|
-
expect(state.streamingAgents.size).toBe(0)
|
|
138
|
-
expect(state.isChainInProgress).toBe(false)
|
|
139
|
-
|
|
140
|
-
// The isBusy calculation should be false
|
|
141
|
-
const isBusy = state.streamingAgents.size > 0 || state.isChainInProgress
|
|
142
|
-
expect(isBusy).toBe(false)
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
test('uses ghost mode when streaming agents present', () => {
|
|
146
|
-
// Set up streaming agents
|
|
147
|
-
useChatStore.getState().setStreamingAgents(new Set(['agent-1']))
|
|
148
|
-
|
|
149
|
-
const state = useChatStore.getState()
|
|
150
|
-
const isBusy = state.streamingAgents.size > 0 || state.isChainInProgress
|
|
151
|
-
expect(isBusy).toBe(true)
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
test('uses ghost mode when chain in progress', () => {
|
|
155
|
-
// Set chain in progress
|
|
156
|
-
useChatStore.getState().setIsChainInProgress(true)
|
|
157
|
-
|
|
158
|
-
const state = useChatStore.getState()
|
|
159
|
-
const isBusy = state.streamingAgents.size > 0 || state.isChainInProgress
|
|
160
|
-
expect(isBusy).toBe(true)
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
test('uses ghost mode when both streaming and chain in progress', () => {
|
|
164
|
-
useChatStore.getState().setStreamingAgents(new Set(['agent-1']))
|
|
165
|
-
useChatStore.getState().setIsChainInProgress(true)
|
|
166
|
-
|
|
167
|
-
const state = useChatStore.getState()
|
|
168
|
-
const isBusy = state.streamingAgents.size > 0 || state.isChainInProgress
|
|
169
|
-
expect(isBusy).toBe(true)
|
|
170
|
-
})
|
|
171
|
-
})
|
|
172
|
-
|
|
173
|
-
describe('pending bash messages', () => {
|
|
174
|
-
test('addPendingBashMessage adds message to store', () => {
|
|
175
|
-
const { addPendingBashMessage } = useChatStore.getState()
|
|
176
|
-
|
|
177
|
-
addPendingBashMessage({
|
|
178
|
-
id: 'test-id',
|
|
179
|
-
command: 'ls -la',
|
|
180
|
-
stdout: '',
|
|
181
|
-
stderr: '',
|
|
182
|
-
exitCode: 0,
|
|
183
|
-
isRunning: true,
|
|
184
|
-
cwd: '/test',
|
|
185
|
-
})
|
|
186
|
-
|
|
187
|
-
const messages = useChatStore.getState().pendingBashMessages
|
|
188
|
-
expect(messages.length).toBe(1)
|
|
189
|
-
expect(messages[0].command).toBe('ls -la')
|
|
190
|
-
expect(messages[0].isRunning).toBe(true)
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
test('updatePendingBashMessage updates existing message', () => {
|
|
194
|
-
const { addPendingBashMessage, updatePendingBashMessage } =
|
|
195
|
-
useChatStore.getState()
|
|
196
|
-
|
|
197
|
-
addPendingBashMessage({
|
|
198
|
-
id: 'test-id',
|
|
199
|
-
command: 'ls -la',
|
|
200
|
-
stdout: '',
|
|
201
|
-
stderr: '',
|
|
202
|
-
exitCode: 0,
|
|
203
|
-
isRunning: true,
|
|
204
|
-
cwd: '/test',
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
updatePendingBashMessage('test-id', {
|
|
208
|
-
stdout: 'file1.txt\nfile2.txt',
|
|
209
|
-
exitCode: 0,
|
|
210
|
-
isRunning: false,
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
const messages = useChatStore.getState().pendingBashMessages
|
|
214
|
-
expect(messages[0].stdout).toBe('file1.txt\nfile2.txt')
|
|
215
|
-
expect(messages[0].isRunning).toBe(false)
|
|
216
|
-
})
|
|
217
|
-
|
|
218
|
-
test('removePendingBashMessage removes message from store', () => {
|
|
219
|
-
const { addPendingBashMessage, removePendingBashMessage } =
|
|
220
|
-
useChatStore.getState()
|
|
221
|
-
|
|
222
|
-
addPendingBashMessage({
|
|
223
|
-
id: 'test-id',
|
|
224
|
-
command: 'ls',
|
|
225
|
-
stdout: '',
|
|
226
|
-
stderr: '',
|
|
227
|
-
exitCode: 0,
|
|
228
|
-
isRunning: false,
|
|
229
|
-
cwd: '/test',
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
expect(useChatStore.getState().pendingBashMessages.length).toBe(1)
|
|
233
|
-
|
|
234
|
-
removePendingBashMessage('test-id')
|
|
235
|
-
|
|
236
|
-
expect(useChatStore.getState().pendingBashMessages.length).toBe(0)
|
|
237
|
-
})
|
|
238
|
-
|
|
239
|
-
test('clearPendingBashMessages removes all messages', () => {
|
|
240
|
-
const { addPendingBashMessage, clearPendingBashMessages } =
|
|
241
|
-
useChatStore.getState()
|
|
242
|
-
|
|
243
|
-
addPendingBashMessage({
|
|
244
|
-
id: 'test-1',
|
|
245
|
-
command: 'ls',
|
|
246
|
-
stdout: '',
|
|
247
|
-
stderr: '',
|
|
248
|
-
exitCode: 0,
|
|
249
|
-
isRunning: false,
|
|
250
|
-
cwd: '/test',
|
|
251
|
-
})
|
|
252
|
-
addPendingBashMessage({
|
|
253
|
-
id: 'test-2',
|
|
254
|
-
command: 'pwd',
|
|
255
|
-
stdout: '',
|
|
256
|
-
stderr: '',
|
|
257
|
-
exitCode: 0,
|
|
258
|
-
isRunning: false,
|
|
259
|
-
cwd: '/test',
|
|
260
|
-
})
|
|
261
|
-
|
|
262
|
-
expect(useChatStore.getState().pendingBashMessages.length).toBe(2)
|
|
263
|
-
|
|
264
|
-
clearPendingBashMessages()
|
|
265
|
-
|
|
266
|
-
expect(useChatStore.getState().pendingBashMessages.length).toBe(0)
|
|
267
|
-
})
|
|
268
|
-
})
|
|
269
|
-
|
|
270
|
-
describe('bash mode state transitions', () => {
|
|
271
|
-
test('entering bash mode sets inputMode to bash', () => {
|
|
272
|
-
useChatStore.getState().setInputMode('bash')
|
|
273
|
-
expect(useChatStore.getState().inputMode).toBe('bash')
|
|
274
|
-
})
|
|
275
|
-
|
|
276
|
-
test('exiting bash mode sets inputMode to default', () => {
|
|
277
|
-
useChatStore.getState().setInputMode('bash')
|
|
278
|
-
useChatStore.getState().setInputMode('default')
|
|
279
|
-
expect(useChatStore.getState().inputMode).toBe('default')
|
|
280
|
-
})
|
|
281
|
-
|
|
282
|
-
test('reset clears inputMode to default', () => {
|
|
283
|
-
useChatStore.getState().setInputMode('bash')
|
|
284
|
-
useChatStore.getState().reset()
|
|
285
|
-
expect(useChatStore.getState().inputMode).toBe('default')
|
|
286
|
-
})
|
|
287
|
-
})
|
|
288
|
-
|
|
289
|
-
describe('/bash with special characters in args', () => {
|
|
290
|
-
const createMockParams = (
|
|
291
|
-
overrides: Partial<RouterParams> = {},
|
|
292
|
-
): RouterParams => ({
|
|
293
|
-
agentMode: 'DEFAULT',
|
|
294
|
-
inputRef: { current: null },
|
|
295
|
-
inputValue: '/bash',
|
|
296
|
-
isChainInProgressRef: { current: false },
|
|
297
|
-
isStreaming: false,
|
|
298
|
-
logoutMutation: {} as RouterParams['logoutMutation'],
|
|
299
|
-
streamMessageIdRef: { current: null },
|
|
300
|
-
addToQueue: mock(() => {}),
|
|
301
|
-
clearMessages: mock(() => {}),
|
|
302
|
-
saveToHistory: mock(() => {}),
|
|
303
|
-
scrollToLatest: mock(() => {}),
|
|
304
|
-
sendMessage: mock(async () => {}),
|
|
305
|
-
setCanProcessQueue: mock(() => {}),
|
|
306
|
-
setInputFocused: mock(() => {}),
|
|
307
|
-
setInputValue: mock(() => {}),
|
|
308
|
-
setIsAuthenticated: mock(() => {}),
|
|
309
|
-
setMessages: mock(() => {}),
|
|
310
|
-
setUser: mock(() => {}),
|
|
311
|
-
...overrides,
|
|
312
|
-
})
|
|
313
|
-
|
|
314
|
-
test('/bash with pipe characters preserves them', () => {
|
|
315
|
-
const saveToHistory = mock(() => {})
|
|
316
|
-
const bashCommand = findCommand('bash')
|
|
317
|
-
const params = createMockParams({ saveToHistory })
|
|
318
|
-
|
|
319
|
-
bashCommand?.handler(params, 'ls | grep foo')
|
|
320
|
-
|
|
321
|
-
expect(saveToHistory).toHaveBeenCalledWith('!ls | grep foo')
|
|
322
|
-
})
|
|
323
|
-
|
|
324
|
-
test('/bash with quoted arguments preserves them', () => {
|
|
325
|
-
const saveToHistory = mock(() => {})
|
|
326
|
-
const bashCommand = findCommand('bash')
|
|
327
|
-
const params = createMockParams({ saveToHistory })
|
|
328
|
-
|
|
329
|
-
bashCommand?.handler(params, 'echo "hello world"')
|
|
330
|
-
|
|
331
|
-
expect(saveToHistory).toHaveBeenCalledWith('!echo "hello world"')
|
|
332
|
-
})
|
|
333
|
-
|
|
334
|
-
test('/bash with redirection operators preserves them', () => {
|
|
335
|
-
const saveToHistory = mock(() => {})
|
|
336
|
-
const bashCommand = findCommand('bash')
|
|
337
|
-
const params = createMockParams({ saveToHistory })
|
|
338
|
-
|
|
339
|
-
bashCommand?.handler(params, 'echo test > debug/output.txt')
|
|
340
|
-
|
|
341
|
-
expect(saveToHistory).toHaveBeenCalledWith(
|
|
342
|
-
'!echo test > debug/output.txt',
|
|
343
|
-
)
|
|
344
|
-
})
|
|
345
|
-
|
|
346
|
-
test('/bash with environment variables preserves them', () => {
|
|
347
|
-
const saveToHistory = mock(() => {})
|
|
348
|
-
const bashCommand = findCommand('bash')
|
|
349
|
-
const params = createMockParams({ saveToHistory })
|
|
350
|
-
|
|
351
|
-
bashCommand?.handler(params, 'echo $HOME')
|
|
352
|
-
|
|
353
|
-
expect(saveToHistory).toHaveBeenCalledWith('!echo $HOME')
|
|
354
|
-
})
|
|
355
|
-
|
|
356
|
-
test('/bash with semicolon command chaining preserves it', () => {
|
|
357
|
-
const saveToHistory = mock(() => {})
|
|
358
|
-
const bashCommand = findCommand('bash')
|
|
359
|
-
const params = createMockParams({ saveToHistory })
|
|
360
|
-
|
|
361
|
-
bashCommand?.handler(params, 'cd /tmp; ls')
|
|
362
|
-
|
|
363
|
-
expect(saveToHistory).toHaveBeenCalledWith('!cd /tmp; ls')
|
|
364
|
-
})
|
|
365
|
-
|
|
366
|
-
test('/bash with && command chaining preserves it', () => {
|
|
367
|
-
const saveToHistory = mock(() => {})
|
|
368
|
-
const bashCommand = findCommand('bash')
|
|
369
|
-
const params = createMockParams({ saveToHistory })
|
|
370
|
-
|
|
371
|
-
bashCommand?.handler(params, 'mkdir test && cd test')
|
|
372
|
-
|
|
373
|
-
expect(saveToHistory).toHaveBeenCalledWith('!mkdir test && cd test')
|
|
374
|
-
})
|
|
375
|
-
})
|
|
376
|
-
|
|
377
|
-
describe('bang prefix handling in queue', () => {
|
|
378
|
-
test('command starting with ! and length > 1 is recognized as bash command', () => {
|
|
379
|
-
const input = '!ls -la'
|
|
380
|
-
const isBashFromQueue = input.startsWith('!') && input.length > 1
|
|
381
|
-
expect(isBashFromQueue).toBe(true)
|
|
382
|
-
})
|
|
383
|
-
|
|
384
|
-
test('single ! character is NOT recognized as bash command from queue', () => {
|
|
385
|
-
const input = '!'
|
|
386
|
-
const isBashFromQueue = input.startsWith('!') && input.length > 1
|
|
387
|
-
expect(isBashFromQueue).toBe(false)
|
|
388
|
-
})
|
|
389
|
-
|
|
390
|
-
test('command extracts correctly without ! prefix', () => {
|
|
391
|
-
const input = '!git status'
|
|
392
|
-
const command = input.slice(1)
|
|
393
|
-
expect(command).toBe('git status')
|
|
394
|
-
})
|
|
395
|
-
|
|
396
|
-
test('empty string is not a bash command from queue', () => {
|
|
397
|
-
const input = ''
|
|
398
|
-
const isBashFromQueue = input.startsWith('!') && input.length > 1
|
|
399
|
-
expect(isBashFromQueue).toBe(false)
|
|
400
|
-
})
|
|
401
|
-
|
|
402
|
-
test('regular text without ! is not a bash command from queue', () => {
|
|
403
|
-
const input = 'help me with this'
|
|
404
|
-
const isBashFromQueue = input.startsWith('!') && input.length > 1
|
|
405
|
-
expect(isBashFromQueue).toBe(false)
|
|
406
|
-
})
|
|
407
|
-
})
|
|
408
|
-
|
|
409
|
-
describe('bash mode configuration', () => {
|
|
410
|
-
test('bash mode has correct label', () => {
|
|
411
|
-
const config = getInputModeConfig('bash')
|
|
412
|
-
expect(config.icon).toBe(null)
|
|
413
|
-
expect(config.label).toBe('!')
|
|
414
|
-
})
|
|
415
|
-
|
|
416
|
-
test('bash mode uses info color', () => {
|
|
417
|
-
const config = getInputModeConfig('bash')
|
|
418
|
-
expect(config.color).toBe('info')
|
|
419
|
-
})
|
|
420
|
-
|
|
421
|
-
test('bash mode has correct placeholder', () => {
|
|
422
|
-
const config = getInputModeConfig('bash')
|
|
423
|
-
expect(config.placeholder).toBe('enter bash command...')
|
|
424
|
-
})
|
|
425
|
-
|
|
426
|
-
test('bash mode has width adjustment of 4', () => {
|
|
427
|
-
const config = getInputModeConfig('bash')
|
|
428
|
-
expect(config.widthAdjustment).toBe(4)
|
|
429
|
-
})
|
|
430
|
-
|
|
431
|
-
test('bash mode hides agent mode toggle', () => {
|
|
432
|
-
const config = getInputModeConfig('bash')
|
|
433
|
-
expect(config.showAgentModeToggle).toBe(false)
|
|
434
|
-
})
|
|
435
|
-
|
|
436
|
-
test('bash mode disables slash command suggestions', () => {
|
|
437
|
-
const config = getInputModeConfig('bash')
|
|
438
|
-
expect(config.disableSlashSuggestions).toBe(true)
|
|
439
|
-
})
|
|
440
|
-
|
|
441
|
-
test('bash mode config exists in INPUT_MODE_CONFIGS', () => {
|
|
442
|
-
expect(INPUT_MODE_CONFIGS.bash).toBeDefined()
|
|
443
|
-
})
|
|
444
|
-
})
|
|
445
|
-
})
|