@agent-native/core 0.168.9 → 0.168.11

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 (48) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/clips/changelog/2026-08-19-desktop-settings-are-tighter-with-a-new-advanced-tab.md +6 -0
  3. package/corpus/templates/clips/desktop/README.md +79 -1
  4. package/corpus/templates/clips/desktop/components.json +20 -0
  5. package/corpus/templates/clips/desktop/package.json +10 -1
  6. package/corpus/templates/clips/desktop/src/app.tsx +1812 -1994
  7. package/corpus/templates/clips/desktop/src/components/ReadinessPanel.tsx +23 -65
  8. package/corpus/templates/clips/desktop/src/components/settings/settings-ui.tsx +399 -0
  9. package/corpus/templates/clips/desktop/src/components/ui/alert-dialog.tsx +166 -0
  10. package/corpus/templates/clips/desktop/src/components/ui/button.tsx +57 -0
  11. package/corpus/templates/clips/desktop/src/components/ui/empty.tsx +104 -0
  12. package/corpus/templates/clips/desktop/src/components/ui/input.tsx +22 -0
  13. package/corpus/templates/clips/desktop/src/components/ui/popover.tsx +38 -0
  14. package/corpus/templates/clips/desktop/src/components/ui/select.tsx +164 -0
  15. package/corpus/templates/clips/desktop/src/components/ui/skeleton.tsx +15 -0
  16. package/corpus/templates/clips/desktop/src/components/ui/spinner.tsx +17 -0
  17. package/corpus/templates/clips/desktop/src/components/ui/switch.tsx +27 -0
  18. package/corpus/templates/clips/desktop/src/components/ui/textarea.tsx +22 -0
  19. package/corpus/templates/clips/desktop/src/dev/browser-preview.ts +65 -0
  20. package/corpus/templates/clips/desktop/src/hooks/useSystemAccessRows.ts +128 -0
  21. package/corpus/templates/clips/desktop/src/hooks/useWhisperSettings.ts +0 -2
  22. package/corpus/templates/clips/desktop/src/lib/permission-status.ts +84 -0
  23. package/corpus/templates/clips/desktop/src/lib/rewind-status.ts +6 -5
  24. package/corpus/templates/clips/desktop/src/lib/settings-navigation.ts +18 -5
  25. package/corpus/templates/clips/desktop/src/lib/utils.ts +6 -0
  26. package/corpus/templates/clips/desktop/src/main.tsx +31 -4
  27. package/corpus/templates/clips/desktop/src/overlays/finalizing.tsx +2 -2
  28. package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +2 -2
  29. package/corpus/templates/clips/desktop/src/styles.css +75 -1427
  30. package/corpus/templates/clips/desktop/src/tailwind.css +282 -0
  31. package/corpus/templates/clips/desktop/tsconfig.json +4 -1
  32. package/corpus/templates/clips/desktop/vite.config.ts +7 -1
  33. package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +1 -0
  34. package/corpus/templates/content/app/global.css +5 -0
  35. package/corpus/templates/content/docs/solutions/2026-08-20-code-block-slash-production-regression-shape.md +492 -0
  36. package/corpus/templates/content/docs/solutions/2026-08-20-code-block-surface-background-shape.md +273 -0
  37. package/dist/deploy/build.js +1 -1
  38. package/dist/observability/routes.d.ts +3 -3
  39. package/dist/progress/routes.d.ts +1 -1
  40. package/dist/secrets/routes.d.ts +6 -6
  41. package/dist/server/action-routes.js +3 -2
  42. package/dist/server/realtime-token.d.ts +1 -1
  43. package/dist/server/request-origin.d.ts +6 -0
  44. package/dist/server/request-origin.js +12 -0
  45. package/dist/server/transcribe-voice.d.ts +1 -1
  46. package/dist/shared/mcp-embed-headers.d.ts +1 -1
  47. package/dist/shared/mcp-embed-headers.js +10 -3
  48. package/package.json +1 -1
