@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,127 +0,0 @@
|
|
|
1
|
-
import { mock } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
export interface MockTreeNode {
|
|
4
|
-
text: string
|
|
5
|
-
type?: string
|
|
6
|
-
startPosition?: { row: number; column: number }
|
|
7
|
-
endPosition?: { row: number; column: number }
|
|
8
|
-
children?: MockTreeNode[]
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface MockTree {
|
|
12
|
-
rootNode: MockTreeNode
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface MockCapture {
|
|
16
|
-
name: string
|
|
17
|
-
node: MockTreeNode
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface MockParser {
|
|
21
|
-
parse: (input: string) => MockTree | null
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface MockQuery {
|
|
25
|
-
captures: (node: MockTreeNode) => MockCapture[]
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface CreateMockParserOptions {
|
|
29
|
-
tree?: MockTree | null
|
|
30
|
-
parseImpl?: (input: string) => MockTree | null
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface CreateMockQueryOptions {
|
|
34
|
-
captures?: MockCapture[]
|
|
35
|
-
capturesImpl?: (node: MockTreeNode) => MockCapture[]
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function createMockCapture(name: string, text: string): MockCapture {
|
|
39
|
-
return {
|
|
40
|
-
name,
|
|
41
|
-
node: { text },
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function createMockTreeSitterCaptures(
|
|
46
|
-
items: Array<{ name: string; text: string }>,
|
|
47
|
-
): MockCapture[] {
|
|
48
|
-
return items.map(({ name, text }) => createMockCapture(name, text))
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function createMockTree(rootNodeText: string = 'mock tree'): MockTree {
|
|
52
|
-
return {
|
|
53
|
-
rootNode: { text: rootNodeText },
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function createMockTreeSitterParser(
|
|
58
|
-
options: CreateMockParserOptions = {},
|
|
59
|
-
): MockParser {
|
|
60
|
-
const { tree, parseImpl } = options
|
|
61
|
-
const defaultTree = createMockTree()
|
|
62
|
-
const parseFn = parseImpl ?? (() => tree ?? defaultTree)
|
|
63
|
-
|
|
64
|
-
return {
|
|
65
|
-
parse: mock(parseFn),
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function createMockTreeSitterQuery(
|
|
70
|
-
options: CreateMockQueryOptions = {},
|
|
71
|
-
): MockQuery {
|
|
72
|
-
const { captures = [], capturesImpl } = options
|
|
73
|
-
const capturesFn = capturesImpl ?? (() => captures)
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
captures: mock(capturesFn),
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export interface CreateMockLanguageConfigOptions {
|
|
81
|
-
extensions?: string[]
|
|
82
|
-
wasmFile?: string
|
|
83
|
-
queryText?: string
|
|
84
|
-
parser?: MockParser | null
|
|
85
|
-
query?: MockQuery | null
|
|
86
|
-
captures?: MockCapture[]
|
|
87
|
-
tree?: MockTree | null
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function createMockLanguageConfig(
|
|
91
|
-
options: CreateMockLanguageConfigOptions = {},
|
|
92
|
-
): {
|
|
93
|
-
extensions: string[]
|
|
94
|
-
wasmFile: string
|
|
95
|
-
queryText: string
|
|
96
|
-
parser: MockParser | null
|
|
97
|
-
query: MockQuery | null
|
|
98
|
-
} {
|
|
99
|
-
const {
|
|
100
|
-
extensions = ['.ts'],
|
|
101
|
-
wasmFile = 'tree-sitter-typescript.wasm',
|
|
102
|
-
queryText = 'mock query',
|
|
103
|
-
parser,
|
|
104
|
-
query,
|
|
105
|
-
captures,
|
|
106
|
-
tree,
|
|
107
|
-
} = options
|
|
108
|
-
|
|
109
|
-
const finalQuery =
|
|
110
|
-
query ??
|
|
111
|
-
(captures
|
|
112
|
-
? createMockTreeSitterQuery({ captures })
|
|
113
|
-
: createMockTreeSitterQuery())
|
|
114
|
-
const finalParser =
|
|
115
|
-
parser ??
|
|
116
|
-
(tree !== undefined
|
|
117
|
-
? createMockTreeSitterParser({ tree })
|
|
118
|
-
: createMockTreeSitterParser())
|
|
119
|
-
|
|
120
|
-
return {
|
|
121
|
-
extensions,
|
|
122
|
-
wasmFile,
|
|
123
|
-
queryText,
|
|
124
|
-
parser: finalParser,
|
|
125
|
-
query: finalQuery,
|
|
126
|
-
}
|
|
127
|
-
}
|
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test setup utilities for common patterns.
|
|
3
|
-
*
|
|
4
|
-
* Provides helper functions for setting up and tearing down test fixtures
|
|
5
|
-
* in a consistent way across the codebase.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```typescript
|
|
9
|
-
* import { createTestSetup, TestSetupResult } from '@anvil/common/testing/setup'
|
|
10
|
-
*
|
|
11
|
-
* describe('my test', () => {
|
|
12
|
-
* const setup = createTestSetup()
|
|
13
|
-
*
|
|
14
|
-
* beforeEach(() => setup.beforeEach())
|
|
15
|
-
* afterEach(() => setup.afterEach())
|
|
16
|
-
* })
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import { setupAnalyticsMocks } from './mocks/analytics'
|
|
21
|
-
import { setupCryptoMocks } from './mocks/crypto'
|
|
22
|
-
import { setupDbSpies } from './mocks/database'
|
|
23
|
-
import { createMockLogger } from './mocks/logger'
|
|
24
|
-
import { resetToolCallIdCounter } from './mocks/stream'
|
|
25
|
-
|
|
26
|
-
import type {
|
|
27
|
-
AnalyticsSpies,
|
|
28
|
-
TrackEventFn,
|
|
29
|
-
FlushAnalyticsFn,
|
|
30
|
-
} from './mocks/analytics'
|
|
31
|
-
import type { CryptoMockSpies } from './mocks/crypto'
|
|
32
|
-
import type { DbSpies } from './mocks/database'
|
|
33
|
-
import type { MockLogger } from './mocks/logger'
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Options for creating a test setup.
|
|
37
|
-
*/
|
|
38
|
-
export interface CreateTestSetupOptions {
|
|
39
|
-
/**
|
|
40
|
-
* Whether to set up analytics mocks.
|
|
41
|
-
* @default true
|
|
42
|
-
*/
|
|
43
|
-
analytics?: boolean
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Whether to set up crypto mocks.
|
|
47
|
-
* @default true
|
|
48
|
-
*/
|
|
49
|
-
crypto?: boolean
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Whether to set up database mocks.
|
|
53
|
-
* Requires passing the db module.
|
|
54
|
-
* @default false
|
|
55
|
-
*/
|
|
56
|
-
database?: boolean
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* The database module to mock (required if database is true).
|
|
60
|
-
* Must have insert and update methods that are functions.
|
|
61
|
-
*/
|
|
62
|
-
dbModule?: {
|
|
63
|
-
insert: (...args: unknown[]) => unknown
|
|
64
|
-
update: (...args: unknown[]) => unknown
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* The analytics module to mock (required if analytics is true).
|
|
69
|
-
*/
|
|
70
|
-
analyticsModule?: {
|
|
71
|
-
trackEvent: TrackEventFn
|
|
72
|
-
flushAnalytics: FlushAnalyticsFn
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Prefix for crypto mock UUIDs.
|
|
77
|
-
* @default 'test'
|
|
78
|
-
*/
|
|
79
|
-
cryptoPrefix?: string
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Result of creating a test setup.
|
|
84
|
-
*/
|
|
85
|
-
export interface TestSetupResult {
|
|
86
|
-
/** The mock logger instance */
|
|
87
|
-
logger: MockLogger
|
|
88
|
-
|
|
89
|
-
/** Analytics spies (if enabled) */
|
|
90
|
-
analyticsSpy?: AnalyticsSpies
|
|
91
|
-
|
|
92
|
-
/** Crypto spies (if enabled) */
|
|
93
|
-
cryptoSpy?: CryptoMockSpies
|
|
94
|
-
|
|
95
|
-
/** Database spies (if enabled) */
|
|
96
|
-
dbSpy?: DbSpies
|
|
97
|
-
|
|
98
|
-
/** Call this in beforeEach */
|
|
99
|
-
beforeEach: () => void
|
|
100
|
-
|
|
101
|
-
/** Call this in afterEach */
|
|
102
|
-
afterEach: () => void
|
|
103
|
-
|
|
104
|
-
/** Restore all mocks */
|
|
105
|
-
restore: () => void
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Creates a test setup with common mocks pre-configured.
|
|
110
|
-
*
|
|
111
|
-
* @param options - Configuration options
|
|
112
|
-
* @returns A test setup result with mocks and lifecycle methods
|
|
113
|
-
*
|
|
114
|
-
* @example
|
|
115
|
-
* ```typescript
|
|
116
|
-
* import * as analytics from '@anvil/common/analytics'
|
|
117
|
-
* const db = createMockDbOperations()
|
|
118
|
-
*
|
|
119
|
-
* describe('my test', () => {
|
|
120
|
-
* const setup = createTestSetup({
|
|
121
|
-
* analytics: true,
|
|
122
|
-
* analyticsModule: analytics,
|
|
123
|
-
* database: true,
|
|
124
|
-
* dbModule: db,
|
|
125
|
-
* })
|
|
126
|
-
*
|
|
127
|
-
* beforeEach(() => setup.beforeEach())
|
|
128
|
-
* afterEach(() => setup.afterEach())
|
|
129
|
-
*
|
|
130
|
-
* it('does something', () => {
|
|
131
|
-
* expect(setup.analyticsSpy.trackEvent).toHaveBeenCalled()
|
|
132
|
-
* })
|
|
133
|
-
* })
|
|
134
|
-
* ```
|
|
135
|
-
*/
|
|
136
|
-
export function createTestSetup(
|
|
137
|
-
options: CreateTestSetupOptions = {},
|
|
138
|
-
): TestSetupResult {
|
|
139
|
-
const {
|
|
140
|
-
analytics = true,
|
|
141
|
-
crypto = true,
|
|
142
|
-
database = false,
|
|
143
|
-
dbModule,
|
|
144
|
-
analyticsModule,
|
|
145
|
-
cryptoPrefix = 'test',
|
|
146
|
-
} = options
|
|
147
|
-
|
|
148
|
-
const logger = createMockLogger()
|
|
149
|
-
let analyticsSpy: AnalyticsSpies | undefined
|
|
150
|
-
let cryptoSpy: CryptoMockSpies | undefined
|
|
151
|
-
let dbSpy: DbSpies | undefined
|
|
152
|
-
|
|
153
|
-
const beforeEach = (): void => {
|
|
154
|
-
// Reset tool call ID counter for deterministic tests
|
|
155
|
-
resetToolCallIdCounter()
|
|
156
|
-
|
|
157
|
-
// Set up analytics mocks
|
|
158
|
-
if (analytics && analyticsModule) {
|
|
159
|
-
analyticsSpy = setupAnalyticsMocks(analyticsModule)
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Set up crypto mocks
|
|
163
|
-
if (crypto) {
|
|
164
|
-
cryptoSpy = setupCryptoMocks({ prefix: cryptoPrefix, sequential: true })
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Set up database mocks
|
|
168
|
-
if (database && dbModule) {
|
|
169
|
-
dbSpy = setupDbSpies(dbModule)
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const afterEach = (): void => {
|
|
174
|
-
// Restore all mocks
|
|
175
|
-
analyticsSpy?.restore()
|
|
176
|
-
cryptoSpy?.restore()
|
|
177
|
-
dbSpy?.restore()
|
|
178
|
-
|
|
179
|
-
// Reset the spies
|
|
180
|
-
analyticsSpy = undefined
|
|
181
|
-
cryptoSpy = undefined
|
|
182
|
-
dbSpy = undefined
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const restore = afterEach
|
|
186
|
-
|
|
187
|
-
return {
|
|
188
|
-
logger,
|
|
189
|
-
get analyticsSpy() {
|
|
190
|
-
return analyticsSpy
|
|
191
|
-
},
|
|
192
|
-
get cryptoSpy() {
|
|
193
|
-
return cryptoSpy
|
|
194
|
-
},
|
|
195
|
-
get dbSpy() {
|
|
196
|
-
return dbSpy
|
|
197
|
-
},
|
|
198
|
-
beforeEach,
|
|
199
|
-
afterEach,
|
|
200
|
-
restore,
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* A simple sleep function for async tests.
|
|
206
|
-
*
|
|
207
|
-
* @param ms - Milliseconds to sleep
|
|
208
|
-
* @returns A promise that resolves after the specified time
|
|
209
|
-
*
|
|
210
|
-
* @example
|
|
211
|
-
* ```typescript
|
|
212
|
-
* await sleep(100) // Wait 100ms
|
|
213
|
-
* ```
|
|
214
|
-
*/
|
|
215
|
-
export function sleep(ms: number): Promise<void> {
|
|
216
|
-
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Waits for a condition to be true, polling at the specified interval.
|
|
221
|
-
*
|
|
222
|
-
* @param condition - Function that returns true when the condition is met
|
|
223
|
-
* @param timeout - Maximum time to wait in ms
|
|
224
|
-
* @param interval - Polling interval in ms
|
|
225
|
-
* @returns A promise that resolves when the condition is met
|
|
226
|
-
* @throws Error if the timeout is reached
|
|
227
|
-
*
|
|
228
|
-
* @example
|
|
229
|
-
* ```typescript
|
|
230
|
-
* await waitFor(() => document.querySelector('.loaded') !== null)
|
|
231
|
-
* ```
|
|
232
|
-
*/
|
|
233
|
-
export async function waitFor(
|
|
234
|
-
condition: () => boolean | Promise<boolean>,
|
|
235
|
-
timeout: number = 5000,
|
|
236
|
-
interval: number = 50,
|
|
237
|
-
): Promise<void> {
|
|
238
|
-
const start = Date.now()
|
|
239
|
-
|
|
240
|
-
while (Date.now() - start < timeout) {
|
|
241
|
-
const result = await condition()
|
|
242
|
-
if (result) {
|
|
243
|
-
return
|
|
244
|
-
}
|
|
245
|
-
await sleep(interval)
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
throw new Error(`waitFor timed out after ${timeout}ms`)
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Wraps a function to capture its call arguments.
|
|
253
|
-
* Useful for verifying function calls in tests.
|
|
254
|
-
*
|
|
255
|
-
* @param fn - The function to wrap
|
|
256
|
-
* @returns An object with the wrapped function and captured calls
|
|
257
|
-
*
|
|
258
|
-
* @example
|
|
259
|
-
* ```typescript
|
|
260
|
-
* const { fn, calls } = captureCallArgs((a: number, b: string) => a + b.length)
|
|
261
|
-
*
|
|
262
|
-
* fn(1, 'hello')
|
|
263
|
-
* fn(2, 'world')
|
|
264
|
-
*
|
|
265
|
-
* expect(calls).toEqual([
|
|
266
|
-
* [1, 'hello'],
|
|
267
|
-
* [2, 'world'],
|
|
268
|
-
* ])
|
|
269
|
-
* ```
|
|
270
|
-
*/
|
|
271
|
-
export function captureCallArgs<T extends unknown[], R>(
|
|
272
|
-
fn: (...args: T) => R,
|
|
273
|
-
): { fn: (...args: T) => R; calls: T[] } {
|
|
274
|
-
const calls: T[] = []
|
|
275
|
-
|
|
276
|
-
const wrappedFn = (...args: T): R => {
|
|
277
|
-
calls.push(args)
|
|
278
|
-
return fn(...args)
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
return { fn: wrappedFn, calls }
|
|
282
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
import z from 'zod/v4'
|
|
3
|
-
|
|
4
|
-
import { compileToolDefinitions } from '../compile-tool-definitions'
|
|
5
|
-
|
|
6
|
-
// These tests feed synthetic schemas so they exercise the compile logic
|
|
7
|
-
// directly and stay stable as real tools are added, removed, or reshaped.
|
|
8
|
-
describe('compileToolDefinitions', () => {
|
|
9
|
-
test('emits gravity index action enum values', () => {
|
|
10
|
-
const definitions = compileToolDefinitions()
|
|
11
|
-
|
|
12
|
-
expect(definitions).toContain('export interface GravityIndexParams {')
|
|
13
|
-
expect(definitions).not.toContain('export type GravityIndexParams =')
|
|
14
|
-
expect(definitions).toContain(
|
|
15
|
-
'"action": "search" | "browse" | "list_categories" | "get_service" | "report_integration"',
|
|
16
|
-
)
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
test('keeps object tool schemas as interfaces', () => {
|
|
20
|
-
const objectSchema = z.object({ query: z.string() })
|
|
21
|
-
const definitions = compileToolDefinitions([
|
|
22
|
-
{ name: 'web_search', inputSchema: objectSchema },
|
|
23
|
-
])
|
|
24
|
-
|
|
25
|
-
expect(definitions).toContain('export interface WebSearchParams {')
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
test('compiles every published tool by default', () => {
|
|
29
|
-
const definitions = compileToolDefinitions()
|
|
30
|
-
|
|
31
|
-
expect(definitions).toContain('export type ToolName =')
|
|
32
|
-
expect(definitions).toContain('export interface ToolParamsMap {')
|
|
33
|
-
})
|
|
34
|
-
})
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
import z from 'zod/v4'
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
coerceToArray,
|
|
6
|
-
coerceToObject,
|
|
7
|
-
normalizeReplacementAliases,
|
|
8
|
-
} from '../utils'
|
|
9
|
-
|
|
10
|
-
describe('coerceToArray', () => {
|
|
11
|
-
it('passes through arrays unchanged', () => {
|
|
12
|
-
expect(coerceToArray(['a', 'b'])).toEqual(['a', 'b'])
|
|
13
|
-
expect(coerceToArray([{ old: 'x', new: 'y' }])).toEqual([
|
|
14
|
-
{ old: 'x', new: 'y' },
|
|
15
|
-
])
|
|
16
|
-
expect(coerceToArray([])).toEqual([])
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
it('wraps a single string in an array', () => {
|
|
20
|
-
expect(coerceToArray('file.ts')).toEqual(['file.ts'])
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('wraps a single object in an array', () => {
|
|
24
|
-
expect(coerceToArray({ old: 'x', new: 'y' })).toEqual([
|
|
25
|
-
{ old: 'x', new: 'y' },
|
|
26
|
-
])
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
it('wraps a single number in an array', () => {
|
|
30
|
-
expect(coerceToArray(42)).toEqual([42])
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('parses a stringified JSON array', () => {
|
|
34
|
-
expect(coerceToArray('["file1.ts", "file2.ts"]')).toEqual([
|
|
35
|
-
'file1.ts',
|
|
36
|
-
'file2.ts',
|
|
37
|
-
])
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it('wraps a non-JSON string (does not parse as array)', () => {
|
|
41
|
-
expect(coerceToArray('not-json')).toEqual(['not-json'])
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('wraps a stringified JSON object (not an array) in an array', () => {
|
|
45
|
-
expect(coerceToArray('{"key": "value"}')).toEqual(['{"key": "value"}'])
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('passes through null', () => {
|
|
49
|
-
expect(coerceToArray(null)).toBeNull()
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it('passes through undefined', () => {
|
|
53
|
-
expect(coerceToArray(undefined)).toBeUndefined()
|
|
54
|
-
})
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
describe('coerceToObject', () => {
|
|
58
|
-
it('passes through objects unchanged', () => {
|
|
59
|
-
expect(coerceToObject({ key: 'value' })).toEqual({ key: 'value' })
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
it('parses a stringified JSON object', () => {
|
|
63
|
-
expect(coerceToObject('{"key": "value"}')).toEqual({ key: 'value' })
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('leaves non-JSON strings untouched', () => {
|
|
67
|
-
expect(coerceToObject('not-json')).toBe('not-json')
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
it('passes through arrays and primitives so validation can reject them', () => {
|
|
71
|
-
expect(coerceToObject(['a'])).toEqual(['a'])
|
|
72
|
-
expect(coerceToObject(1)).toBe(1)
|
|
73
|
-
})
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
describe('coerceToArray with Zod schemas', () => {
|
|
77
|
-
it('coerces a single string into an array for z.array(z.string())', () => {
|
|
78
|
-
const schema = z.object({
|
|
79
|
-
paths: z.preprocess(coerceToArray, z.array(z.string())),
|
|
80
|
-
})
|
|
81
|
-
const result = schema.safeParse({ paths: 'file.ts' })
|
|
82
|
-
expect(result.success).toBe(true)
|
|
83
|
-
if (result.success) {
|
|
84
|
-
expect(result.data.paths).toEqual(['file.ts'])
|
|
85
|
-
}
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it('coerces a single object into an array for z.array(z.object(...))', () => {
|
|
89
|
-
const schema = z.object({
|
|
90
|
-
replacements: z.preprocess(
|
|
91
|
-
coerceToArray,
|
|
92
|
-
z.array(z.object({ old: z.string(), new: z.string() })),
|
|
93
|
-
),
|
|
94
|
-
})
|
|
95
|
-
const result = schema.safeParse({ replacements: { old: 'x', new: 'y' } })
|
|
96
|
-
expect(result.success).toBe(true)
|
|
97
|
-
if (result.success) {
|
|
98
|
-
expect(result.data.replacements).toEqual([{ old: 'x', new: 'y' }])
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
it('still validates correctly when already an array', () => {
|
|
103
|
-
const schema = z.object({
|
|
104
|
-
paths: z.preprocess(coerceToArray, z.array(z.string())),
|
|
105
|
-
})
|
|
106
|
-
const result = schema.safeParse({ paths: ['a.ts', 'b.ts'] })
|
|
107
|
-
expect(result.success).toBe(true)
|
|
108
|
-
if (result.success) {
|
|
109
|
-
expect(result.data.paths).toEqual(['a.ts', 'b.ts'])
|
|
110
|
-
}
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
it('still rejects invalid inner types after coercion', () => {
|
|
114
|
-
const schema = z.object({
|
|
115
|
-
paths: z.preprocess(coerceToArray, z.array(z.string())),
|
|
116
|
-
})
|
|
117
|
-
const result = schema.safeParse({ paths: 123 })
|
|
118
|
-
expect(result.success).toBe(false)
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
it('works with optional arrays', () => {
|
|
122
|
-
const schema = z.object({
|
|
123
|
-
paths: z.preprocess(coerceToArray, z.array(z.string())).optional(),
|
|
124
|
-
})
|
|
125
|
-
const withValue = schema.safeParse({ paths: 'file.ts' })
|
|
126
|
-
expect(withValue.success).toBe(true)
|
|
127
|
-
if (withValue.success) {
|
|
128
|
-
expect(withValue.data.paths).toEqual(['file.ts'])
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const withoutValue = schema.safeParse({})
|
|
132
|
-
expect(withoutValue.success).toBe(true)
|
|
133
|
-
if (withoutValue.success) {
|
|
134
|
-
expect(withoutValue.data.paths).toBeUndefined()
|
|
135
|
-
}
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
it('produces identical JSON schema with or without preprocess', () => {
|
|
139
|
-
const plain = z.object({ paths: z.array(z.string()) })
|
|
140
|
-
const coerced = z.object({
|
|
141
|
-
paths: z.preprocess(coerceToArray, z.array(z.string())),
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
const plainSchema = z.toJSONSchema(plain, { io: 'input' })
|
|
145
|
-
const coercedSchema = z.toJSONSchema(coerced, { io: 'input' })
|
|
146
|
-
expect(coercedSchema).toEqual(plainSchema)
|
|
147
|
-
})
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
describe('coerceToObject with Zod schemas', () => {
|
|
151
|
-
it('produces identical JSON schema with or without preprocess', () => {
|
|
152
|
-
const plain = z.object({
|
|
153
|
-
params: z.record(z.string(), z.any()).optional(),
|
|
154
|
-
})
|
|
155
|
-
const coerced = z.object({
|
|
156
|
-
params: z
|
|
157
|
-
.preprocess(coerceToObject, z.record(z.string(), z.any()))
|
|
158
|
-
.optional(),
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
const plainSchema = z.toJSONSchema(plain, { io: 'input' })
|
|
162
|
-
const coercedSchema = z.toJSONSchema(coerced, { io: 'input' })
|
|
163
|
-
expect(coercedSchema).toEqual(plainSchema)
|
|
164
|
-
})
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
describe('normalizeReplacementAliases', () => {
|
|
168
|
-
it('maps old_str and new_str onto the documented replacement keys', () => {
|
|
169
|
-
expect(
|
|
170
|
-
normalizeReplacementAliases({
|
|
171
|
-
old_str: 'before',
|
|
172
|
-
new_str: 'after',
|
|
173
|
-
allowMultiple: true,
|
|
174
|
-
}),
|
|
175
|
-
).toEqual({
|
|
176
|
-
old_str: 'before',
|
|
177
|
-
new_str: 'after',
|
|
178
|
-
oldString: 'before',
|
|
179
|
-
newString: 'after',
|
|
180
|
-
allowMultiple: true,
|
|
181
|
-
})
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
it('maps old_string and new_string onto the documented replacement keys', () => {
|
|
185
|
-
expect(
|
|
186
|
-
normalizeReplacementAliases({
|
|
187
|
-
old_string: 'before',
|
|
188
|
-
new_string: 'after',
|
|
189
|
-
}),
|
|
190
|
-
).toEqual({
|
|
191
|
-
old_string: 'before',
|
|
192
|
-
new_string: 'after',
|
|
193
|
-
oldString: 'before',
|
|
194
|
-
newString: 'after',
|
|
195
|
-
})
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
it('does not overwrite documented replacement keys', () => {
|
|
199
|
-
expect(
|
|
200
|
-
normalizeReplacementAliases({
|
|
201
|
-
oldString: 'before',
|
|
202
|
-
newString: 'after',
|
|
203
|
-
old_str: 'ignored',
|
|
204
|
-
new_str: 'ignored',
|
|
205
|
-
}),
|
|
206
|
-
).toEqual({
|
|
207
|
-
oldString: 'before',
|
|
208
|
-
newString: 'after',
|
|
209
|
-
old_str: 'ignored',
|
|
210
|
-
new_str: 'ignored',
|
|
211
|
-
})
|
|
212
|
-
})
|
|
213
|
-
})
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { readDocsParams } from '../tool/read-docs'
|
|
4
|
-
|
|
5
|
-
describe('read_docs parameters', () => {
|
|
6
|
-
test('trims text inputs and defaults max_tokens', () => {
|
|
7
|
-
const result = readDocsParams.inputSchema.parse({
|
|
8
|
-
libraryTitle: ' React ',
|
|
9
|
-
topic: ' hooks ',
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
expect(result).toEqual({
|
|
13
|
-
libraryTitle: 'React',
|
|
14
|
-
topic: 'hooks',
|
|
15
|
-
max_tokens: 10_000,
|
|
16
|
-
})
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
test('rejects empty text and invalid token counts', () => {
|
|
20
|
-
expect(
|
|
21
|
-
readDocsParams.inputSchema.safeParse({
|
|
22
|
-
libraryTitle: ' ',
|
|
23
|
-
topic: 'hooks',
|
|
24
|
-
}).success,
|
|
25
|
-
).toBe(false)
|
|
26
|
-
expect(
|
|
27
|
-
readDocsParams.inputSchema.safeParse({
|
|
28
|
-
libraryTitle: 'React',
|
|
29
|
-
topic: ' ',
|
|
30
|
-
}).success,
|
|
31
|
-
).toBe(false)
|
|
32
|
-
expect(
|
|
33
|
-
readDocsParams.inputSchema.safeParse({
|
|
34
|
-
libraryTitle: 'React',
|
|
35
|
-
topic: 'hooks',
|
|
36
|
-
max_tokens: -1,
|
|
37
|
-
}).success,
|
|
38
|
-
).toBe(false)
|
|
39
|
-
expect(
|
|
40
|
-
readDocsParams.inputSchema.safeParse({
|
|
41
|
-
libraryTitle: 'React',
|
|
42
|
-
topic: 'hooks',
|
|
43
|
-
max_tokens: 1.5,
|
|
44
|
-
}).success,
|
|
45
|
-
).toBe(false)
|
|
46
|
-
})
|
|
47
|
-
})
|