@agent-native/core 0.213.1 → 0.214.0

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 (33) hide show
  1. package/dist/appearance/actions/get-theme-family.d.ts +8 -0
  2. package/dist/appearance/actions/get-theme-family.js +38 -0
  3. package/dist/appearance/actions/set-theme-family.d.ts +7 -0
  4. package/dist/appearance/actions/set-theme-family.js +33 -0
  5. package/dist/appearance/theme-family.d.ts +13 -0
  6. package/dist/appearance/theme-family.js +38 -0
  7. package/dist/client/theme-family.d.ts +35 -0
  8. package/dist/client/theme-family.js +223 -0
  9. package/dist/client/theme.d.ts +1 -1
  10. package/dist/client/theme.js +5 -2
  11. package/dist/client/ui/index.d.ts +1 -0
  12. package/dist/client/ui/index.js +1 -0
  13. package/dist/collab/awareness.d.ts +2 -2
  14. package/dist/collab/routes.d.ts +2 -2
  15. package/dist/collab/struct-routes.d.ts +1 -1
  16. package/dist/data-widgets/index.d.ts +339 -4
  17. package/dist/data-widgets/index.js +150 -7
  18. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  19. package/dist/framework-tools.js +2 -0
  20. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  21. package/dist/progress/routes.d.ts +1 -1
  22. package/dist/provider-api/actions/custom-provider-registration.d.ts +3 -3
  23. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  24. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  25. package/dist/secrets/routes.d.ts +4 -4
  26. package/dist/server/action-discovery.js +8 -0
  27. package/dist/server/agent-chat/context-tools.js +43 -1
  28. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  29. package/dist/server/agent-engine-default-model-route.d.ts +1 -1
  30. package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
  31. package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
  32. package/dist/triggers/actions/manage-automation.d.ts +1 -1
  33. package/package.json +3 -3