@@ -0,0 +1,273 @@
1
+ # Ordinary Code Block surface contrast
2
+
3
+ ## Decision
4
+
5
+ Give ordinary native Code Blocks a quiet semantic surface that is visibly
6
+ distinct from the Page canvas in both light and dark themes. Reuse Content's
7
+ existing `--muted` theme token and restore the existing six-pixel radius and
8
+ block spacing directly on `pre.notion-code-block`.
9
+
10
+ This is a separate local refinement from the code-block insertion regression.
11
+ It must not delay, rewrite, or expand that repair, which remains committed at
12
+ `fbe8c9c9060944e3514fd1f2b1a43edc88115199` and land-ready.
13
+
14
+ ## Current truth
15
+
16
+ Direct source evidence:
17
+
18
+ - The Page canvas uses `--background`: white in light mode and 13% lightness in
19
+ dark mode.
20
+ - Content already defines `--muted`: 96% lightness in light mode and 16% in
21
+ dark mode.
22
+ - `.notion-code-block-wrapper` uses `background: hsl(var(--muted))`, a six-pixel
23
+ radius, and `0.6em` vertical margins.
24
+ - Ordinary Code Blocks now use Tiptap's native DOM renderer and carry the class
25
+ `notion-code-block`; they do not render the old wrapper.
26
+ - The shared `pre` rule explicitly gives `.notion-code-block` a transparent
27
+ background, zero radius, and zero margin. It therefore visually collapses
28
+ into the Page canvas.
29
+
30
+ Inference: the missing contrast is a styling seam left behind when ordinary
31
+ Code Blocks moved from the former wrapper/node view to Tiptap's native renderer.
32
+ No new Code Block product contract or color system is required.
33
+
34
+ ## Scope
35
+
36
+ Owned outcome: an ordinary native Code Block reads as a contained code surface
37
+ against the surrounding Page in light and dark themes while preserving current
38
+ source editing, syntax highlighting, selection, keyboard behavior, and
39
+ persistence.
40
+
41
+ Explicit exclusions:
42
+
43
+ - language controls, headers, tabs, execution, output, or other Code Block UX;
44
+ - Mermaid or registry-backed Code blocks;
45
+ - slash-command catalog or insertion behavior;
46
+ - syntax-highlight token redesign;
47
+ - Page, card, popover, sidebar, or global theme palette changes;
48
+ - image insertion or media styling.
49
+
50
+ ## Smallest compatible repair
51
+
52
+ Keep the shared typography and overflow rule. Add a native-block-specific rule
53
+ after it that applies:
54
+
55
+ - `background: hsl(var(--muted))`;
56
+ - `border-radius: 6px`;
57
+ - `margin: 0.6em 0`.
58
+
59
+ Do not add raw light/dark colors or a new token. The existing semantic token
60
+ already expresses the intended quiet secondary surface and automatically
61
+ tracks both themes.
62
+
63
+ ## Successful-user-story acceptance plan
64
+
65
+ Use the current task-owned local Content runtime or an equivalent disposable
66
+ runtime built from the exact Work artifact.
67
+
68
+ 1. Open an ordinary Page in light mode and insert a native Code Block.
69
+ 2. Confirm the block has a subtle non-white surface distinct from the Page,
70
+ with visible rounded bounds and normal vertical separation.
71
+ 3. Type representative plain and highlighted code; confirm text contrast,
72
+ syntax colors, caret, selection, horizontal overflow, and Tab remain usable.
73
+ 4. Switch to dark mode and confirm the same block has a subtle non-black/dark
74
+ canvas distinction without becoming a high-contrast black panel.
75
+ 5. Reload and confirm the Code Block source persists and the themed surface
76
+ returns.
77
+ 6. Confirm an ordinary paragraph, inline code, registry `Code`, and Mermaid
78
+ presentation are unchanged.
79
+ 7. Run formatter, Content typecheck, and the focused editor/style tests on the
80
+ exact review artifact.
81
+
82
+ Acceptance is human-facing and visual, so it uses a real interface with
83
+ preferred independence and same-context custody. Independent technical review
84
+ is not required for this bounded CSS-only refinement.
85
+
86
+ ## Lifecycle envelope
87
+
88
+ ```yaml
89
+ authoritySchemaVersion: 3
90
+ stage: shape
91
+ authority-source: "Alice: While at it, we should give the code block background a background that's different than the white of the page and the black of the page. $shape"
92
+ authorized-scope:
93
+ repositories:
94
+ - BuilderIO/agent-native
95
+ product-surfaces:
96
+ - Content ordinary native Code Block presentation
97
+ outcome: Give ordinary native Code Blocks a subtle theme-aware surface distinct from the Page canvas.
98
+ allowed-mutations:
99
+ - artifact-write
100
+ write-targets:
101
+ artifacts:
102
+ - templates/content/docs/solutions/2026-08-20-code-block-surface-background-shape.md
103
+ prototype-sandboxes: []
104
+ test-resources: []
105
+ governing-artifact:
106
+ path: templates/content/docs/solutions/2026-08-20-code-block-surface-background-shape.md
107
+ revision: content-code-block-surface-shape-v1
108
+ architecture-fingerprint:
109
+ outcome: Give ordinary native Code Blocks a subtle theme-aware surface distinct from the Page canvas.
110
+ shipping-surfaces:
111
+ - id: content-native-code-block-surface
112
+ repository: BuilderIO/agent-native
113
+ product-surface: Content visual Page editor ordinary native Code Block presentation
114
+ constituency: signed-in Content writers and readers
115
+ durable-destination: public Content template behavior in BuilderIO/agent-native
116
+ integration-action: merge
117
+ governing-architecture: Style the existing native Tiptap Code Block through Content's existing semantic theme tokens without adding a renderer, wrapper, block type, or palette.
118
+ acceptance-story:
119
+ id: content-native-code-block-surface-v1
120
+ summary: A writer sees the same ordinary Code Block as a quiet contained surface distinct from the Page in light and dark themes, with editing and persistence unchanged.
121
+ required-assertions:
122
+ - light mode Code Block surface is visibly distinct from the white Page canvas
123
+ - dark mode Code Block surface is visibly distinct from the dark Page canvas without becoming a black panel
124
+ - existing code text syntax highlighting caret selection overflow and Tab remain usable
125
+ - reload preserves source and restores the same theme-aware presentation
126
+ - paragraphs inline code registry Code Mermaid insertion and persistence behavior remain unchanged
127
+ - focused technical checks and exact-artifact real-interface acceptance pass
128
+ acceptance-policy:
129
+ modality: real-interface
130
+ independence: preferred
131
+ custody: same-context-allowed
132
+ interface: Disposable local Content Page built from the exact review artifact, exercised in light and dark themes.
133
+ rationale: The outcome is a bounded visual refinement whose success depends on rendered contrast in both themes; same-context real-interface judgment is proportionate.
134
+ risk-strategy:
135
+ kind: system-ready
136
+ production-validation-after-merge: false
137
+ architecture-grounding:
138
+ applicability: not-required
139
+ reason: Bounded local CSS refinement using an existing Content-owned class and existing semantic theme token; no shared contract, schema, renderer, identity, or persistence boundary changes.
140
+ status: grounded
141
+ demonstrated-callers:
142
+ - Signed-in Content writer or reader viewing an ordinary native Code Block in a Page.
143
+ existing-primitives:
144
+ - pre.notion-code-block from CodeBlockNode.tsx
145
+ - --background and --muted theme tokens in app/global.css
146
+ - existing wrapper radius and spacing treatment
147
+ ownership-boundaries:
148
+ - Content global editor CSS owns ordinary Code Block presentation
149
+ - Tiptap owns native Code Block structure and editing behavior
150
+ - Content theme tokens own light and dark surface values
151
+ legacy-contracts:
152
+ - portable fenced-code source and Lowlight syntax highlighting
153
+ - ordinary editor keyboard and persistence behavior
154
+ - registry Code Mermaid inline code and unrelated Page surfaces
155
+ shared-vocabulary:
156
+ - ordinary native Code Block means Tiptap codeBlock rendered as pre.notion-code-block
157
+ smallest-compatible-delta: Add one native-block-specific semantic background radius and margin rule after the shared pre typography rule.
158
+ deferred-capabilities:
159
+ - executable Code Block UX
160
+ - language headers and controls
161
+ - syntax palette redesign
162
+ - registry and Mermaid presentation
163
+ reversibility: One local CSS rule using existing tokens; removal restores the prior presentation with no data migration.
164
+ direct-evidence:
165
+ - repository revision fbe8c9c9060944e3514fd1f2b1a43edc88115199
166
+ - CodeBlockNode.tsx assigns notion-code-block to the native renderer
167
+ - global.css gives the old wrapper muted background but the native block transparent background
168
+ inferences:
169
+ - the contrast regression followed removal of the former React wrapper from the native renderer
170
+ unresolved-owner-questions: []
171
+ delegation-ceiling:
172
+ - artifact-write
173
+ product-boundary-gates:
174
+ agent-native-public-constituency: Any source-blind Content writer or reader benefits without Alice-private data credentials or orchestration; this belongs in the public Content template.
175
+ bowerbird-product-boundary: not-applicable
176
+ acceptance-state:
177
+ status: land-ready
178
+ summary: Work added the bounded semantic CSS rule and passed light/dark real-interface acceptance without changing adjacent Code Block behavior.
179
+ blockers: []
180
+ last-land-packet: null
181
+ ledger-revision: content-code-block-surface-shape-v1
182
+ status: work-complete
183
+ ```
184
+
185
+ ## Exact handoff
186
+
187
+ `/work templates/content/docs/solutions/2026-08-20-code-block-surface-background-shape.md`
188
+
189
+ Execution placement: local. The expected Work is one CSS rule, focused checks,
190
+ and light/dark browser acceptance; framework compute is unnecessary. The
191
+ currently running local server and Page remain available for Alice's manual
192
+ testing and were not mutated or stopped by Shape.
193
+
194
+ ## Work execution record
195
+
196
+ Work lane: `codex/code-block-surface-background` in
197
+ `/Users/alicemoore/.codex/worktrees/content-code-block-surface-background`,
198
+ refreshed from `origin/main` at
199
+ `8617890c4b9688ebcca5075efb74774f7ac39918` on 2026-08-20.
200
+
201
+ Acceptance reconciliation: consistent. Schema v3 freezes real-interface
202
+ acceptance, preferred independence, and same-context custody.
203
+
204
+ Work mutations are bounded to the CSS refinement, focused tests, this evidence
205
+ artifact, a local commit, and the following disposable test resource:
206
+
207
+ - resource id: `content-codeblock-surface-work-20260820`
208
+ - kind: local server, SQLite database, browser session, and task-created Page
209
+ - surface: `http://127.0.0.1:4189` backed by
210
+ `/tmp/content-codeblock-surface-work-20260820/content.db`
211
+ - ownership marker: Page title `Code Block Surface Acceptance 2026-08-20`
212
+ - baseline: port 4189 unbound and sandbox path absent before creation
213
+ - allowed actions: create, update, exercise, read back, reload, and delete
214
+ - cleanup trigger: after light/dark acceptance and evidence capture
215
+ - cleanup method: close the task browser tab, stop the server, confirm port
216
+ 4189 unbound, and move the exact sandbox to Trash
217
+ - cleanup proof: independent port and original-path absence checks
218
+ - shared impact: none
219
+ - isolation: local runtime
220
+ - ownership: task-created and task-exclusive
221
+ - production data: false
222
+ - customer data: false
223
+ - cost: none
224
+ - maximum lifetime: 240 minutes
225
+ - status: declared
226
+
227
+ ## Work evidence
228
+
229
+ Implementation:
230
+
231
+ - added one `.notion-editor .notion-code-block` rule using `hsl(var(--muted))`,
232
+ the existing 6px radius, and the existing `0.6em` vertical rhythm
233
+ - did not change the renderer, command transaction, persistence, registry Code,
234
+ Mermaid, inline code, syntax palette, or slash-command catalog
235
+
236
+ Exact real-interface acceptance on the task-created Content Page:
237
+
238
+ - light theme: block `rgb(245, 245, 245)` against Page
239
+ `rgb(255, 255, 255)`; text `rgb(38, 38, 38)`
240
+ - dark theme: block `rgb(41, 41, 41)` against Page `rgb(33, 33, 33)`;
241
+ text `rgb(230, 230, 230)`
242
+ - both themes: `6px` radius and `8.16px` top/bottom computed margins
243
+ - the persisted fenced source rendered through `pre.notion-code-block` as
244
+ `const greeting = "hello";// `
245
+
246
+ Technical checks:
247
+
248
+ - `oxfmt` passed for the modified CSS and this artifact
249
+ - `git diff --check` passed
250
+ - focused editor suite passed: 31/31 tests in
251
+ `SlashCommandMenu.test.ts`
252
+ - repository typecheck exited 0; it also printed the expected local-production
253
+ warnings for absent `BETTER_AUTH_SECRET` and persistent database URL
254
+ - changelog command was attempted and reported that changelogs are disabled in
255
+ the Content app configuration; no changelog file was created
256
+
257
+ Framework compute preflight could not reach the configured framework host
258
+ (Tailscale stopped and the host did not resolve), so the proportionate checks
259
+ ran locally on the actual execution host. This visual-only delta does not rely
260
+ on remote-host behavior.
261
+
262
+ Cleanup completed: the task browser tab was closed, the port-4189 server was
263
+ stopped, port 4189 was confirmed unbound, the original sandbox path was
264
+ confirmed absent, and the exact sandbox was moved to
265
+ `/Users/alicemoore/.Trash/content-codeblock-surface-work-20260820`. The fixture
266
+ is recoverable from Trash. The separate port-4188 insertion-test server and its
267
+ fixture were not touched.
268
+
269
+ Acceptance result: successful-user-story schema v3 is satisfied in the same
270
+ context allowed by the frozen custody policy. Independent human review remains
271
+ preferred but is not a completion gate for this bounded visual refinement.
272
+
273
+ ledger-revision: content-code-block-surface-work-v1
@@ -1389,7 +1389,7 @@ async function getHandler() {
1389
1389
  headers: {
1390
1390
  "Access-Control-Allow-Origin": "*",
1391
1391
  "Access-Control-Allow-Methods": "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS",
1392
- "Access-Control-Allow-Headers": "Content-Type,Authorization,X-Requested-With,X-Request-Source,X-Agent-Native-CSRF,X-User-Timezone,X-Agent-Native-Session-Id,X-Agent-Native-Client-Platform,X-Agent-Native-Tool-Bridge,X-Agent-Native-Tool-Id,X-Agent-Native-Frontend,X-Agent-Native-Client-Compatibility,X-Agent-Native-Build-Id,X-Agent-Native-Embed-Target",
1392
+ "Access-Control-Allow-Headers": "Content-Type,Authorization,X-Requested-With,X-Request-Source,X-Agent-Native-CSRF,X-User-Timezone,X-Agent-Native-Session-Id,X-Agent-Native-Client-Platform,X-Agent-Native-Desktop-Verifier,X-Agent-Native-Tool-Bridge,X-Agent-Native-Tool-Id,X-Agent-Native-Frontend,X-Agent-Native-Client-Compatibility,X-Agent-Native-Build-Id,X-Agent-Native-Embed-Target",
1393
1393
  },
1394
1394
  });
