Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const SETTINGS_WEB_SEARCH_COPY = {
provider: 'Search source', providerHelp: 'Reuse the current model provider when it supports hosted search, or explicitly use Tavily.', providerModel: 'Current model', providerTavily: 'Tavily',
modelCredential: 'Primary-model native search', modelCredentialHelp: 'At the start of each turn, Maka uses the current connection and exact model to decide whether to inject native web_search into the same model request. It stores no second search key and sends no separate model call from Settings.',
statusAria: 'Web search credential status', lastTest: 'Last tested ', enabledAria: 'Enable web search', key: 'Tavily key',
envKeyHelp: 'Currently using TAVILY_API_KEY / MAKA_TAVILY_API_KEY from the environment. Remove the environment variable and restart to use a saved key.', savedKeyHelp: 'The key is stored only on this machine. Apply at:',
envKeyHelp: 'Currently using TAVILY_API_KEY / MAKA_TAVILY_API_KEY from the environment. Remove the environment variable and restart to use a saved key.', savedKeyHelp: 'The key is stored only on this machine. Apply at: ',
envPlaceholder: 'Provided by environment variable', storedPlaceholder: 'Saved (enter a new key to replace)', keyPlaceholder: 'tvly-xxxxxxxx', keyAria: 'Tavily key',
actions: 'Credential actions', actionsHelp: 'After saving, test with a real request. Clearing credentials also disables web search.', saving: 'Saving…', saveKey: 'Save key', testing: 'Testing…', testKey: 'Test credentials', clearing: 'Clearing…', clearKey: 'Clear key',
testSearch: 'Test search', testSearchHelp: 'Send a real query to confirm the selected web search source is configured and working. Results appear here only and are not written to the task.', queryPlaceholder: 'For example: AI product launches this week',
Expand Down
13 changes: 10 additions & 3 deletions apps/desktop/src/renderer/settings/password-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/

import { useEffect, useRef, useState } from 'react';
import { useEffect, useRef, useState, type ReactNode } from 'react';
import { ICON_SIZE, Check, Copy, Eye, EyeOff } from '@maka/ui/icons';
import {
IconButton,
Expand Down Expand Up @@ -53,7 +53,12 @@ export function PasswordInput(props: {
placeholder?: string;
label: string;
isLabelHidden?: boolean;
description?: string;
// ReactNode, not string: a description may carry an inline link (e.g. the web
// search "申请地址:tavily.com" apply link). Astryx FieldLabel already renders
// a ReactNode description and its click-forwarding skips nested interactive
// content; only the InputGroup/Field prop types under-declare it as `string`,
// which the single cast at the InputGroup call site below papers over.
description?: ReactNode;
status?: InputGroupProps['status'];
isRequired?: boolean;
isOptional?: boolean;
Expand Down Expand Up @@ -112,7 +117,9 @@ export function PasswordInput(props: {
// written on, and the group's `aria-labelledby` is what names it.
<InputGroup
label={props.label}
description={props.description}
// Cast: InputGroup/Field type `description` as `string`, but the
// underlying FieldLabel renders any ReactNode (see the prop's note).
description={props.description as string | undefined}
isLabelHidden={props.isLabelHidden}
isDisabled={props.isDisabled}
isRequired={props.isRequired}
Expand Down
12 changes: 6 additions & 6 deletions apps/desktop/src/renderer/settings/web-search-settings-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -346,13 +346,13 @@ export function WebSearchSettingsPage(props: {
isDisabled={usingEnvKey || credentialActionBusy}
placeholder={usingEnvKey ? copy.envPlaceholder : hasStoredKey ? copy.storedPlaceholder : copy.keyPlaceholder}
label={copy.key}
description={usingEnvKey ? copy.envKeyHelp : copy.savedKeyHelp}
description={usingEnvKey ? copy.envKeyHelp : (
<>
{copy.savedKeyHelp}
<Link href="https://tavily.com" target="_blank" rel="noreferrer noopener">tavily.com</Link>
</>
)}
/>
{!usingEnvKey && (
<small className="settingsQuietStatus">
<Link href="https://tavily.com" target="_blank" rel="noreferrer noopener">tavily.com</Link>
</small>
)}
</SettingsField>

<SettingsActions role="group" aria-label={copy.actions}>
Expand Down
9 changes: 8 additions & 1 deletion apps/desktop/src/renderer/styles/native-cursor.css
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,16 @@

/* 1. Generic interactive roles (Button, menu rows, options, labels, trees…).
* Astryx FieldLabel / TreeListItem set StyleX cursor:pointer on <label> and
* [role=treeitem] — cover them here so the product rule stays one sheet. */
* [role=treeitem] — cover them here so the product rule stays one sheet.
* FieldLabel also renders a bare `<span class="astryx-field-label">` for a
* group label (InputGroup: `isGroupLabel`), which names a group via
* `aria-labelledby` and forwards no click — the `label` selector misses it,
* so it kept StyleX's hand cursor. Match the stable themeProps class to catch
* that span too (real <label> field labels are already covered above). */
:where(
button,
label,
.astryx-field-label,
[role="button"],
[role="menuitem"],
[role="menuitemradio"],
Expand All @@ -68,6 +74,7 @@
:where(
button,
label,
.astryx-field-label,
[role="button"],
[role="menuitem"],
[role="menuitemradio"],
Expand Down