@@ -0,0 +1,8 @@
1
+ import { type ThemeFamily } from "../theme-family.js";
2
+ export interface ThemeFamilyPreference {
3
+ family: ThemeFamily;
4
+ source: "default" | "user-setting";
5
+ appId: string | null;
6
+ }
7
+ declare const _default: import("../../action.js").ActionDefinition<Record<string, never>, ThemeFamilyPreference>;
8
+ export default _default;
@@ -0,0 +1,38 @@
1
+ import { z } from "zod";
2
+ import { defineAction, fail } from "../../action.js";
3
+ import { getUserSetting } from "../../settings/user-settings.js";
4
+ import { DEFAULT_THEME_FAMILY, THEME_FAMILIES, themeFamilySettingKey, } from "../theme-family.js";
5
+ export default defineAction({
6
+ description: "Read the current app's saved theme family, which is independent of light or dark color mode.",
7
+ schema: z.object({}),
8
+ http: { method: "GET" },
9
+ readOnly: true,
10
+ agentTool: false,
11
+ run: async (_args, ctx) => {
12
+ const email = ctx?.userEmail;
13
+ if (!email)
14
+ fail("Not authenticated.", { statusCode: 401 });
15
+ const stored = await getUserSetting(email, themeFamilySettingKey(ctx?.appId));
16
+ if (stored === null) {
17
+ return {
18
+ family: DEFAULT_THEME_FAMILY,
19
+ source: "default",
20
+ appId: ctx?.appId ?? null,
21
+ };
22
+ }
23
+ const parsed = z
24
+ .object({ family: z.enum(THEME_FAMILIES) })
25
+ .safeParse(stored);
26
+ if (!parsed.success) {
27
+ fail("The saved theme family setting is invalid and could not be read.", {
28
+ errorCode: "theme_family_setting_invalid",
29
+ statusCode: 500,
30
+ });
31
+ }
32
+ return {
33
+ family: parsed.data.family,
34
+ source: "user-setting",
35
+ appId: ctx?.appId ?? null,
36
+ };
37
+ },
38
+ });
@@ -0,0 +1,7 @@
1
+ declare const _default: import("../../action.js").ActionDefinition<{
2
+ family: "agent-native" | "original";
3
+ }, {
4
+ family: "agent-native" | "original";
5
+ appId: string;
6
+ }>;
7
+ export default _default;
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ import { defineAction, fail } from "../../action.js";
3
+ import { writeAppState } from "../../application-state/script-helpers.js";
4
+ import { putUserSetting } from "../../settings/user-settings.js";
5
+ import { THEME_FAMILIES, themeFamilyAppStateKey, themeFamilySettingKey, } from "../theme-family.js";
6
+ export default defineAction({
7
+ description: "Set the current app's theme family to agent-native or original. This is separate from light or dark color mode.",
8
+ schema: z.object({
9
+ family: z
10
+ .enum(THEME_FAMILIES)
11
+ .describe("Theme family: agent-native or original."),
12
+ }),
13
+ http: { method: "POST" },
14
+ mcpAnnotations: {
15
+ readOnlyHint: false,
16
+ destructiveHint: false,
17
+ openWorldHint: false,
18
+ },
19
+ run: async ({ family }, ctx) => {
20
+ const email = ctx?.userEmail;
21
+ if (!email)
22
+ fail("Not authenticated.", { statusCode: 401 });
23
+ const settingKey = themeFamilySettingKey(ctx?.appId);
24
+ await putUserSetting(email, settingKey, { family });
25
+ try {
26
+ await writeAppState(themeFamilyAppStateKey(ctx?.appId), { family });
27
+ }
28
+ catch {
29
+ fail("The theme family was saved, but the open app could not be synchronized.", { errorCode: "theme_family_sync_failed", statusCode: 503 });
30
+ }
31
+ return { family, appId: ctx?.appId ?? null };
32
+ },
33
+ });
@@ -0,0 +1,13 @@
1
+ export declare const THEME_FAMILIES: readonly ["agent-native", "original"];
2
+ export type ThemeFamily = (typeof THEME_FAMILIES)[number];
3
+ export declare const DEFAULT_THEME_FAMILY: ThemeFamily;
4
+ export declare const THEME_FAMILY_STORAGE_KEY = "theme-family";
5
+ export declare const THEME_FAMILY_ATTRIBUTE = "data-theme-family";
6
+ export declare const THEME_FAMILY_STATUS_ATTRIBUTE = "data-theme-family-status";
7
+ export declare const THEME_FAMILY_APP_STATE_KEY = "theme-family";
8
+ export declare const THEME_FAMILY_SETTING_PREFIX = "theme-family";
9
+ export declare function isThemeFamily(value: unknown): value is ThemeFamily;
10
+ export declare function themeFamilySettingKey(appId?: string): string;
11
+ export declare function themeFamilyStorageKey(appId?: string): string;
12
+ export declare function themeFamilyAppStateKey(appId?: string): string;
13
+ export declare function getThemeFamilyInitScript(appId?: string | null): string;
@@ -0,0 +1,38 @@
1
+ export const THEME_FAMILIES = ["agent-native", "original"];
2
+ export const DEFAULT_THEME_FAMILY = "original";
3
+ export const THEME_FAMILY_STORAGE_KEY = "theme-family";
4
+ export const THEME_FAMILY_ATTRIBUTE = "data-theme-family";
5
+ export const THEME_FAMILY_STATUS_ATTRIBUTE = "data-theme-family-status";
6
+ export const THEME_FAMILY_APP_STATE_KEY = "theme-family";
7
+ export const THEME_FAMILY_SETTING_PREFIX = "theme-family";
8
+ export function isThemeFamily(value) {
9
+ return value === "agent-native" || value === "original";
10
+ }
11
+ export function themeFamilySettingKey(appId) {
12
+ // Older or standalone action contexts can genuinely omit appId. Keep their
13
+ // setting isolated under one stable fallback rather than borrowing another app's choice.
14
+ if (appId === undefined)
15
+ return `${THEME_FAMILY_SETTING_PREFIX}:__no_app_id__`;
16
+ const normalizedAppId = appId.trim().toLowerCase();
17
+ if (!normalizedAppId) {
18
+ throw new TypeError("Theme family settings require a non-empty appId.");
19
+ }
20
+ return `${THEME_FAMILY_SETTING_PREFIX}:${encodeURIComponent(normalizedAppId)}`;
21
+ }
22
+ export function themeFamilyStorageKey(appId) {
23
+ return themeFamilySettingKey(appId);
24
+ }
25
+ export function themeFamilyAppStateKey(appId) {
26
+ if (appId === undefined)
27
+ return `${THEME_FAMILY_APP_STATE_KEY}:__no_app_id__`;
28
+ const normalizedAppId = appId.trim().toLowerCase();
29
+ if (!normalizedAppId) {
30
+ throw new TypeError("Theme family application state requires a non-empty appId.");
31
+ }
32
+ const encodedAppId = Array.from(normalizedAppId, (character) => character.codePointAt(0).toString(16)).join("_");
33
+ return `${THEME_FAMILY_APP_STATE_KEY}:${encodedAppId}`;
34
+ }
35
+ export function getThemeFamilyInitScript(appId) {
36
+ const storageKey = themeFamilyStorageKey(appId ?? undefined);
37
+ return `(function(){var root=document.documentElement;var fallback=${JSON.stringify(DEFAULT_THEME_FAMILY)};try{var value=window.localStorage.getItem(${JSON.stringify(storageKey)});if(value===null){root.setAttribute(${JSON.stringify(THEME_FAMILY_ATTRIBUTE)},fallback);root.setAttribute(${JSON.stringify(THEME_FAMILY_STATUS_ATTRIBUTE)},'awaiting-app-setting');return}if(value==='agent-native'||value==='original'){root.setAttribute(${JSON.stringify(THEME_FAMILY_ATTRIBUTE)},value);root.removeAttribute(${JSON.stringify(THEME_FAMILY_STATUS_ATTRIBUTE)});return}root.setAttribute(${JSON.stringify(THEME_FAMILY_ATTRIBUTE)},fallback);root.setAttribute(${JSON.stringify(THEME_FAMILY_STATUS_ATTRIBUTE)},'invalid')}catch(e){root.setAttribute(${JSON.stringify(THEME_FAMILY_ATTRIBUTE)},fallback);root.setAttribute(${JSON.stringify(THEME_FAMILY_STATUS_ATTRIBUTE)},'unreadable')}})();`;
38
+ }
@@ -0,0 +1,35 @@
1
+ import { type ThemeFamily } from "../appearance/theme-family.js";
2
+ export { DEFAULT_THEME_FAMILY, isThemeFamily, THEME_FAMILY_APP_STATE_KEY, THEME_FAMILY_ATTRIBUTE, THEME_FAMILY_STORAGE_KEY, themeFamilyAppStateKey, themeFamilyStorageKey, type ThemeFamily, } from "../appearance/theme-family.js";
3
+ export declare const THEME_FAMILY_CHANGE_EVENT = "agent-native:theme-family-change";
4
+ export type ThemeFamilyStorageStatus = "valid" | "missing" | "invalid" | "unreadable";
5
+ export type StoredThemeFamily = {
6
+ status: "valid";
7
+ family: ThemeFamily;
8
+ } | {
9
+ status: "missing";
10
+ } | {
11
+ status: "invalid";
12
+ value: string;
13
+ } | {
14
+ status: "unreadable";
15
+ error: Error;
16
+ };
17
+ export interface ThemeFamilyApplyResult {
18
+ family: ThemeFamily;
19
+ storageStatus: "saved" | "unavailable";
20
+ }
21
+ export interface ThemeFamilyPreference {
22
+ family: ThemeFamily;
23
+ source: "default" | "user-setting";
24
+ appId: string | null;
25
+ }
26
+ export declare function readStoredThemeFamily(appId?: string | null): StoredThemeFamily;
27
+ export declare function applyThemeFamily(family: ThemeFamily, appId?: string | null): ThemeFamilyApplyResult;
28
+ export interface ThemeFamilyHook {
29
+ family: ThemeFamily;
30
+ status: "loading" | "success" | "error";
31
+ error?: Error;
32
+ storageStatus: ThemeFamilyStorageStatus;
33
+ setFamily: (family: ThemeFamily) => Promise<ThemeFamily>;
34
+ }
35
+ export declare function useThemeFamily(): ThemeFamilyHook;
@@ -0,0 +1,223 @@
1
+ import { useCallback, useEffect, useRef, useState, useSyncExternalStore, } from "react";
2
+ import { DEFAULT_THEME_FAMILY, isThemeFamily, THEME_FAMILY_ATTRIBUTE, THEME_FAMILY_STATUS_ATTRIBUTE, themeFamilyAppStateKey, themeFamilyStorageKey, } from "../appearance/theme-family.js";
3
+ import { injectedAgentNativeAppId } from "./app-config.js";
4
+ import { readClientAppState } from "./application-state.js";
5
+ import { useActionMutation, useActionQuery } from "./use-action.js";
6
+ import { useChangeVersion } from "./use-change-version.js";
7
+ export { DEFAULT_THEME_FAMILY, isThemeFamily, THEME_FAMILY_APP_STATE_KEY, THEME_FAMILY_ATTRIBUTE, THEME_FAMILY_STORAGE_KEY, themeFamilyAppStateKey, themeFamilyStorageKey, } from "../appearance/theme-family.js";
8
+ export const THEME_FAMILY_CHANGE_EVENT = "agent-native:theme-family-change";
9
+ const familySnapshots = new Map();
10
+ function resolvedAppId(appId) {
11
+ if (appId !== undefined)
12
+ return appId ?? undefined;
13
+ return injectedAgentNativeAppId() ?? undefined;
14
+ }
15
+ function scopeKey(appId) {
16
+ return themeFamilyStorageKey(resolvedAppId(appId));
17
+ }
18
+ function asError(error) {
19
+ return error instanceof Error ? error : new Error(String(error));
20
+ }
21
+ export function readStoredThemeFamily(appId) {
22
+ if (typeof window === "undefined")
23
+ return { status: "missing" };
24
+ let value;
25
+ try {
26
+ value = window.localStorage.getItem(themeFamilyStorageKey(resolvedAppId(appId)));
27
+ }
28
+ catch (error) {
29
+ return { status: "unreadable", error: asError(error) };
30
+ }
31
+ if (value === null)
32
+ return { status: "missing" };
33
+ if (isThemeFamily(value))
34
+ return { status: "valid", family: value };
35
+ return { status: "invalid", value };
36
+ }
37
+ function getFamilySnapshot(appId) {
38
+ return familySnapshots.get(scopeKey(appId)) ?? DEFAULT_THEME_FAMILY;
39
+ }
40
+ function subscribe(onChange, appId) {
41
+ if (typeof window === "undefined")
42
+ return () => { };
43
+ const refreshFromStorage = () => {
44
+ const stored = readStoredThemeFamily(appId);
45
+ const key = scopeKey(appId);
46
+ if (stored.status === "valid") {
47
+ familySnapshots.set(key, stored.family);
48
+ window.document.documentElement.setAttribute(THEME_FAMILY_ATTRIBUTE, stored.family);
49
+ window.document.documentElement.removeAttribute(THEME_FAMILY_STATUS_ATTRIBUTE);
50
+ }
51
+ else if (stored.status === "missing" || stored.status === "invalid") {
52
+ familySnapshots.set(key, DEFAULT_THEME_FAMILY);
53
+ window.document.documentElement.setAttribute(THEME_FAMILY_ATTRIBUTE, DEFAULT_THEME_FAMILY);
54
+ if (stored.status === "invalid") {
55
+ window.document.documentElement.setAttribute(THEME_FAMILY_STATUS_ATTRIBUTE, "invalid");
56
+ }
57
+ }
58
+ onChange();
59
+ };
60
+ const onStorage = (event) => {
61
+ if (event.key === null || event.key === scopeKey(appId)) {
62
+ refreshFromStorage();
63
+ }
64
+ };
65
+ const onFamilyChange = (event) => {
66
+ const storageKey = event.detail
67
+ ?.storageKey;
68
+ if (storageKey === scopeKey(appId))
69
+ refreshFromStorage();
70
+ };
71
+ window.addEventListener("storage", onStorage);
72
+ window.addEventListener(THEME_FAMILY_CHANGE_EVENT, onFamilyChange);
73
+ return () => {
74
+ window.removeEventListener("storage", onStorage);
75
+ window.removeEventListener(THEME_FAMILY_CHANGE_EVENT, onFamilyChange);
76
+ };
77
+ }
78
+ export function applyThemeFamily(family, appId) {
79
+ if (!isThemeFamily(family)) {
80
+ throw new TypeError(`Unknown theme family: ${String(family)}`);
81
+ }
82
+ const storageAppId = resolvedAppId(appId);
83
+ const key = themeFamilyStorageKey(storageAppId);
84
+ familySnapshots.set(key, family);
85
+ if (typeof window === "undefined") {
86
+ return { family, storageStatus: "unavailable" };
87
+ }
88
+ const root = window.document.documentElement;
89
+ root.setAttribute(THEME_FAMILY_ATTRIBUTE, family);
90
+ try {
91
+ window.localStorage.setItem(key, family);
92
+ root.removeAttribute(THEME_FAMILY_STATUS_ATTRIBUTE);
93
+ window.dispatchEvent(new CustomEvent(THEME_FAMILY_CHANGE_EVENT, {
94
+ detail: { storageKey: key },
95
+ }));
96
+ return { family, storageStatus: "saved" };
97
+ }
98
+ catch {
99
+ root.setAttribute(THEME_FAMILY_STATUS_ATTRIBUTE, "unreadable");
100
+ window.dispatchEvent(new CustomEvent(THEME_FAMILY_CHANGE_EVENT, {
101
+ detail: { storageKey: key },
102
+ }));
103
+ return { family, storageStatus: "unavailable" };
104
+ }
105
+ }
106
+ function storageStatusForApply(result) {
107
+ return result.storageStatus === "saved" ? "valid" : "unreadable";
108
+ }
109
+ function errorForState(value) {
110
+ return new Error(`The open app's theme-family state is invalid: ${JSON.stringify(value)}`);
111
+ }
112
+ export function useThemeFamily() {
113
+ const runtimeAppId = injectedAgentNativeAppId();
114
+ const query = useActionQuery("get-theme-family", undefined, { retry: false, queryKeyScope: ["theme-family", runtimeAppId] });
115
+ const mutation = useActionMutation("set-theme-family", { skipActionQueryInvalidation: true });
116
+ const appId = query.data === undefined ? runtimeAppId : query.data.appId;
117
+ const appStateKey = themeFamilyAppStateKey(appId ?? undefined);
118
+ const appStateVersion = useChangeVersion(`app-state:${appStateKey}`);
119
+ const [storageStatus, setStorageStatus] = useState(() => readStoredThemeFamily(appId).status);
120
+ const [mutationError, setMutationError] = useState();
121
+ const mutationPending = useRef(false);
122
+ const family = useSyncExternalStore((onChange) => subscribe(onChange, appId), () => getFamilySnapshot(appId), () => DEFAULT_THEME_FAMILY);
123
+ useEffect(() => {
124
+ if (mutationPending.current)
125
+ return;
126
+ if (query.data === undefined)
127
+ return;
128
+ if (!isThemeFamily(query.data?.family)) {
129
+ setMutationError(errorForState(query.data));
130
+ return;
131
+ }
132
+ const applied = applyThemeFamily(query.data.family, query.data.appId);
133
+ setStorageStatus(storageStatusForApply(applied));
134
+ setMutationError(undefined);
135
+ }, [mutationPending, query.data]);
136
+ useEffect(() => {
137
+ if (appStateVersion === 0)
138
+ return;
139
+ let current = true;
140
+ void readClientAppState(appStateKey)
141
+ .then((state) => {
142
+ if (!current || state === null)
143
+ return;
144
+ if (!isThemeFamily(state.family)) {
145
+ setMutationError(errorForState(state));
146
+ return;
147
+ }
148
+ const applied = applyThemeFamily(state.family, appId);
149
+ setStorageStatus(storageStatusForApply(applied));
150
+ setMutationError(undefined);
151
+ })
152
+ .catch((error) => {
153
+ if (current)
154
+ setMutationError(asError(error));
155
+ });
156
+ return () => {
157
+ current = false;
158
+ };
159
+ }, [appId, appStateKey, appStateVersion]);
160
+ const setFamily = useCallback(async (nextFamily) => {
161
+ if (!isThemeFamily(nextFamily)) {
162
+ throw new TypeError(`Unknown theme family: ${String(nextFamily)}`);
163
+ }
164
+ const previousAppId = appId;
165
+ const previousFamily = getFamilySnapshot(previousAppId);
166
+ mutationPending.current = true;
167
+ const optimistic = applyThemeFamily(nextFamily, previousAppId);
168
+ setStorageStatus(storageStatusForApply(optimistic));
169
+ setMutationError(undefined);
170
+ try {
171
+ const result = await mutation.mutateAsync({ family: nextFamily });
172
+ if (!isThemeFamily(result?.family)) {
173
+ throw errorForState(result);
174
+ }
175
+ if (result.appId !== null && typeof result.appId !== "string") {
176
+ throw errorForState(result);
177
+ }
178
+ if (result.family !== nextFamily) {
179
+ throw new Error("The saved theme family did not match the selection.");
180
+ }
181
+ mutationPending.current = false;
182
+ const applied = applyThemeFamily(result.family, result.appId);
183
+ setStorageStatus(storageStatusForApply(applied));
184
+ return result.family;
185
+ }
186
+ catch (error) {
187
+ const normalized = asError(error);
188
+ let reconciledFamily = previousFamily;
189
+ let reconciledAppId = previousAppId;
190
+ let reconciliationError;
191
+ try {
192
+ const refreshed = await query.refetch();
193
+ const data = refreshed.data;
194
+ if (refreshed.isError) {
195
+ reconciliationError = asError(refreshed.error);
196
+ }
197
+ else if (!data ||
198
+ !isThemeFamily(data.family) ||
199
+ (data.appId !== null && typeof data.appId !== "string")) {
200
+ reconciliationError = errorForState(data);
201
+ }
202
+ else {
203
+ reconciledFamily = data.family;
204
+ reconciledAppId = data.appId;
205
+ }
206
+ }
207
+ catch (refreshError) {
208
+ reconciliationError = asError(refreshError);
209
+ }
210
+ mutationPending.current = false;
211
+ const reconciled = applyThemeFamily(reconciledFamily, reconciledAppId);
212
+ setStorageStatus(storageStatusForApply(reconciled));
213
+ const failure = reconciliationError
214
+ ? new AggregateError([normalized, reconciliationError], "The theme family update failed and its saved value could not be reloaded.")
215
+ : normalized;
216
+ setMutationError(failure);
217
+ throw failure;
218
+ }
219
+ }, [appId, mutation]);
220
+ const error = mutationError ?? (query.isError ? asError(query.error) : undefined);
221
+ const status = error ? "error" : query.isSuccess ? "success" : "loading";
222
+ return { family, status, error, storageStatus, setFamily };
223
+ }
@@ -15,5 +15,5 @@ export interface NormalizedEmbeddedThemeUpdate {
15
15
  export declare function parseEmbeddedThemeUpdate(value: unknown): NormalizedEmbeddedThemeUpdate | null;
16
16
  export declare function buildEmbeddedThemeUpdate(theme: ResolvedTheme, vars?: Record<string, string>): EmbeddedThemeUpdate;
17
17
  export declare function applyEmbeddedThemeUpdate(root: HTMLElement, update: NormalizedEmbeddedThemeUpdate): void;
18
- export declare function getThemeInitScript(defaultTheme?: ThemePreference, enableSystem?: boolean): string;
18
+ export declare function getThemeInitScript(defaultTheme?: ThemePreference, enableSystem?: boolean, appId?: string): string;
19
19
  export declare const themeInitScript: string;
@@ -1,4 +1,6 @@
1
+ import { getThemeFamilyInitScript } from "../appearance/theme-family.js";
1
2
  import { THEME_VAR_NAMES } from "../extensions/theme.js";
3
+ import { injectedAgentNativeAppId } from "./app-config.js";
2
4
  import { getViteDevRecoveryScript, shouldInlineViteDevRecoveryScript, } from "./vite-dev-recovery-script.js";
3
5
  export const EMBEDDED_THEME_UPDATE_MESSAGE = "agent-native-theme-update";
4
6
  export const EMBEDDED_THEME_CHANGE_EVENT = "agent-native:theme-change";
@@ -60,10 +62,11 @@ function normalizeDefaultTheme(theme) {
60
62
  }
61
63
  return "system";
62
64
  }