1395
1395
  }
@@ -41,16 +41,16 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
41
41
  thumbsUpRate: number;
42
42
  avgEvalScore: number;
43
43
  } | {
44
- error?: undefined;
45
44
  summary: import("./types.js").TraceSummary;
46
45
  spans: import("./types.js").TraceSpan[];
47
46
  id?: undefined;
47
+ error?: undefined;
48
48
  ok?: undefined;
49
49
  } | {
50
- error?: undefined;
51
50
  summary?: undefined;
52
51
  spans?: undefined;
53
52
  id: string;
53
+ error?: undefined;
54
54
  ok?: undefined;
55
55
  } | {
56
56
  summary?: undefined;
@@ -59,9 +59,9 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
59
59
  error: any;
60
60
  ok?: undefined;
61
61
  } | {
62
- error?: undefined;
63
62
  summary?: undefined;
64
63
  spans?: undefined;
65
64
  id?: undefined;
65
+ error?: undefined;
66
66
  ok: boolean;
67
67
  }>>;
@@ -15,6 +15,6 @@ export declare function createProgressHandler(): import("h3").EventHandlerWithFe
15
15
  error: string;
16
16
  ok?: undefined;
17
17
  } | {
18
- error?: undefined;
19
18
  ok: boolean;
19
+ error?: undefined;
20
20
  }>>;
