@alumbwe/anvil 1.0.42 → 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.
Files changed (238) hide show
  1. package/bin/anvil.js +18 -0
  2. package/package.json +13 -6
  3. package/src/agents/bundled-agents.generated.ts +1 -1
  4. package/src/index.tsx +27 -4
  5. package/src/login/plain-login.ts +60 -0
  6. package/src/login/supabase-auth.ts +346 -0
  7. package/src/utils/anvil-client.ts +4 -0
  8. package/src/utils/auth.ts +16 -4
  9. package/src/utils/config-dir.ts +1 -1
  10. package/vendor/@anvil/common/src/constants/deepseek-direct.ts +30 -1
  11. package/vendor/@anvil/common/src/util/project-ignore.ts +4 -3
  12. package/vendor/@anvil/sdk/dist/index.cjs +46 -10
  13. package/vendor/@anvil/sdk/dist/index.mjs +46 -10
  14. package/src/commands/__tests__/anvil-command-aliases.test.ts +0 -56
  15. package/src/commands/__tests__/bash-command.test.ts +0 -445
  16. package/src/commands/__tests__/command-args.test.ts +0 -349
  17. package/src/commands/__tests__/copy-conversation-clipboard.test.ts +0 -108
  18. package/src/commands/__tests__/copy-conversation.test.ts +0 -226
  19. package/src/commands/__tests__/diagnostics-command.test.ts +0 -35
  20. package/src/commands/__tests__/image.test.ts +0 -99
  21. package/src/commands/__tests__/init.test.ts +0 -456
  22. package/src/commands/__tests__/new-command-rotates-chat.test.ts +0 -91
  23. package/src/commands/__tests__/process-diagnostics.test.ts +0 -54
  24. package/src/commands/__tests__/prompt-builders.test.ts +0 -28
  25. package/src/commands/__tests__/router-input.test.ts +0 -298
  26. package/src/components/__tests__/ad-banner.test.tsx +0 -83
  27. package/src/components/__tests__/anvil-landing-heading-row.test.tsx +0 -91
  28. package/src/components/__tests__/anvil-model-selector.test.tsx +0 -519
  29. package/src/components/__tests__/anvil-offer-invariants.test.ts +0 -54
  30. package/src/components/__tests__/anvil-takeover-prompt.test.tsx +0 -212
  31. package/src/components/__tests__/chat-input-bar.test.tsx +0 -130
  32. package/src/components/__tests__/grid-layout.integration.test.tsx +0 -304
  33. package/src/components/__tests__/grid-layout.test.tsx +0 -1051
  34. package/src/components/__tests__/message-block.completion.test.tsx +0 -104
  35. package/src/components/__tests__/message-block.streaming.test.tsx +0 -78
  36. package/src/components/__tests__/message-with-agents.test.tsx +0 -579
  37. package/src/components/__tests__/multiline-input.test.tsx +0 -1132
  38. package/src/components/__tests__/queue-panel.test.tsx +0 -398
  39. package/src/components/__tests__/selectable-list.test.ts +0 -232
  40. package/src/components/__tests__/status-bar.test.tsx +0 -44
  41. package/src/components/__tests__/status-indicator.test.tsx +0 -204
  42. package/src/components/__tests__/terminal-thinking-orb.test.tsx +0 -111
  43. package/src/components/__tests__/user-error-banner.test.tsx +0 -102
  44. package/src/components/ask-user/__tests__/multiple-choice-form.test.ts +0 -432
  45. package/src/components/ask-user/__tests__/validation.test.ts +0 -213
  46. package/src/components/tools/__tests__/apply-patch.test.tsx +0 -84
  47. package/src/components/tools/__tests__/code-search.test.tsx +0 -45
  48. package/src/components/tools/__tests__/gravity-index.test.ts +0 -76
  49. package/src/components/tools/__tests__/render-ui.test.tsx +0 -92
  50. package/src/components/tools/__tests__/run-terminal-command.test.ts +0 -233
  51. package/src/contexts/__tests__/chat-runtime-context.test.tsx +0 -149
  52. package/src/data/slash-commands.test.ts +0 -24
  53. package/src/hooks/__tests__/holds-live-anvil-slot.test.ts +0 -49
  54. package/src/hooks/__tests__/session-fetch-signal.test.ts +0 -63
  55. package/src/hooks/__tests__/use-activity-query.test.ts +0 -1000
  56. package/src/hooks/__tests__/use-ask-user-bridge.test.ts +0 -176
  57. package/src/hooks/__tests__/use-auth-query.test.ts +0 -21
  58. package/src/hooks/__tests__/use-chat-input-remount.test.tsx +0 -66
  59. package/src/hooks/__tests__/use-clipboard.test.tsx +0 -73
  60. package/src/hooks/__tests__/use-connection-status.test.ts +0 -112
  61. package/src/hooks/__tests__/use-directory-browser.test.ts +0 -203
  62. package/src/hooks/__tests__/use-gravity-ad.test.ts +0 -73
  63. package/src/hooks/__tests__/use-grid-layout.test.ts +0 -349
  64. package/src/hooks/__tests__/use-input-history.test.ts +0 -699
  65. package/src/hooks/__tests__/use-message-queue-editing.test.tsx +0 -209
  66. package/src/hooks/__tests__/use-message-queue.test.tsx +0 -71
  67. package/src/hooks/__tests__/use-path-tab-completion.test.ts +0 -315
  68. package/src/hooks/__tests__/use-queue-controls.test.ts +0 -68
  69. package/src/hooks/__tests__/use-queue-ui.test.tsx +0 -83
  70. package/src/hooks/__tests__/use-searchable-list.test.ts +0 -359
  71. package/src/hooks/__tests__/use-send-message-timer.test.ts +0 -146
  72. package/src/hooks/__tests__/use-suggestion-engine-mention.test.ts +0 -361
  73. package/src/hooks/__tests__/use-suggestion-engine.test.ts +0 -485
  74. package/src/hooks/__tests__/use-terminal-focus.test.ts +0 -66
  75. package/src/hooks/__tests__/use-terminal-layout.test.ts +0 -675
  76. package/src/hooks/__tests__/use-timeout.test.ts +0 -330
  77. package/src/hooks/__tests__/use-usage-query.test.ts +0 -502
  78. package/src/hooks/__tests__/use-user-details-query.test.ts +0 -195
  79. package/src/hooks/helpers/__tests__/send-message.test.ts +0 -1918
  80. package/src/init/__tests__/init-direnv.test.ts +0 -526
  81. package/src/state/__tests__/chat-store-focus.test.ts +0 -22
  82. package/src/state/__tests__/feedback-store.test.ts +0 -257
  83. package/src/utils/__tests__/active-run.test.ts +0 -140
  84. package/src/utils/__tests__/activity-tracker.test.ts +0 -440
  85. package/src/utils/__tests__/agent-display.test.ts +0 -139
  86. package/src/utils/__tests__/analytics-client.test.ts +0 -262
  87. package/src/utils/__tests__/anonymous-id.test.ts +0 -74
  88. package/src/utils/__tests__/anvil-api.test.ts +0 -578
  89. package/src/utils/__tests__/anvil-instance-owner.test.ts +0 -69
  90. package/src/utils/__tests__/anvil-model-navigation.test.ts +0 -102
  91. package/src/utils/__tests__/anvil-premium-reset.test.ts +0 -79
  92. package/src/utils/__tests__/anvil-referral-cache.test.ts +0 -116
  93. package/src/utils/__tests__/anvil-session-api.test.ts +0 -215
  94. package/src/utils/__tests__/anvil-session-display.test.ts +0 -23
  95. package/src/utils/__tests__/anvil-streak-line.test.ts +0 -217
  96. package/src/utils/__tests__/arrays.test.ts +0 -264
  97. package/src/utils/__tests__/bash-context-processor.test.ts +0 -38
  98. package/src/utils/__tests__/block-processor.test.ts +0 -810
  99. package/src/utils/__tests__/chat-history.test.ts +0 -203
  100. package/src/utils/__tests__/chat-input-key-intercept.test.ts +0 -40
  101. package/src/utils/__tests__/chat-meta.test.ts +0 -130
  102. package/src/utils/__tests__/clipboard-linux.test.ts +0 -359
  103. package/src/utils/__tests__/clipboard.test.ts +0 -910
  104. package/src/utils/__tests__/code-search-summary.test.ts +0 -84
  105. package/src/utils/__tests__/collapse-helpers.test.ts +0 -1109
  106. package/src/utils/__tests__/error-handling.test.ts +0 -658
  107. package/src/utils/__tests__/exit-cleanly.test.ts +0 -110
  108. package/src/utils/__tests__/feedback-helpers.test.ts +0 -444
  109. package/src/utils/__tests__/feedback-submission.test.ts +0 -26
  110. package/src/utils/__tests__/fetch-usage.test.ts +0 -355
  111. package/src/utils/__tests__/fingerprint.test.ts +0 -144
  112. package/src/utils/__tests__/fixtures/terminal-command-broker-child.ts +0 -7
  113. package/src/utils/__tests__/fixtures/terminal-command-broker-entry.ts +0 -3
  114. package/src/utils/__tests__/fixtures/terminal-command-broker-owner.ts +0 -33
  115. package/src/utils/__tests__/format-elapsed-time.test.ts +0 -103
  116. package/src/utils/__tests__/format-timeout.test.ts +0 -87
  117. package/src/utils/__tests__/image-dimensions.test.ts +0 -249
  118. package/src/utils/__tests__/image-processor.test.ts +0 -209
  119. package/src/utils/__tests__/implementor-helpers.test.ts +0 -1458
  120. package/src/utils/__tests__/keyboard-actions.test.ts +0 -660
  121. package/src/utils/__tests__/layout-helpers.test.ts +0 -36
  122. package/src/utils/__tests__/lazy-response-ads.test.ts +0 -167
  123. package/src/utils/__tests__/log-shipper.test.ts +0 -53
  124. package/src/utils/__tests__/markdown-renderer.test.tsx +0 -421
  125. package/src/utils/__tests__/message-block-helpers.test.ts +0 -1263
  126. package/src/utils/__tests__/message-updater.test.ts +0 -645
  127. package/src/utils/__tests__/osc-timeout-scenarios.test.ts +0 -172
  128. package/src/utils/__tests__/pending-attachments.test.ts +0 -277
  129. package/src/utils/__tests__/polling-backoff.test.ts +0 -51
  130. package/src/utils/__tests__/queue-panel-actions.test.ts +0 -148
  131. package/src/utils/__tests__/run-state-storage.test.ts +0 -919
  132. package/src/utils/__tests__/safe-json.test.ts +0 -77
  133. package/src/utils/__tests__/sdk-event-handlers.test.ts +0 -685
  134. package/src/utils/__tests__/send-message-helpers.test.ts +0 -1898
  135. package/src/utils/__tests__/send-message-timer.test.ts +0 -64
  136. package/src/utils/__tests__/settings.test.ts +0 -99
  137. package/src/utils/__tests__/strings.test.ts +0 -192
  138. package/src/utils/__tests__/terminal-color-detection.test.ts +0 -425
  139. package/src/utils/__tests__/terminal-command-broker.test.ts +0 -528
  140. package/src/utils/__tests__/terminal-enter-detection.test.ts +0 -77
  141. package/src/utils/__tests__/terminal-io.test.ts +0 -137
  142. package/src/utils/__tests__/terminal-protocol-controller.test.ts +0 -119
  143. package/src/utils/__tests__/text-layout.test.ts +0 -82
  144. package/src/utils/__tests__/theme-platform-detection.test.ts +0 -125
  145. package/src/utils/__tests__/think-tag-parser.test.ts +0 -159
  146. package/src/utils/__tests__/trace-writer.test.ts +0 -223
  147. package/src/utils/__tests__/trim-chat-logs.test.ts +0 -78
  148. package/src/utils/__tests__/usage-banner-state.test.ts +0 -298
  149. package/src/utils/__tests__/validation-error-formatting.test.ts +0 -126
  150. package/src/utils/__tests__/windows-terminal-health.test.ts +0 -101
  151. package/src/utils/__tests__/write-file-atomic.test.ts +0 -127
  152. package/vendor/@anvil/common/src/__tests__/agent-validation.test.ts +0 -846
  153. package/vendor/@anvil/common/src/__tests__/anvil-model-availability.test.ts +0 -101
  154. package/vendor/@anvil/common/src/__tests__/anvil-models.test.ts +0 -1408
  155. package/vendor/@anvil/common/src/__tests__/anvil-public-data-use-copy.test.ts +0 -258
  156. package/vendor/@anvil/common/src/__tests__/anvil-referral-tiers.test.ts +0 -48
  157. package/vendor/@anvil/common/src/__tests__/anvil-spend-ceilings.test.ts +0 -282
  158. package/vendor/@anvil/common/src/__tests__/anvil-trust.test.ts +0 -526
  159. package/vendor/@anvil/common/src/__tests__/deepseek-direct.test.ts +0 -68
  160. package/vendor/@anvil/common/src/__tests__/disposable-email.test.ts +0 -132
  161. package/vendor/@anvil/common/src/__tests__/dynamic-agent-template-schema.test.ts +0 -422
  162. package/vendor/@anvil/common/src/__tests__/env-ci.test.ts +0 -167
  163. package/vendor/@anvil/common/src/__tests__/env-process.test.ts +0 -145
  164. package/vendor/@anvil/common/src/__tests__/foreign-client-shipped-agents.test.ts +0 -234
  165. package/vendor/@anvil/common/src/__tests__/foreign-client-signals.test.ts +0 -379
  166. package/vendor/@anvil/common/src/__tests__/free-agents.test.ts +0 -807
  167. package/vendor/@anvil/common/src/__tests__/gravity-capi.test.ts +0 -154
  168. package/vendor/@anvil/common/src/__tests__/handlesteps-parsing.test.ts +0 -246
  169. package/vendor/@anvil/common/src/__tests__/kimi-k3-god-only.test.ts +0 -77
  170. package/vendor/@anvil/common/src/__tests__/model-config.test.ts +0 -89
  171. package/vendor/@anvil/common/src/__tests__/project-file-tree.test.ts +0 -298
  172. package/vendor/@anvil/common/src/__tests__/provisioned-model-tiers.test.ts +0 -116
  173. package/vendor/@anvil/common/src/__tests__/reasoning-effort.test.ts +0 -167
  174. package/vendor/@anvil/common/src/__tests__/reddit-capi.test.ts +0 -132
  175. package/vendor/@anvil/common/src/__tests__/response-ad-positions.test.ts +0 -72
  176. package/vendor/@anvil/common/src/__tests__/user-state.test.ts +0 -30
  177. package/vendor/@anvil/common/src/constants/__tests__/anvil-onboarding-gate.test.ts +0 -63
  178. package/vendor/@anvil/common/src/constants/__tests__/anvil-onboarding.test.ts +0 -246
  179. package/vendor/@anvil/common/src/constants/__tests__/cf-worker-signals.test.ts +0 -106
  180. package/vendor/@anvil/common/src/testing/TESTING_PATTERNS.md +0 -351
  181. package/vendor/@anvil/common/src/testing/anvil-offer-invariants.ts +0 -169
  182. package/vendor/@anvil/common/src/testing/errors.ts +0 -33
  183. package/vendor/@anvil/common/src/testing/fixtures/agent-runtime.ts +0 -334
  184. package/vendor/@anvil/common/src/testing/impl/agent-runtime.ts +0 -6
  185. package/vendor/@anvil/common/src/testing/index.ts +0 -84
  186. package/vendor/@anvil/common/src/testing/mock-modules.ts +0 -53
  187. package/vendor/@anvil/common/src/testing/mock-types.ts +0 -123
  188. package/vendor/@anvil/common/src/testing/mocks/analytics.ts +0 -261
  189. package/vendor/@anvil/common/src/testing/mocks/child-process.ts +0 -93
  190. package/vendor/@anvil/common/src/testing/mocks/crypto.ts +0 -218
  191. package/vendor/@anvil/common/src/testing/mocks/database.ts +0 -337
  192. package/vendor/@anvil/common/src/testing/mocks/fetch.ts +0 -219
  193. package/vendor/@anvil/common/src/testing/mocks/filesystem.ts +0 -166
  194. package/vendor/@anvil/common/src/testing/mocks/index.ts +0 -101
  195. package/vendor/@anvil/common/src/testing/mocks/logger.ts +0 -135
  196. package/vendor/@anvil/common/src/testing/mocks/stream.ts +0 -313
  197. package/vendor/@anvil/common/src/testing/mocks/timers.ts +0 -132
  198. package/vendor/@anvil/common/src/testing/mocks/tree-sitter.ts +0 -127
  199. package/vendor/@anvil/common/src/testing/setup.ts +0 -282
  200. package/vendor/@anvil/common/src/tools/__tests__/compile-tool-definitions.test.ts +0 -34
  201. package/vendor/@anvil/common/src/tools/params/__tests__/coerce-to-array.test.ts +0 -213
  202. package/vendor/@anvil/common/src/tools/params/__tests__/read-docs.test.ts +0 -47
  203. package/vendor/@anvil/common/src/tools/params/__tests__/render-ui.test.ts +0 -65
  204. package/vendor/@anvil/common/src/tools/params/tool/__tests__/run-terminal-command-timeout.test.ts +0 -49
  205. package/vendor/@anvil/common/src/types/__tests__/dynamic-agent-template.test.ts +0 -20
  206. package/vendor/@anvil/common/src/util/__tests__/ad-user-agent.test.ts +0 -26
  207. package/vendor/@anvil/common/src/util/__tests__/analytics-dispatcher.test.ts +0 -122
  208. package/vendor/@anvil/common/src/util/__tests__/analytics-log.test.ts +0 -102
  209. package/vendor/@anvil/common/src/util/__tests__/analytics-sampling.test.ts +0 -143
  210. package/vendor/@anvil/common/src/util/__tests__/anvil-streak.test.ts +0 -202
  211. package/vendor/@anvil/common/src/util/__tests__/anvil-usage-summary.test.ts +0 -193
  212. package/vendor/@anvil/common/src/util/__tests__/axiom-only-log.test.ts +0 -140
  213. package/vendor/@anvil/common/src/util/__tests__/client-user-agent.test.ts +0 -148
  214. package/vendor/@anvil/common/src/util/__tests__/engagement-tracker.test.ts +0 -115
  215. package/vendor/@anvil/common/src/util/__tests__/env-file-path.test.ts +0 -57
  216. package/vendor/@anvil/common/src/util/__tests__/error-abort.test.ts +0 -774
  217. package/vendor/@anvil/common/src/util/__tests__/error-api-details.test.ts +0 -206
  218. package/vendor/@anvil/common/src/util/__tests__/file-read-limits.test.ts +0 -173
  219. package/vendor/@anvil/common/src/util/__tests__/format-code-search.test.ts +0 -60
  220. package/vendor/@anvil/common/src/util/__tests__/log-mirror.test.ts +0 -31
  221. package/vendor/@anvil/common/src/util/__tests__/messages.test.ts +0 -1252
  222. package/vendor/@anvil/common/src/util/__tests__/partial-json-delta.test.ts +0 -505
  223. package/vendor/@anvil/common/src/util/__tests__/path.test.ts +0 -22
  224. package/vendor/@anvil/common/src/util/__tests__/project-ignore.test.ts +0 -90
  225. package/vendor/@anvil/common/src/util/__tests__/promise.test.ts +0 -325
  226. package/vendor/@anvil/common/src/util/__tests__/rate-limit.test.ts +0 -28
  227. package/vendor/@anvil/common/src/util/__tests__/reddit-anvil-retention.test.ts +0 -130
  228. package/vendor/@anvil/common/src/util/__tests__/saxy.test.ts +0 -1008
  229. package/vendor/@anvil/common/src/util/__tests__/split-data.test.ts +0 -289
  230. package/vendor/@anvil/common/src/util/__tests__/string.test.ts +0 -239
  231. package/vendor/@anvil/common/src/util/__tests__/thread-title.test.ts +0 -70
  232. package/vendor/@anvil/common/src/util/__tests__/tool-result-media-order.test.ts +0 -108
  233. package/vendor/@anvil/common/src/util/__tests__/ttft-histogram.test.ts +0 -180
  234. package/vendor/@anvil/common/src/util/__tests__/with-timeout.test.ts +0 -24
  235. package/vendor/@anvil/common/src/util/__tests__/zoned-time.test.ts +0 -88
  236. package/vendor/@anvil/common/src/util/skills.test.ts +0 -44
  237. package/vendor/@anvil/sdk/dist/index.cjs.map +0 -440
  238. package/vendor/@anvil/sdk/dist/index.mjs.map +0 -440