63
- export function getThemeInitScript(defaultTheme = "system", enableSystem = true) {
65
+ export function getThemeInitScript(defaultTheme = "system", enableSystem = true, appId) {
64
66
  const safeDefaultTheme = normalizeDefaultTheme(defaultTheme);
65
67
  const systemEnabled = enableSystem ? "true" : "false";
66
- const themeScript = `(function(){function m(){var d={};return{get length(){return Object.keys(d).length},key:function(i){return Object.keys(d)[i]||null},getItem:function(k){k=String(k);return Object.prototype.hasOwnProperty.call(d,k)?d[k]:null},setItem:function(k,v){d[String(k)]=String(v)},removeItem:function(k){delete d[String(k)]},clear:function(){d={}}}}function s(n){try{var x=window[n],p='__an_storage_probe__';x.setItem(p,'1');x.removeItem(p)}catch(e){try{Object.defineProperty(window,n,{configurable:true,value:m()})}catch(_){}}}s('localStorage');s('sessionStorage');try{var defaultTheme=${JSON.stringify(safeDefaultTheme)};var enableSystem=${systemEnabled};var stored=window.localStorage.getItem('theme');var valid=stored==='light'||stored==='dark'||stored==='system'||stored==='auto';var mode=valid?stored:defaultTheme;if(mode==='auto')mode='system';if(!enableSystem&&mode==='system')mode=defaultTheme==='system'?'light':defaultTheme;if(!valid){window.localStorage.removeItem('theme')}else if(stored!==mode){window.localStorage.setItem('theme',mode)}var prefersDark=enableSystem&&mode==='system'&&window.matchMedia&&window.matchMedia('(prefers-color-scheme: dark)').matches;var resolved=mode==='system'?(prefersDark?'dark':'light'):mode;var root=document.documentElement;root.classList.remove('light','dark');root.classList.add(resolved);root.setAttribute('data-theme',resolved);root.style.colorScheme=resolved;var appearance=window.localStorage.getItem('appearance');var appearanceValid=appearance==='warm'||appearance==='ocean'||appearance==='forest'||appearance==='rose'||appearance==='slate';if(appearanceValid){root.setAttribute('data-appearance',appearance)}else{root.removeAttribute('data-appearance');if(appearance!==null)window.localStorage.removeItem('appearance')}}catch(e){}})();`;
68
+ const themeFamilyAppId = appId ?? injectedAgentNativeAppId() ?? undefined;
69
+ const themeScript = `${getThemeFamilyInitScript(themeFamilyAppId)}\n(function(){function m(){var d={};return{get length(){return Object.keys(d).length},key:function(i){return Object.keys(d)[i]||null},getItem:function(k){k=String(k);return Object.prototype.hasOwnProperty.call(d,k)?d[k]:null},setItem:function(k,v){d[String(k)]=String(v)},removeItem:function(k){delete d[k]},clear:function(){d={}}}}function s(n){try{var x=window[n],p='__an_storage_probe__';x.setItem(p,'1');x.removeItem(p)}catch(e){try{Object.defineProperty(window,n,{configurable:true,value:m()})}catch(_){}}}s('localStorage');s('sessionStorage');try{var defaultTheme=${JSON.stringify(safeDefaultTheme)};var enableSystem=${systemEnabled};var stored=window.localStorage.getItem('theme');var valid=stored==='light'||stored==='dark'||stored==='system'||stored==='auto';var mode=valid?stored:defaultTheme;if(mode==='auto')mode='system';if(!enableSystem&&mode==='system')mode=defaultTheme==='system'?'light':defaultTheme;if(!valid){window.localStorage.removeItem('theme')}else if(stored!==mode){window.localStorage.setItem('theme',mode)}var prefersDark=enableSystem&&mode==='system'&&window.matchMedia&&window.matchMedia('(prefers-color-scheme: dark)').matches;var resolved=mode==='system'?(prefersDark?'dark':'light'):mode;var root=document.documentElement;root.classList.remove('light','dark');root.classList.add(resolved);root.setAttribute('data-theme',resolved);root.style.colorScheme=resolved;var appearance=window.localStorage.getItem('appearance');var appearanceValid=appearance==='warm'||appearance==='ocean'||appearance==='forest'||appearance==='rose'||appearance==='slate';if(appearanceValid){root.setAttribute('data-appearance',appearance)}else{root.removeAttribute('data-appearance');if(appearance!==null)window.localStorage.removeItem('appearance')}}catch(e){document.documentElement.setAttribute('data-theme-status','unreadable')}})();`;
67
70
  if (!shouldInlineViteDevRecoveryScript())
68
71
  return themeScript;
69
72
  return `${themeScript}\n${getViteDevRecoveryScript()}`;
@@ -2,3 +2,4 @@ export { buildErrorReportTemplate, buildGitHubIssueUrl, type ErrorReportDebugIte
2
2
  export { getClientSurface, type ClientSurface } from "../client-surface.js";
3
3
  export { applyEmbeddedThemeUpdate, buildEmbeddedThemeUpdate, EMBEDDED_THEME_CHANGE_EVENT, EMBEDDED_THEME_UPDATE_MESSAGE, getThemeInitScript, parseEmbeddedThemeUpdate, themeInitScript, type EmbeddedThemeUpdate, type NormalizedEmbeddedThemeUpdate, type ResolvedTheme, type ThemePreference, } from "../theme.js";
4
4
  export { APPEARANCE_PRESETS, applyAppearance, getStoredAppearance, useAppearance, useAppearanceSync, type AppearancePresetId, } from "../appearance.js";
5
+ export { applyThemeFamily, readStoredThemeFamily, THEME_FAMILY_CHANGE_EVENT, useThemeFamily, type StoredThemeFamily, type ThemeFamily, type ThemeFamilyApplyResult, type ThemeFamilyHook, type ThemeFamilyStorageStatus, } from "../theme-family.js";
@@ -2,3 +2,4 @@ export { buildErrorReportTemplate, buildGitHubIssueUrl, } from "../error-reporti
2
2
  export { getClientSurface } from "../client-surface.js";
3
3
  export { applyEmbeddedThemeUpdate, buildEmbeddedThemeUpdate, EMBEDDED_THEME_CHANGE_EVENT, EMBEDDED_THEME_UPDATE_MESSAGE, getThemeInitScript, parseEmbeddedThemeUpdate, themeInitScript, } from "../theme.js";
4
4
  export { APPEARANCE_PRESETS, applyAppearance, getStoredAppearance, useAppearance, useAppearanceSync, } from "../appearance.js";
5
+ export { applyThemeFamily, readStoredThemeFamily, THEME_FAMILY_CHANGE_EVENT, useThemeFamily, } from "../theme-family.js";
@@ -38,19 +38,19 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
38
38
  error: string;
39
39
  states?: undefined;
40
40
  } | {
41
+ error?: undefined;
41
42
  states: {
42
43
  clientId: number;
43
44
  state: string;
44
45
  }[];
45
- error?: undefined;
46
46
  }>>;
47
47
  export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
48
48
  error: string;
49
49
  users?: undefined;
50
50
  } | {
51
+ error?: undefined;
51
52
  users: {
52
53
  clientId: number;
53
54
  lastSeen: number;
54
55
  }[];
55
- error?: undefined;
56
56
  }>>;
@@ -13,12 +13,12 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
13
13
  };
14
14
  }>>;
15
15
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
- ok?: undefined;
17
16
  error: string;
17
+ ok?: undefined;
18
18
  } | {
19
- error?: undefined;
20
19
  liveCopy: "derived" | "not_derived" | "unchanged";
21
20
  liveCopyReason?: string;
21
+ error?: undefined;
22
22
  ok: boolean;
23
23
  } | {
24
24
  error?: undefined;
@@ -1,6 +1,6 @@
1
1
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
2
- ok?: undefined;
3
2
  error: string;
3
+ ok?: undefined;
4
4
  } | {
5
5
  error?: undefined;
6
6
  ok: boolean;