@@ -37,17 +37,17 @@ export declare function createWriteSecretHandler(): import("h3").EventHandlerWit
37
37
  ok?: undefined;
38
38
  status?: undefined;
39
39
  } | {
40
- error?: undefined;
41
40
  ok: boolean;
42
41
  status: string;
42
+ error?: undefined;
43
43
  } | {
44
44
  ok?: undefined;
45
45
  error: string;
46
46
  removed?: undefined;
47
47
  } | {
48
- error?: undefined;
49
48
  ok: boolean;
50
49
  removed: boolean;
50
+ error?: undefined;
51
51
  }>>;
52
52
  /**
53
53
  * POST /_agent-native/secrets/:key/test — validate an optional candidate value
@@ -58,13 +58,13 @@ export declare function createTestSecretHandler(): import("h3").EventHandlerWith
58
58
  error: string;
59
59
  note?: undefined;
60
60
  } | {
61
- error?: undefined;
62
61
  ok: boolean;
63
62
  note?: undefined;
64
- } | {
65
63
  error?: undefined;
64
+ } | {
66
65
  ok: boolean;
67
66
  note: string;
67
+ error?: undefined;
68
68
  } | {
69
69
  note?: undefined;
70
70
  ok: boolean;
@@ -95,11 +95,11 @@ export interface AdHocSecretPayload {
95
95
  export declare function createAdHocSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<AdHocSecretPayload[] | {
96
96
  error: string;
97
97
  } | {
98
- error?: undefined;
99
98
  ok: boolean;
100
99
  key: string;
101
- } | {
102
100
  error?: undefined;
101
+ } | {
103
102
  ok: boolean;
104
103
  removed: boolean;
104
+ error?: undefined;
105
105
  }>>;
@@ -1,4 +1,4 @@
1
- import { createError, defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getQuery, getHeader, getRequestURL, } from "h3";
1
+ import { createError, defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getQuery, getHeader, } from "h3";
2
2
  import { verifyA2ATokenWithClaims } from "../a2a-claims.js";
3
3
  import { isActionContractError, isAgentActionStopError } from "../action.js";
4
4
  import { isTransientDatabaseError } from "../db/client.js";
@@ -15,6 +15,7 @@ import { getAllowedCorsOrigin as resolveAllowedCorsOrigin, readCorsAllowedOrigin
15
15
  import { resolveEmbedSessionFromRequest, resolvedEmbedCapabilityScope, } from "./embed-session.js";
16
16
  import { getHttpRequestTelemetryId } from "./http-response-telemetry.js";
17
17
  import { consumeOneTimeJti } from "./identity-sso-store.js";
18
+ import { getForwardedRequestOrigin } from "./request-origin.js";
18
19
  function requiredClientCompatibilityVersion() {
19
20
  const configured = typeof __AGENT_NATIVE_CLIENT_COMPATIBILITY_VERSION__ === "string"
20
21
  ? __AGENT_NATIVE_CLIENT_COMPATIBILITY_VERSION__
@@ -410,7 +411,7 @@ export function mountActionRoutes(nitroApp, actions, options) {
410
411
  timezone,
411
412
  browserSessionId,
412
413
  clientPlatform,
413
- requestOrigin: getRequestURL(event).origin,
414
+ requestOrigin: getForwardedRequestOrigin(event),
414
415
  // Captured here because this is the last layer that still holds
415
416
  // the h3 event; everything below reads it off the request store.
416
417
  isLoopbackRequest: isLoopbackRequest(event),
@@ -26,8 +26,8 @@ export declare function createRealtimeTokenHandler(): import("h3").EventHandlerW
26
26
  expiresAt?: undefined;
27
27
  ttlSeconds?: undefined;
28
28
  } | {
29
- error?: undefined;
30
29
  token: string;
31
30
  expiresAt: string;
32
31
  ttlSeconds: number;
32
+ error?: undefined;
33
33
  }>>;
@@ -1,4 +1,10 @@
1
1
  import { type H3Event } from "h3";
2
+ /**
3
+ * Browser-visible origin from proxy-forwarded headers. Unlike `getOrigin()`,
4
+ * this ignores OAuth callback and configured-public-origin overrides so action
5
+ * CSRF checks match the Referer the browser actually sent.
6
+ */
7
+ export declare function getForwardedRequestOrigin(event: H3Event): string;
2
8
  /**
3
9
  * Reject cross-site POSTs. Cookies are `SameSite=None; Secure` over HTTPS so
4
10
  * the browser would otherwise attach the session to a forged form submission
@@ -1,4 +1,16 @@
1
1
  import { getRequestHeader } from "h3";
2
+ /**
3
+ * Browser-visible origin from proxy-forwarded headers. Unlike `getOrigin()`,
4
+ * this ignores OAuth callback and configured-public-origin overrides so action
5
+ * CSRF checks match the Referer the browser actually sent.
6
+ */
7
+ export function getForwardedRequestOrigin(event) {
8
+ const headerHost = getRequestHeader(event, "x-forwarded-host") ||
9
+ getRequestHeader(event, "host");
10
+ const isProd = process.env.NODE_ENV === "production";
11
+ const headerProto = getRequestHeader(event, "x-forwarded-proto") || (isProd ? "https" : "http");
12
+ return `${headerProto}://${headerHost ?? "localhost"}`;
13
+ }
2
14
  function isLoopbackHost(host) {
3
15
  return host.startsWith("localhost:") || host.startsWith("127.0.0.1:");
4
16
  }