@@ -1,84 +0,0 @@
1
- import { 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 { chatThemes } from '../../../utils/theme-system'
7
- import { getToolComponent, renderToolComponent } from '../registry'
8
-
9
- import type { ToolBlock } from '../types'
10
-
11
- initializeThemeStore()
12
-
13
- const createToolBlock = (
14
- operation: Record<string, unknown>,
15
- ): ToolBlock & { toolName: 'apply_patch' } => ({
16
- type: 'tool',
17
- toolName: 'apply_patch',
18
- toolCallId: 'apply-patch-test-id',
19
- input: { operation },
20
- })
21
-
22
- const renderOptions = {
23
- availableWidth: 80,
24
- indentationOffset: 0,
25
- labelWidth: 0,
26
- }
27
-
28
- describe('ApplyPatchComponent', () => {
29
- test('is registered for apply_patch tool calls', () => {
30
- expect(getToolComponent('apply_patch')).toBeDefined()
31
- })
32
-
33
- test('renders create_file operation', () => {
34
- const toolBlock = createToolBlock({
35
- type: 'create_file',
36
- path: 'src/new-file.ts',
37
- diff: '@@\n+export const value = 1\n',
38
- })
39
-
40
- const result = renderToolComponent(toolBlock, chatThemes.dark, renderOptions)
41
-
42
- expect(result).toBeDefined()
43
- expect(result?.content).toBeDefined()
44
-
45
- const markup = renderToStaticMarkup(result?.content as React.ReactElement)
46
- expect(markup).toContain('Create')
47
- expect(markup).toContain('src/new-file.ts')
48
- })
49
-
50
- test('renders update_file operation with diff content', () => {
51
- const toolBlock = createToolBlock({
52
- type: 'update_file',
53
- path: 'src/existing.ts',
54
- diff: '@@\n-oldLine\n+newLine\n',
55
- })
56
-
57
- const result = renderToolComponent(toolBlock, chatThemes.dark, renderOptions)
58
-
59
- expect(result).toBeDefined()
60
- expect(result?.content).toBeDefined()
61
-
62
- const markup = renderToStaticMarkup(result?.content as React.ReactElement)
63
- expect(markup).toContain('Edit')
64
- expect(markup).toContain('src/existing.ts')
65
- expect(markup).toContain('-oldLine')
66
- expect(markup).toContain('+newLine')
67
- })
68
-
69
- test('renders delete_file operation', () => {
70
- const toolBlock = createToolBlock({
71
- type: 'delete_file',
72
- path: 'src/remove-me.ts',
73
- })
74
-
75
- const result = renderToolComponent(toolBlock, chatThemes.dark, renderOptions)
76
-
77
- expect(result).toBeDefined()
78
- expect(result?.content).toBeDefined()
79
-
80
- const markup = renderToStaticMarkup(result?.content as React.ReactElement)
81
- expect(markup).toContain('Delete')
82
- expect(markup).toContain('src/remove-me.ts')
83
- })
84
- })
@@ -1,45 +0,0 @@
1
- import { 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 { CodeSearchComponent } from '../code-search'
7
-
8
- import type { ChatTheme } from '../../../types/theme-system'
9
- import type { ToolBlock } from '../types'
10
-
11
- initializeThemeStore()
12
-
13
- const createToolBlock = (
14
- output?: string,
15
- ): ToolBlock & { toolName: 'code_search' } => ({
16
- type: 'tool',
17
- toolName: 'code_search',
18
- toolCallId: 'code-search-test',
19
- input: {
20
- pattern: 'getAgentBaseName',
21
- cwd: 'cli/src/utils',
22
- },
23
- output,
24
- })
25
-
26
- describe('CodeSearchComponent', () => {
27
- test('uses formatted match count from current code search output', () => {
28
- const result = CodeSearchComponent.render(
29
- createToolBlock(`Found 2 matches
30
- ./message-block-helpers.ts:
31
- Line 13: export const getAgentBaseName = (type: string): string => {
32
- Line 196: getAgentBaseName(options.agentType ?? '') === 'code-searcher'`),
33
- {} as ChatTheme,
34
- {
35
- availableWidth: 80,
36
- indentationOffset: 0,
37
- labelWidth: 10,
38
- },
39
- )
40
-
41
- const markup = renderToStaticMarkup(<>{result.content}</>)
42
-
43
- expect(markup).toContain('getAgentBaseName in cli/src/utils (2 results)')
44
- })
45
- })
@@ -1,76 +0,0 @@
1
- import { describe, expect, test } from 'bun:test'
2
-
3
- import { getGravityIndexParts } from '../gravity-index'
4
-
5
- describe('getGravityIndexParts', () => {
6
- test('describes search queries', () => {
7
- expect(
8
- getGravityIndexParts({
9
- action: 'search',
10
- query: 'transactional email for a Next.js app',
11
- }),
12
- ).toEqual({
13
- name: 'Search services',
14
- description: 'transactional email for a Next.js app',
15
- })
16
- })
17
-
18
- test('describes browse category and keyword', () => {
19
- expect(
20
- getGravityIndexParts({
21
- action: 'browse',
22
- category: 'Email',
23
- q: 'send',
24
- }),
25
- ).toEqual({
26
- name: 'Browse services',
27
- description: 'Email · send',
28
- })
29
- })
30
-
31
- test('describes service detail lookups', () => {
32
- expect(
33
- getGravityIndexParts({
34
- action: 'get_service',
35
- slug: 'sendgrid',
36
- }),
37
- ).toEqual({
38
- name: 'Fetch service',
39
- description: 'sendgrid',
40
- })
41
- })
42
-
43
- test('describes completed integration reports', () => {
44
- expect(
45
- getGravityIndexParts({
46
- action: 'report_integration',
47
- integrated_slug: 'sendgrid',
48
- }),
49
- ).toEqual({
50
- name: 'Report integration',
51
- description: 'sendgrid integration',
52
- })
53
- })
54
-
55
- test('names the action even when the target is missing', () => {
56
- expect(getGravityIndexParts({ action: 'search' })).toEqual({
57
- name: 'Search services',
58
- description: '',
59
- })
60
- expect(getGravityIndexParts({ action: 'list_categories' })).toEqual({
61
- name: 'List service categories',
62
- description: '',
63
- })
64
- })
65
-
66
- test('falls back to the brand for unknown input', () => {
67
- expect(getGravityIndexParts({ action: 'unknown' })).toEqual({
68
- name: 'Services',
69
- description: '',
70
- })
71
- expect(getGravityIndexParts(null)).toEqual({
72
- name: 'Services',
73
- description: '',
74
- })
75
- })
76
- })
@@ -1,92 +0,0 @@
1
- import { 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 { chatThemes } from '../../../utils/theme-system'
7
- import { RenderUIComponent } from '../render-ui'
8
-
9
- import type { ToolBlock } from '../types'
10
-
11
- initializeThemeStore()
12
-
13
- const createToolBlock = (
14
- input: unknown,
15
- ): ToolBlock & { toolName: 'render_ui' } => ({
16
- type: 'tool',
17
- toolName: 'render_ui',
18
- toolCallId: 'test-render-ui-call-id',
19
- input,
20
- })
21
-
22
- describe('RenderUIComponent', () => {
23
- test('renders a button widget', () => {
24
- const result = RenderUIComponent.render(
25
- createToolBlock({
26
- widget: {
27
- type: 'button',
28
- text: 'Open preview',
29
- link: 'https://example.com/preview',
30
- variant: 'primary',
31
- },
32
- }),
33
- chatThemes.light,
34
- {
35
- availableWidth: 80,
36
- indentationOffset: 0,
37
- labelWidth: 10,
38
- },
39
- )
40
-
41
- expect(result.collapsedPreview).toBe(
42
- 'Open preview -> https://example.com/preview',
43
- )
44
- expect(result.content).toBeDefined()
45
- expect(renderToStaticMarkup(<>{result.content}</>)).toContain(
46
- 'Open preview',
47
- )
48
- })
49
-
50
- test('does not render an unresolved Gravity reference', () => {
51
- const result = RenderUIComponent.render(
52
- createToolBlock({
53
- widget: {
54
- type: 'button',
55
- text: 'Get your Resend API key',
56
- link: {
57
- source: 'gravity_index',
58
- search_id: 'search-1',
59
- service_slug: 'resend',
60
- },
61
- },
62
- }),
63
- chatThemes.light,
64
- {
65
- availableWidth: 80,
66
- indentationOffset: 0,
67
- labelWidth: 10,
68
- },
69
- )
70
-
71
- expect(result.content).toBeNull()
72
- })
73
-
74
- test('returns no content for unsupported widgets', () => {
75
- const result = RenderUIComponent.render(
76
- createToolBlock({
77
- widget: {
78
- type: 'slider',
79
- text: 'Volume',
80
- },
81
- }),
82
- chatThemes.light,
83
- {
84
- availableWidth: 80,
85
- indentationOffset: 0,
86
- labelWidth: 10,
87
- },
88
- )
89
-
90
- expect(result.content).toBeNull()
91
- })
92
- })
@@ -1,233 +0,0 @@
1
- import { describe, expect, test } from 'bun:test'
2
-
3
- import { parseTerminalOutput, RunTerminalCommandComponent } from '../run-terminal-command'
4
-
5
- import type { ChatTheme } from '../../../types/theme-system'
6
- import type { ToolBlock } from '../types'
7
- import type { ReactElement } from 'react'
8
-
9
- // Use ChatTheme import for proper typing
10
-
11
- // Type for the render result content element
12
- interface RenderContentElement extends ReactElement {
13
- props: {
14
- timeoutSeconds?: number
15
- }
16
- }
17
-
18
- // Helper to create a mock tool block
19
- const createToolBlock = (
20
- command: string,
21
- output?: string,
22
- timeoutSeconds?: number,
23
- ): ToolBlock & { toolName: 'run_terminal_command' } => ({
24
- type: 'tool',
25
- toolName: 'run_terminal_command',
26
- toolCallId: 'test-tool-call-id',
27
- input: { command, ...(timeoutSeconds !== undefined && { timeout_seconds: timeoutSeconds }) },
28
- output,
29
- })
30
-
31
- // Helper to create JSON output in the format the component expects
32
- const createJsonOutput = (stdout: string, stderr = ''): string => {
33
- return JSON.stringify([
34
- {
35
- type: 'json',
36
- value: {
37
- command: 'test',
38
- stdout,
39
- stderr,
40
- exitCode: 0,
41
- },
42
- },
43
- ])
44
- }
45
-
46
- describe('RunTerminalCommandComponent', () => {
47
- describe('render', () => {
48
- test('returns content and collapsedPreview', () => {
49
- const toolBlock = createToolBlock('ls -la', createJsonOutput('file1\nfile2'))
50
- const mockTheme = {} as ChatTheme
51
- const mockOptions = {
52
- availableWidth: 80,
53
- indentationOffset: 0,
54
- labelWidth: 10,
55
- }
56
-
57
- const result = RunTerminalCommandComponent.render(toolBlock, mockTheme, mockOptions)
58
-
59
- expect(result).toBeDefined()
60
- expect(result.content).toBeDefined()
61
- expect(result.collapsedPreview).toBe('$ ls -la')
62
- })
63
-
64
- test('preserves leading whitespace in stdout (tree output)', () => {
65
- // Simulate tree command output with leading spaces for indentation
66
- const treeOutput = `├── src
67
- │ ├── index.ts
68
- │ └── utils
69
- │ └── helper.ts
70
- └── package.json`
71
-
72
- const { output } = parseTerminalOutput(createJsonOutput(treeOutput))
73
-
74
- expect(output).toBe(treeOutput)
75
- // Verify leading characters are preserved (├ has no leading space, but indented lines do)
76
- expect(output?.startsWith('├')).toBe(true)
77
- expect(output).toContain('│ ├')
78
- expect(output).toContain('│ └')
79
- })
80
-
81
- test('preserves leading spaces in table-like output', () => {
82
- // Simulate output with leading spaces for alignment
83
- const tableOutput = ` Name Size Modified
84
- file1.txt 1.2KB 2024-01-15
85
- file2.txt 3.4MB 2024-01-16`
86
-
87
- const { output } = parseTerminalOutput(createJsonOutput(tableOutput))
88
-
89
- expect(output).toBe(tableOutput)
90
- // Verify leading spaces are preserved
91
- expect(output?.startsWith(' ')).toBe(true)
92
- })
93
-
94
- test('preserves leading spaces in indented code output', () => {
95
- // Simulate indented output like grep with context
96
- const indentedOutput = ` function hello() {
97
- console.log("world")
98
- }`
99
-
100
- const { output } = parseTerminalOutput(createJsonOutput(indentedOutput))
101
-
102
- expect(output).toBe(indentedOutput)
103
- expect(output?.startsWith(' ')).toBe(true)
104
- })
105
-
106
- test('removes trailing whitespace while preserving leading whitespace', () => {
107
- const outputWithTrailing = ' leading preserved\ntrailing removed \n\n'
108
- const expectedOutput = ' leading preserved\ntrailing removed'
109
-
110
- const { output } = parseTerminalOutput(createJsonOutput(outputWithTrailing))
111
-
112
- expect(output).toBe(expectedOutput)
113
- // Leading spaces preserved
114
- expect(output?.startsWith(' ')).toBe(true)
115
- // Trailing whitespace removed
116
- expect(output?.endsWith('removed')).toBe(true)
117
- })
118
-
119
- test('handles raw string output (non-JSON) and preserves leading whitespace', () => {
120
- const rawOutput = ' indented raw output'
121
- const { output } = parseTerminalOutput(rawOutput)
122
-
123
- expect(output).toBe(rawOutput)
124
- expect(output?.startsWith(' ')).toBe(true)
125
- })
126
-
127
- test('handles combined stdout and stderr with leading whitespace', () => {
128
- const stdout = ' stdout with leading space\n'
129
- const stderr = ' stderr with leading space'
130
-
131
- const { output } = parseTerminalOutput(
132
- JSON.stringify([
133
- {
134
- type: 'json',
135
- value: { stdout, stderr, exitCode: 0 },
136
- },
137
- ]),
138
- )
139
-
140
- expect(output).toContain(' stdout with leading space')
141
- expect(output).toContain(' stderr with leading space')
142
- })
143
-
144
- test('handles output that is only whitespace', () => {
145
- const whitespaceOnly = ' '
146
- const { output } = parseTerminalOutput(createJsonOutput(whitespaceOnly))
147
-
148
- // trimEnd() on whitespace-only string returns empty string, which becomes null
149
- expect(output).toBe(null)
150
- })
151
-
152
- test('handles empty output', () => {
153
- const { output } = parseTerminalOutput(createJsonOutput(''))
154
-
155
- expect(output).toBe(null)
156
- })
157
- })
158
-
159
- describe('timeout extraction', () => {
160
- const mockTheme = {} as ChatTheme
161
- const mockOptions = {
162
- availableWidth: 80,
163
- indentationOffset: 0,
164
- labelWidth: 10,
165
- }
166
-
167
- test('passes undefined timeoutSeconds when timeout_seconds not provided', () => {
168
- const toolBlock = createToolBlock('ls -la', createJsonOutput('output'))
169
-
170
- const result = RunTerminalCommandComponent.render(toolBlock, mockTheme, mockOptions)
171
-
172
- expect((result.content as RenderContentElement).props.timeoutSeconds).toBeUndefined()
173
- })
174
-
175
- test('passes timeoutSeconds for positive timeout', () => {
176
- const toolBlock = createToolBlock('npm test', createJsonOutput('tests passed'), 60)
177
-
178
- const result = RunTerminalCommandComponent.render(toolBlock, mockTheme, mockOptions)
179
-
180
- expect((result.content as RenderContentElement).props.timeoutSeconds).toBe(60)
181
- })
182
-
183
- test('passes timeoutSeconds for no timeout (-1)', () => {
184
- const toolBlock = createToolBlock('long-running-task', createJsonOutput('done'), -1)
185
-
186
- const result = RunTerminalCommandComponent.render(toolBlock, mockTheme, mockOptions)
187
-
188
- expect((result.content as RenderContentElement).props.timeoutSeconds).toBe(-1)
189
- })
190
- })
191
-
192
- describe('parseTerminalOutput', () => {
193
- test('handles error messages', () => {
194
- const errorPayload = JSON.stringify([
195
- {
196
- type: 'json',
197
- value: {
198
- command: 'test',
199
- errorMessage: 'Something went wrong',
200
- stdout: '',
201
- stderr: '',
202
- exitCode: 1,
203
- },
204
- },
205
- ])
206
-
207
- const { output, startingCwd } = parseTerminalOutput(errorPayload)
208
-
209
- expect(output).toBe('Error: Something went wrong')
210
- expect(startingCwd).toBeUndefined()
211
- })
212
-
213
- test('extracts startingCwd when present', () => {
214
- const payloadWithCwd = JSON.stringify([
215
- {
216
- type: 'json',
217
- value: {
218
- command: 'pwd',
219
- stdout: '/project\n',
220
- stderr: '',
221
- exitCode: 0,
222
- startingCwd: '/project',
223
- },
224
- },
225
- ])
226
-
227
- const { output, startingCwd } = parseTerminalOutput(payloadWithCwd)
228
-
229
- expect(output).toBe('/project')
230
- expect(startingCwd).toBe('/project')
231
- })
232
- })
233
- })
@@ -1,149 +0,0 @@
1
- import { describe, expect, test } from 'bun:test'
2
- import { createTestRenderer } from '@opentui/core/testing'
3
- import { createRoot, flushSync } from '@opentui/react'
4
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
5
- import React, { useEffect, useState } from 'react'
6
-
7
- import {
8
- ChatRuntimeProvider,
9
- useChatRuntime,
10
- type ChatRuntime,
11
- } from '../chat-runtime-context'
12
- import {
13
- registerActiveRun,
14
- stopActiveRun,
15
- type ActiveRunStopReason,
16
- } from '../../utils/active-run'
17
-
18
- import type { StreamStatus } from '../../hooks/use-message-queue'
19
-
20
- describe('ChatRuntimeProvider navigation', () => {
21
- for (const phase of ['waiting', 'streaming'] satisfies StreamStatus[]) {
22
- test(`preserves ${phase} runtime while visiting chat history`, async () => {
23
- let runtime: ChatRuntime | undefined
24
- let setShowHistory: ((show: boolean) => void) | undefined
25
- let chatUnmounts = 0
26
-
27
- const RuntimeSnapshot = ({ screen }: { screen: 'chat' | 'history' }) => {
28
- runtime = useChatRuntime()
29
- return (
30
- <text>{`${screen}:${runtime.streamStatus}:${runtime.queuedMessages.length}`}</text>
31
- )
32
- }
33
-
34
- // These must remain distinct component types: production routing
35
- // unmounts Chat and mounts ChatHistoryScreen rather than updating props
36
- // on one shared view component.
37
- const ChatView = () => {
38
- useEffect(
39
- () => () => {
40
- chatUnmounts++
41
- },
42
- [],
43
- )
44
- return <RuntimeSnapshot screen="chat" />
45
- }
46
- const HistoryView = () => <RuntimeSnapshot screen="history" />
47
-
48
- const HistoryRouter = () => {
49
- const [showHistory, setHistory] = useState(false)
50
- setShowHistory = setHistory
51
- return showHistory ? <HistoryView /> : <ChatView />
52
- }
53
-
54
- const setup = await createTestRenderer({ width: 80, height: 3 })
55
- const root = createRoot(setup.renderer)
56
- const queryClient = new QueryClient({
57
- defaultOptions: { queries: { retry: false } },
58
- })
59
- const inputRef = { current: null }
60
- flushSync(() => {
61
- root.render(
62
- <QueryClientProvider client={queryClient}>
63
- <ChatRuntimeProvider inputRef={inputRef} continueChat={false}>
64
- <HistoryRouter />
65
- </ChatRuntimeProvider>
66
- </QueryClientProvider>,
67
- )
68
- })
69
- await setup.renderOnce()
70
-
71
- try {
72
- expect(runtime).toBeDefined()
73
- const stopReasons: ActiveRunStopReason[] = []
74
- registerActiveRun('navigation-test', (reason) => {
75
- stopReasons.push(reason)
76
- })
77
-
78
- flushSync(() => {
79
- runtime!.isChainInProgressRef.current = true
80
- runtime!.setStreamStatus(phase)
81
- runtime!.mainAgentTimer.start()
82
- runtime!.addToQueue('keep me queued')
83
- })
84
- await setup.renderOnce()
85
-
86
- const timerStartTime = runtime!.timerStartTime
87
- const sendMessage = runtime!.sendMessage
88
- expect(timerStartTime).not.toBeNull()
89
- expect(setup.captureCharFrame()).toContain(`chat:${phase}:1`)
90
-
91
- flushSync(() => setShowHistory!(true))
92
- await setup.renderOnce()
93
-
94
- expect(setup.captureCharFrame()).toContain(`history:${phase}:1`)
95
- expect(chatUnmounts).toBe(1)
96
- expect(runtime!.timerStartTime).toBe(timerStartTime)
97
- expect(runtime!.sendMessage).toBe(sendMessage)
98
-
99
- flushSync(() => setShowHistory!(false))
100
- await setup.renderOnce()
101
-
102
- expect(setup.captureCharFrame()).toContain(`chat:${phase}:1`)
103
- expect(runtime!.timerStartTime).toBe(timerStartTime)
104
- expect(runtime!.sendMessage).toBe(sendMessage)
105
- let stoppedRun = false
106
- flushSync(() => {
107
- stoppedRun = stopActiveRun('user-interrupt')
108
- })
109
- expect(stoppedRun).toBe(true)
110
- expect(stopReasons).toEqual(['user-interrupt'])
111
- await setup.renderOnce()
112
- expect(runtime!.queuePaused).toBe(true)
113
- expect(runtime!.queuedMessages).toHaveLength(1)
114
-
115
- // A queue add and interrupt can occur before React renders again.
116
- // The synchronous queue ref must still make the interrupt pause it.
117
- flushSync(() => {
118
- runtime!.clearQueue()
119
- runtime!.resumeQueue()
120
- registerActiveRun('same-tick-test', (reason) => {
121
- stopReasons.push(reason)
122
- })
123
- runtime!.addToQueue('queued in the interrupt tick')
124
- stoppedRun = stopActiveRun('user-interrupt')
125
- })
126
- expect(stoppedRun).toBe(true)
127
- await setup.renderOnce()
128
- expect(runtime!.queuePaused).toBe(true)
129
- expect(runtime!.queuedMessages).toHaveLength(1)
130
- expect(stopReasons).toEqual(['user-interrupt', 'user-interrupt'])
131
-
132
- // Context changes still clean a paused queue after the run owner has
133
- // already been released.
134
- flushSync(() => {
135
- stoppedRun = stopActiveRun('new-chat')
136
- })
137
- expect(stoppedRun).toBe(false)
138
- await setup.renderOnce()
139
- expect(runtime!.queuedMessages).toHaveLength(0)
140
- expect(runtime!.queuePaused).toBe(false)
141
- } finally {
142
- stopActiveRun('process-exit')
143
- flushSync(() => root.unmount())
144
- queryClient.clear()
145
- setup.renderer.destroy()
146
- }
147
- })
148
- }
149
- })