@agent-native/core 0.98.2 → 0.98.3

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 (64) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +10 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/agent/production-agent.ts +2 -2
  5. package/corpus/core/src/client/index.ts +2 -0
  6. package/corpus/core/src/client/settings/DemoModeSection.tsx +6 -6
  7. package/corpus/core/src/client/settings/SettingsPanel.tsx +31 -211
  8. package/corpus/core/src/client/settings/agent-settings-search.ts +219 -0
  9. package/corpus/core/src/client/settings/index.ts +4 -0
  10. package/corpus/core/src/demo/actions/toggle-demo-mode.ts +2 -2
  11. package/corpus/core/src/demo/config.ts +6 -6
  12. package/corpus/core/src/demo/redact.ts +18 -76
  13. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +21 -4
  14. package/corpus/templates/analytics/AGENTS.md +6 -6
  15. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +429 -244
  16. package/corpus/templates/analytics/app/components/layout/command-palette-search.ts +93 -0
  17. package/corpus/templates/analytics/app/hooks/use-replay-storage-status.ts +2 -1
  18. package/corpus/templates/analytics/app/lib/demo-chart-trend.ts +46 -33
  19. package/corpus/templates/analytics/app/pages/Settings.tsx +8 -45
  20. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +205 -70
  21. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +32 -16
  22. package/corpus/templates/analytics/app/pages/settings/settings-search.ts +126 -0
  23. package/corpus/templates/analytics/changelog/2026-07-12-command-menu-loading-placeholders-now-stay-below-available-r.md +6 -0
  24. package/corpus/templates/analytics/changelog/2026-07-12-command-menu-search-now-prioritizes-the-best-match.md +6 -0
  25. package/corpus/templates/analytics/changelog/2026-07-12-demo-charts-preserve-source-movement.md +6 -0
  26. package/corpus/templates/analytics/changelog/2026-07-12-replay-storage-settings-stay-readable-at-narrow-widths.md +6 -0
  27. package/corpus/templates/analytics/changelog/2026-07-12-session-replays-preserve-recorded-styling-and-keep-malformed.md +6 -0
  28. package/dist/agent/production-agent.js +2 -2
  29. package/dist/agent/production-agent.js.map +1 -1
  30. package/dist/client/index.d.ts +1 -1
  31. package/dist/client/index.d.ts.map +1 -1
  32. package/dist/client/index.js +1 -1
  33. package/dist/client/index.js.map +1 -1
  34. package/dist/client/settings/DemoModeSection.d.ts +3 -3
  35. package/dist/client/settings/DemoModeSection.js +4 -4
  36. package/dist/client/settings/DemoModeSection.js.map +1 -1
  37. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  38. package/dist/client/settings/SettingsPanel.js +41 -191
  39. package/dist/client/settings/SettingsPanel.js.map +1 -1
  40. package/dist/client/settings/agent-settings-search.d.ts +16 -0
  41. package/dist/client/settings/agent-settings-search.d.ts.map +1 -0
  42. package/dist/client/settings/agent-settings-search.js +178 -0
  43. package/dist/client/settings/agent-settings-search.js.map +1 -0
  44. package/dist/client/settings/index.d.ts +1 -0
  45. package/dist/client/settings/index.d.ts.map +1 -1
  46. package/dist/client/settings/index.js +1 -0
  47. package/dist/client/settings/index.js.map +1 -1
  48. package/dist/collab/routes.d.ts +2 -2
  49. package/dist/collab/struct-routes.d.ts +1 -1
  50. package/dist/demo/actions/toggle-demo-mode.js +2 -2
  51. package/dist/demo/actions/toggle-demo-mode.js.map +1 -1
  52. package/dist/demo/config.js +6 -6
  53. package/dist/demo/config.js.map +1 -1
  54. package/dist/demo/redact.d.ts +7 -5
  55. package/dist/demo/redact.d.ts.map +1 -1
  56. package/dist/demo/redact.js +19 -54
  57. package/dist/demo/redact.js.map +1 -1
  58. package/dist/notifications/routes.d.ts +1 -1
  59. package/dist/progress/routes.d.ts +1 -1
  60. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  61. package/dist/resources/handlers.d.ts +3 -3
  62. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  63. package/dist/server/transcribe-voice.d.ts +1 -1
  64. package/package.json +2 -2