@@ -20,6 +20,6 @@ export declare function createTranscribeVoiceHandler(): import("h3").EventHandle
20
20
  error: string;
21
21
  text?: undefined;
22
22
  } | {
23
- error?: undefined;
24
23
  text: string;
24
+ error?: undefined;
25
25
  }>>;
@@ -1,4 +1,4 @@
1
- export declare const MCP_EMBED_CORS_ALLOW_HEADERS = "Content-Type,Authorization,X-Requested-With,X-Request-Source,X-Agent-Native-CSRF,X-Agent-Native-Frontend,X-Agent-Native-Client-Compatibility,X-Agent-Native-Build-Id,X-User-Timezone,X-Agent-Native-Session-Id,X-Agent-Native-Client-Platform,X-Agent-Native-Embed-Target,X-Agent-Native-Embed-Transplant";
1
+ export declare const MCP_EMBED_CORS_ALLOW_HEADERS = "Content-Type,Authorization,X-Requested-With,X-Request-Source,X-Agent-Native-CSRF,X-Agent-Native-Frontend,X-Agent-Native-Client-Compatibility,X-Agent-Native-Build-Id,X-User-Timezone,X-Agent-Native-Session-Id,X-Agent-Native-Client-Platform,X-Agent-Native-Desktop-Verifier,X-Agent-Native-Embed-Target,X-Agent-Native-Embed-Transplant";
2
2
  export declare const EMBED_TRANSPLANT_HEADER = "x-agent-native-embed-transplant";
3
3
  export declare function isLocalMcpEmbedOrigin(origin: string | null | undefined): boolean;
4
4
  export declare function isClaudeMcpContentOrigin(origin: string | null | undefined): boolean;
@@ -1,4 +1,4 @@
1
- export const MCP_EMBED_CORS_ALLOW_HEADERS = "Content-Type,Authorization,X-Requested-With,X-Request-Source,X-Agent-Native-CSRF,X-Agent-Native-Frontend,X-Agent-Native-Client-Compatibility,X-Agent-Native-Build-Id,X-User-Timezone,X-Agent-Native-Session-Id,X-Agent-Native-Client-Platform,X-Agent-Native-Embed-Target,X-Agent-Native-Embed-Transplant";
1
+ export const MCP_EMBED_CORS_ALLOW_HEADERS = "Content-Type,Authorization,X-Requested-With,X-Request-Source,X-Agent-Native-CSRF,X-Agent-Native-Frontend,X-Agent-Native-Client-Compatibility,X-Agent-Native-Build-Id,X-User-Timezone,X-Agent-Native-Session-Id,X-Agent-Native-Client-Platform,X-Agent-Native-Desktop-Verifier,X-Agent-Native-Embed-Target,X-Agent-Native-Embed-Transplant";
2
2
  export const EMBED_TRANSPLANT_HEADER = "x-agent-native-embed-transplant";