package/corpus/README.md CHANGED
@@ -27,5 +27,5 @@ rg -n "defineAction|useActionQuery" node_modules/@agent-native/core/corpus
27
27
 
28
28
  ## Generated Counts
29
29
 
30
- - core files: 2234
31
- - template files: 5482
30
+ - core files: 2235
31
+ - template files: 5488
@@ -1,5 +1,15 @@
1
1
  # @agent-native/core
2
2
 
3
+ ## 0.98.3
4
+
5
+ ### Patch Changes
6
+
7
+ - ffad302: Stop heuristically rewriting name-like text in demo mode while continuing to replace email addresses and numbers.
8
+ - ffad302: Expose lightweight settings search metadata for command palettes and other navigation surfaces.
9
+ - Updated dependencies [ffad302]
10
+ - Updated dependencies [ffad302]
11
+ - @agent-native/toolkit@0.4.8
12
+
3
13
  ## 0.98.2
4
14
 
5
15
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.98.2",
3
+ "version": "0.98.3",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -4352,8 +4352,8 @@ export async function runAgentLoop(opts: {
4352
4352
  // content parts; first-party actions opt in via the well-known
4353
4353
  // `_agentImages` result field (stripped from the JSON the model
4354
4354
  // reads, even in demo mode). Demo mode drops the images themselves —
4355
- // text redaction can't scrub pixels, and a screenshot would leak the
4356
- // real contact names/emails/numbers the redaction exists to hide. The images array
4355
+ // text redaction can't scrub pixels, and a screenshot may expose
4356
+ // original visual data. The images array
4357
4357
  // never touches the ledger — only the compact text notes appended
4358
4358
  // below are persisted.
4359
4359
  let imageNotes: string[] = [];
@@ -681,6 +681,7 @@ export {
681
681
  SettingsPanel,
682
682
  SettingsTabsPage,
683
683
  SecretsSection,
684
+ getAgentSettingsSearchTabs,
684
685
  openBuilderConnectPopup,
685
686
  useAgentSettingsTabs,
686
687
  useBuilderConnectFlow,
@@ -690,6 +691,7 @@ export {
690
691
  type BuilderConnectFlowOptions,
691
692
  type BuilderConnectStartOptions,
692
693
  type BuilderStatus,
694
+ type AgentSettingsSearchTab,
693
695
  type OpenBuilderConnectPopupOptions,
694
696
  type SecretsSectionProps,
695
697
  type SettingsPanelProps,
@@ -1,7 +1,7 @@
1
1
  /**
2
- * <DemoModeSection /> — toggle that replaces contact/free-text names, emails,
3
- * and numbers with realistic fake data everywhere (UI + what the agent sees)
4
- * while preserving labels, IDs, and structure so the app keeps working.
2
+ * <DemoModeSection /> — toggle that replaces emails and numbers with realistic
3
+ * fake data everywhere (UI + what the agent sees) while preserving names,
4
+ * free text, labels, IDs, and structure so the app keeps working.
5
5
  *
6
6
  * The toggle is stored in application_state under `demo-mode`
7
7
  * (`{ enabled: boolean }`) and written via `PUT
@@ -64,9 +64,9 @@ export function DemoModeSection() {
64
64
  Enable demo mode
65
65
  </div>
66
66
  <p className="text-[10px] text-muted-foreground mt-0.5">
67
- Replace contact/free-text names, emails, and numbers with realistic
68
- fake data everywhere — in the UI and what the agent sees. Labels, IDs,
69
- and structure are preserved so the app keeps working.
67
+ Replace emails and numbers with realistic fake data everywhere — in
68
+ the UI and what the agent sees. Names, free text, labels, IDs, and
69
+ structure are preserved so the app keeps working.
70
70
  </p>
71
71
  {forced && (
72
72
  <p className="text-[10px] text-muted-foreground mt-0.5">
@@ -50,6 +50,15 @@ import { uploadAvatar, useAvatarUrl } from "../use-avatar.js";
50
50
  import { useDevMode } from "../use-dev-mode.js";
51
51
  import { useSession } from "../use-session.js";
52
52
  import { cn } from "../utils.js";
53
+ import {
54
+ AGENT_SETTINGS_SECTIONS,
55
+ ALL_SETTINGS_SECTIONS,
56
+ CONNECTION_SETTINGS_SECTIONS,
57
+ SETTINGS_SECTION_IDS,
58
+ WORKSPACE_SETTINGS_SECTIONS,
59
+ getAgentSettingsSearchTabs,
60
+ type SettingsSectionId,
61
+ } from "./agent-settings-search.js";
53
62
  import { AgentsSection } from "./AgentsSection.js";
54
63
  import { AutomationsSection } from "./AutomationsSection.js";
55
64
  import { DemoModeSection } from "./DemoModeSection.js";
@@ -60,10 +69,7 @@ import {
60
69
  useSettingsSurface,
61
70
  type SettingsSurface,
62
71
  } from "./SettingsSection.js";
63
- import type {
64
- SettingsSearchEntry,
65
- SettingsTabItem,
66
- } from "./SettingsTabsPage.js";
72
+ import type { SettingsTabItem } from "./SettingsTabsPage.js";
67
73
  import { UsageSection } from "./UsageSection.js";
68
74
  import {
69
75
  type BuilderConnectFlow,
@@ -2299,192 +2305,6 @@ export interface SettingsPanelProps {
2299
2305
  sectionRequestKey?: number;
2300
2306
  }
2301
2307
 
2302
- type SettingsSectionId =
2303
- | "account"
2304
- | "llm"
2305
- | "app-models"
2306
- | "limits"
2307
- | "voice"
2308
- | "demo-mode"
2309
- | "automations"
2310
- | "secrets"
2311
- | "hosting"
2312
- | "database"
2313
- | "uploads"
2314
- | "auth"
2315
- | "email"
2316
- | "browser"
2317
- | "background"
2318
- | "integrations"
2319
- | "usage"
2320
- | "a2a";
2321
-
2322
- const SETTINGS_SECTION_IDS = new Set<SettingsSectionId>([
2323
- "account",
2324
- "llm",
2325
- "app-models",
2326
- "limits",
2327
- "voice",
2328
- "demo-mode",
2329
- "automations",
2330
- "secrets",
2331
- "hosting",
2332
- "database",
2333
- "uploads",
2334
- "auth",
2335
- "email",
2336
- "browser",
2337
- "background",
2338
- "integrations",
2339
- "usage",
2340
- "a2a",
2341
- ]);
2342
-
2343
- const ALL_SETTINGS_SECTIONS: readonly SettingsSectionId[] = [
2344
- "account",
2345
- "llm",
2346
- "app-models",
2347
- "limits",
2348
- "voice",
2349
- "demo-mode",
2350
- "automations",
2351
- "secrets",
2352
- "hosting",
2353
- "database",
2354
- "uploads",
2355
- "auth",
2356
- "email",
2357
- "browser",
2358
- "background",
2359
- "integrations",
2360
- "usage",
2361
- "a2a",
2362
- ];
2363
-
2364
- const AGENT_SETTINGS_SECTIONS: readonly SettingsSectionId[] = [
2365
- "llm",
2366
- "app-models",
2367
- "limits",
2368
- "voice",
2369
- "automations",
2370
- "background",
2371
- "a2a",
2372
- ];
2373
-
2374
- const CONNECTION_SETTINGS_SECTIONS: readonly SettingsSectionId[] = [
2375
- "secrets",
2376
- "integrations",
2377
- "email",
2378
- "browser",
2379
- "usage",
2380
- ];
2381
-
2382
- const WORKSPACE_SETTINGS_SECTIONS: readonly SettingsSectionId[] = [
2383
- "account",
2384
- "demo-mode",
2385
- "hosting",
2386
- "database",
2387
- "uploads",
2388
- "auth",
2389
- ];
2390
-
2391
- // Search metadata for each section so settings search can deep-link straight
2392
- // to a section from any tab. Labels mirror the section headers; keywords add
2393
- // synonyms and provider names the header doesn't spell out.
2394
- const SETTINGS_SECTION_SEARCH_META: Record<
2395
- SettingsSectionId,
2396
- { label: string; keywords: string; description?: string }
2397
- > = {
2398
- account: {
2399
- label: "Account",
2400
- keywords: "profile photo avatar identity signed in email name",
2401
- },
2402
- llm: {
2403
- label: "LLM",
2404
- keywords:
2405
- "model claude gpt openai anthropic gemini api key provider ai engine llm",
2406
- },
2407
- "app-models": {
2408
- label: "App Default Model",
2409
- keywords: "default model provider app template composer",
2410
- },
2411
- limits: {
2412
- label: "Agent Limits",
2413
- keywords: "max iterations budget loop timeout runtime",
2414
- },
2415
- voice: {
2416
- label: "Voice Transcription",
2417
- keywords: "microphone dictation speech to text whisper",
2418
- },
2419
- "demo-mode": {
2420
- label: "Demo mode",
2421
- keywords: "fake data anonymize redact screenshot privacy mask",
2422
- },
2423
- automations: {
2424
- label: "Automations",
2425
- keywords: "triggers scheduled events cron jobs",
2426
- },
2427
- secrets: {
2428
- label: "API Keys & Connections",
2429
- keywords: "secrets credentials tokens api keys environment variables",
2430
- },
2431
- hosting: {
2432
- label: "Hosting",
2433
- keywords: "deploy netlify vercel cloudflare builder nitro",
2434
- },
2435
- database: {
2436
- label: "Database",
2437
- keywords: "postgres sqlite neon supabase turso storage sql pglite",
2438
- },
2439
- uploads: {
2440
- label: "File uploads",
2441
- keywords: "files storage s3 avatars attachments bucket blob",
2442
- },
2443
- auth: {
2444
- label: "Authentication",
2445
- keywords: "login signup oauth google github better auth access sso",
2446
- },
2447
- email: {
2448
- label: "Email",
2449
- keywords: "resend sendgrid smtp transactional notifications reports",
2450
- },
2451
- browser: {
2452
- label: "Browser Automation",
2453
- keywords: "web scraping playwright chrome headless",
2454
- },
2455
- background: {
2456
- label: "Background Agent",
2457
- keywords: "code changes branches builder production async",
2458
- },
2459
- integrations: {
2460
- label: "Integrations",
2461
- keywords: "slack telegram whatsapp discord messaging connect",
2462
- },
2463
- usage: {
2464
- label: "Usage",
2465
- keywords: "tokens cost spend billing consumption",
2466
- },
2467
- a2a: {
2468
- label: "Connected Agents (A2A)",
2469
- keywords: "remote agents protocol a2a connected",
2470
- },
2471
- };
2472
-
2473
- function buildSectionSearchEntries(
2474
- sections: readonly SettingsSectionId[],
2475
- ): SettingsSearchEntry[] {
2476
- return sections.map((section) => {
2477
- const meta = SETTINGS_SECTION_SEARCH_META[section];
2478
- return {
2479
- id: `section:${section}`,
2480
- label: meta.label,
2481
- keywords: meta.keywords,
2482
- description: meta.description,
2483
- hash: section,
2484
- };
2485
- });
2486
- }
2487
-
2488
2308
  function normalizeSettingsSection(
2489
2309
  value?: string | null,
2490
2310
  ): SettingsSectionId | null {
@@ -2970,7 +2790,7 @@ function SettingsPanelContent({
2970
2790
  id={settingsSectionDomId("demo-mode")}
2971
2791
  icon={<IconEyeOff size={14} />}
2972
2792
  title="Demo mode"
2973
- subtitle="Replace contact/free-text names, emails, and numbers with realistic fake data everywhere — in the UI and what the agent sees. Labels, IDs, and structure are preserved so the app keeps working."
2793
+ subtitle="Replace emails and numbers with realistic fake data everywhere — in the UI and what the agent sees. Names, free text, labels, IDs, and structure are preserved so the app keeps working."
2974
2794
  open={openSection === "demo-mode"}
2975
2795
  onToggle={() => toggle("demo-mode")}
2976
2796
  >
@@ -3250,15 +3070,24 @@ export function useAgentSettingsTabs(): SettingsTabItem[] {
3250
3070
  [canToggle, isDevMode, setDevMode],
3251
3071
  );
3252
3072
 
3253
- return useMemo<SettingsTabItem[]>(
3254
- () => [
3073
+ return useMemo<SettingsTabItem[]>(() => {
3074
+ const searchTabs = getAgentSettingsSearchTabs();
3075
+ const searchTab = (
3076
+ id: "agent" | "connections" | "organization" | "workspace",
3077
+ ) => {
3078
+ const tab = searchTabs.find((candidate) => candidate.id === id);
3079
+ if (!tab) throw new Error(`Missing agent settings tab: ${id}`);
3080
+ return tab;
3081
+ };
3082
+ const agent = searchTab("agent");
3083
+ const connections = searchTab("connections");
3084
+ const organization = searchTab("organization");
3085
+ const workspace = searchTab("workspace");
3086
+ return [
3255
3087
  {
3256
- id: "agent",
3257
- label: "Agent",
3088
+ ...agent,
3258
3089
  icon: IconBrain,
3259
3090
  group: "agent",
3260
- keywords: "agent model llm limits voice automations",
3261
- searchEntries: buildSectionSearchEntries(AGENT_SETTINGS_SECTIONS),
3262
3091
  content: (
3263
3092
  <SettingsPanelContent
3264
3093
  {...baseProps}
@@ -3270,12 +3099,9 @@ export function useAgentSettingsTabs(): SettingsTabItem[] {
3270
3099
  ),
3271
3100
  },
3272
3101
  {
3273
- id: "connections",
3274
- label: "Connections",
3102
+ ...connections,
3275
3103
  icon: IconPlugConnected,
3276
3104
  group: "agent",
3277
- keywords: "connections secrets integrations email browser usage",
3278
- searchEntries: buildSectionSearchEntries(CONNECTION_SETTINGS_SECTIONS),
3279
3105
  content: (
3280
3106
  <SettingsPanelContent
3281
3107
  {...baseProps}
@@ -3287,11 +3113,9 @@ export function useAgentSettingsTabs(): SettingsTabItem[] {
3287
3113
  ),
3288
3114
  },
3289
3115
  {
3290
- id: "organization",
3291
- label: "Organization",
3116
+ ...organization,
3292
3117
  icon: IconUsersGroup,
3293
3118
  group: "workspace",
3294
- keywords: "organization org team members invites collaborators",
3295
3119
  content: (
3296
3120
  <div className="mx-auto w-full max-w-2xl">
3297
3121
  <TeamPage showTitle={false} />
@@ -3299,12 +3123,9 @@ export function useAgentSettingsTabs(): SettingsTabItem[] {
3299
3123
  ),
3300
3124
  },
3301
3125
  {
3302
- id: "workspace",
3303
- label: "Workspace",
3126
+ ...workspace,
3304
3127
  icon: IconCloud,
3305
3128
  group: "workspace",
3306
- keywords: "workspace account hosting database uploads auth",
3307
- searchEntries: buildSectionSearchEntries(WORKSPACE_SETTINGS_SECTIONS),
3308
3129
  content: (
3309
3130
  <SettingsPanelContent
3310
3131
  {...baseProps}
@@ -3315,7 +3136,6 @@ export function useAgentSettingsTabs(): SettingsTabItem[] {
3315
3136
  />
3316
3137
  ),
3317
3138
  },
3318
- ],
3319
- [baseProps],
3320
- );
3139
+ ];
3140
+ }, [baseProps]);
3321
3141
  }
@@ -0,0 +1,219 @@
1
+ import type { SettingsSearchEntry } from "./SettingsTabsPage.js";
2
+
3
+ export type SettingsSectionId =
4
+ | "account"
5
+ | "llm"
6
+ | "app-models"
7
+ | "limits"
8
+ | "voice"
9
+ | "demo-mode"
10
+ | "automations"
11
+ | "secrets"
12
+ | "hosting"
13
+ | "database"
14
+ | "uploads"
15
+ | "auth"
16
+ | "email"
17
+ | "browser"
18
+ | "background"
19
+ | "integrations"
20
+ | "usage"
21
+ | "a2a";
22
+
23
+ export const SETTINGS_SECTION_IDS = new Set<SettingsSectionId>([
24
+ "account",
25
+ "llm",
26
+ "app-models",
27
+ "limits",
28
+ "voice",
29
+ "demo-mode",
30
+ "automations",
31
+ "secrets",
32
+ "hosting",
33
+ "database",
34
+ "uploads",
35
+ "auth",
36
+ "email",
37
+ "browser",
38
+ "background",
39
+ "integrations",
40
+ "usage",
41
+ "a2a",
42
+ ]);
43
+
44
+ export const ALL_SETTINGS_SECTIONS: readonly SettingsSectionId[] = [
45
+ "account",
46
+ "llm",
47
+ "app-models",
48
+ "limits",
49
+ "voice",
50
+ "demo-mode",
51
+ "automations",
52
+ "secrets",
53
+ "hosting",
54
+ "database",
55
+ "uploads",
56
+ "auth",
57
+ "email",
58
+ "browser",
59
+ "background",
60
+ "integrations",
61
+ "usage",
62
+ "a2a",
63
+ ];
64
+
65
+ export const AGENT_SETTINGS_SECTIONS: readonly SettingsSectionId[] = [
66
+ "llm",
67
+ "app-models",
68
+ "limits",
69
+ "voice",
70
+ "automations",
71
+ "background",
72
+ "a2a",
73
+ ];
74
+
75
+ export const CONNECTION_SETTINGS_SECTIONS: readonly SettingsSectionId[] = [
76
+ "secrets",
77
+ "integrations",
78
+ "email",
79
+ "browser",
80
+ "usage",
81
+ ];
82
+
83
+ export const WORKSPACE_SETTINGS_SECTIONS: readonly SettingsSectionId[] = [
84
+ "account",
85
+ "demo-mode",
86
+ "hosting",
87
+ "database",
88
+ "uploads",
89
+ "auth",
90
+ ];
91
+
92
+ const SETTINGS_SECTION_SEARCH_META: Record<
93
+ SettingsSectionId,
94
+ { label: string; keywords: string; description?: string }
95
+ > = {
96
+ account: {
97
+ label: "Account",
98
+ keywords: "profile photo avatar identity signed in email name",
99
+ },
100
+ llm: {
101
+ label: "LLM",
102
+ keywords:
103
+ "model claude gpt openai anthropic gemini api key provider ai engine llm",
104
+ },
105
+ "app-models": {
106
+ label: "App Default Model",
107
+ keywords: "default model provider app template composer",
108
+ },
109
+ limits: {
110
+ label: "Agent Limits",
111
+ keywords: "max iterations budget loop timeout runtime",
112
+ },
113
+ voice: {
114
+ label: "Voice Transcription",
115
+ keywords: "microphone dictation speech to text whisper",
116
+ },
117
+ "demo-mode": {
118
+ label: "Demo mode",
119
+ keywords: "fake data anonymize redact screenshot privacy mask",
120
+ },
121
+ automations: {
122
+ label: "Automations",
123
+ keywords: "triggers scheduled events cron jobs",
124
+ },
125
+ secrets: {
126
+ label: "API Keys & Connections",
127
+ keywords: "secrets credentials tokens api keys environment variables",
128
+ },
129
+ hosting: {
130
+ label: "Hosting",
131
+ keywords: "deploy netlify vercel cloudflare builder nitro",
132
+ },
133
+ database: {
134
+ label: "Database",
135
+ keywords: "postgres sqlite neon supabase turso storage sql pglite",
136
+ },
137
+ uploads: {
138
+ label: "File uploads",
139
+ keywords: "files storage s3 avatars attachments bucket blob",
140
+ },
141
+ auth: {
142
+ label: "Authentication",
143
+ keywords: "login signup oauth google github better auth access sso",
144
+ },
145
+ email: {
146
+ label: "Email",
147
+ keywords: "resend sendgrid smtp transactional notifications reports",
148
+ },
149
+ browser: {
150
+ label: "Browser Automation",
151
+ keywords: "web scraping playwright chrome headless",
152
+ },
153
+ background: {
154
+ label: "Background Agent",
155
+ keywords: "code changes branches builder production async",
156
+ },
157
+ integrations: {
158
+ label: "Integrations",
159
+ keywords: "slack telegram whatsapp discord messaging connect",
160
+ },
161
+ usage: {
162
+ label: "Usage",
163
+ keywords: "tokens cost spend billing consumption",
164
+ },
165
+ a2a: {
166
+ label: "Connected Agents (A2A)",
167
+ keywords: "remote agents protocol a2a connected",
168
+ },
169
+ };
170
+
171
+ export function buildSectionSearchEntries(
172
+ sections: readonly SettingsSectionId[],
173
+ ): SettingsSearchEntry[] {
174
+ return sections.map((section) => {
175
+ const meta = SETTINGS_SECTION_SEARCH_META[section];
176
+ return {
177
+ id: `section:${section}`,
178
+ label: meta.label,
179
+ keywords: meta.keywords,
180
+ description: meta.description,
181
+ hash: section,
182
+ };
183
+ });
184
+ }
185
+
186
+ export interface AgentSettingsSearchTab {
187
+ id: string;
188
+ label: string;
189
+ keywords: string;
190
+ searchEntries?: SettingsSearchEntry[];
191
+ }
192
+
193
+ export function getAgentSettingsSearchTabs(): AgentSettingsSearchTab[] {
194
+ return [
195
+ {
196
+ id: "agent",
197
+ label: "Agent",
198
+ keywords: "agent model llm limits voice automations",
199
+ searchEntries: buildSectionSearchEntries(AGENT_SETTINGS_SECTIONS),
200
+ },
201
+ {
202
+ id: "connections",
203
+ label: "Connections",
204
+ keywords: "connections secrets integrations email browser usage",
205
+ searchEntries: buildSectionSearchEntries(CONNECTION_SETTINGS_SECTIONS),
206
+ },
207
+ {
208
+ id: "organization",
209
+ label: "Organization",
210
+ keywords: "organization org team members invites collaborators",
211
+ },
212
+ {
213
+ id: "workspace",
214
+ label: "Workspace",
215
+ keywords: "workspace account hosting database uploads auth",
216
+ searchEntries: buildSectionSearchEntries(WORKSPACE_SETTINGS_SECTIONS),
217
+ },
218
+ ];
219
+ }
@@ -3,6 +3,10 @@ export {
3
3
  useAgentSettingsTabs,
4
4
  type SettingsPanelProps,
5
5
  } from "./SettingsPanel.js";
6
+ export {
7
+ getAgentSettingsSearchTabs,
8
+ type AgentSettingsSearchTab,
9
+ } from "./agent-settings-search.js";
6
10
  export {
7
11
  SettingsTabsPage,
8
12
  type SettingsSearchEntry,
@@ -5,7 +5,7 @@ import { writeAppState } from "../../application-state/script-helpers.js";
5
5
 
6
6
  export default defineAction({
7
7
  description:
8
- "Turn demo mode on or off. When demo mode is on, the app replaces contact/free-text names, email addresses, and numbers with realistic fake data everywhere — in the UI and in what you (the agent) see — while keeping labels, IDs, dates, and structure intact so everything still works. Use when the user asks to 'hide my data', 'turn on demo mode', 'anonymize this for a screen share / recording', or similar. This is the same toggle as the Demo mode switch in settings.",
8
+ "Turn demo mode on or off. When demo mode is on, the app replaces email addresses and numbers with realistic fake data everywhere — in the UI and in what you (the agent) see — while keeping names, free text, labels, IDs, dates, and structure intact so everything still works. Use when the user asks to 'hide my data', 'turn on demo mode', 'anonymize this for a screen share / recording', or similar. This is the same toggle as the Demo mode switch in settings.",
9
9
  schema: z.object({
10
10
  enabled: z
11
11
  .boolean()
@@ -16,7 +16,7 @@ export default defineAction({
16
16
  return {
17
17
  enabled,
18
18
  message: enabled
19
- ? "Demo mode is ON — contact/free-text names, emails, and numbers are now replaced with deterministic fake data everywhere (UI and agent). Labels, IDs, and structure are preserved so everything keeps working."
19
+ ? "Demo mode is ON — emails and numbers are now replaced with deterministic fake data everywhere (UI and agent). Names, free text, labels, IDs, and structure are preserved so everything keeps working."
20
20
  : "Demo mode is OFF — real data is shown again.",
21
21
  };
22
22
  },
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Demo mode gate.
3
3
  *
4
- * Demo mode replaces contact/free-text names, email addresses, and numbers in every action
5
- * result with deterministic fake data — for both the UI and what the agent
6
- * sees while preserving labels, IDs, dates, URLs, and structure so the app
7
- * keeps working. The redaction WALK (see ./redact.ts) is expensive on large
8
- * payloads, so callers MUST gate it behind this function and only walk when it
9
- * returns true.
4
+ * Demo mode replaces email addresses and numbers in every action result with
5
+ * deterministic fake data — for both the UI and what the agent sees — while
6
+ * preserving names, free text, labels, IDs, dates, URLs, and structure so the
7
+ * app keeps working. The redaction WALK (see ./redact.ts) is expensive on
8
+ * large payloads, so callers MUST gate it behind this function and only walk
9
+ * when it returns true.
10
10
  *
11
11
  * This gate itself is intentionally cheap:
12
12
  * - An env-forced deployment (a hosted demo site) short-circuits with zero