3
3
  const CLAUDE_MCP_CONTENT_HOST_RE = /^[a-f0-9]{32}\.claudemcpcontent\.com$/i;
4
4
  const CHATGPT_MCP_SANDBOX_HOST_RE = /^(?:[^.]+\.)?web-sandbox\.oaiusercontent\.com$/i;
@@ -128,8 +128,15 @@ export function shouldAllowMcpEmbedCredentials(origin) {
128
128
  // Builder, localhost, and arbitrary origins use bearer/embed credentials;
129
129
  // only the configured browser allowlist and the framework's exact native
130
130
  // app origins may receive cookies.
131
- return (TRUSTED_NATIVE_APP_ORIGIN_RE.test(origin) ||
132
- isExplicitCorsAllowedOrigin(origin));
131
+ if (TRUSTED_NATIVE_APP_ORIGIN_RE.test(origin) ||
132
+ isExplicitCorsAllowedOrigin(origin)) {
133
+ return true;
134
+ }
135
+ // Dev only: the desktop renderer runs on its own localhost port
136
+ // (http://localhost:1420 for Tauri) and calls the dev server with
137
+ // `credentials: "include"`. Production keeps the rule above — a deployed
138
+ // app must never hand cookies to an arbitrary process on the user's machine.
139
+ return (process.env.NODE_ENV === "development" && isLocalMcpEmbedOrigin(origin));
133
140
  }
134
141
  // These paths are served straight off the CDN, so the security-headers h3
135
142
  // middleware never runs for them — anything it sets that must also hold for
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.168.9",
3
+ "version": "0.168.11",
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": {