@molecule/app-ide-react 1.20.5 → 1.21.1

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.
@@ -13,12 +13,16 @@
13
13
  * credential, so write access through one is something a host has to opt into
14
14
  * rather than something this modal offers by default.
15
15
  *
16
+ * A host can add its own sections below the links (`children`) — e.g. what a
17
+ * link exposes beyond the app — and can hide the links section (`showLinks`)
18
+ * for a caller who may open the dialog but not see the links.
19
+ *
16
20
  * Styling uses `getClassMap()` (`cm.*`); the only inline styles are layout the
17
21
  * ClassMap can't express. All user-facing text goes through `t()`.
18
22
  *
19
23
  * @module
20
24
  */
21
- import type { JSX } from 'react';
25
+ import type { JSX, ReactNode } from 'react';
22
26
  import type { ShareLinkResult, ShareRole } from './chat-share-utilities.js';
23
27
  /**
24
28
  * The share-link modal opened by `/share`, `/share <role>`, and the header
@@ -27,7 +31,7 @@ import type { ShareLinkResult, ShareRole } from './chat-share-utilities.js';
27
31
  * @param props - Component props.
28
32
  * @returns The rendered share modal.
29
33
  */
30
- export declare function ShareModal({ projectId, initialRole, roles, canManage, canCreate, canRevoke, onClose, onCreated, }: {
34
+ export declare function ShareModal({ projectId, initialRole, roles, canManage, canCreate, canRevoke, showLinks, refreshSignal, children, onClose, onCreated, }: {
31
35
  projectId: string;
32
36
  initialRole?: ShareRole;
33
37
  /**
@@ -48,6 +52,16 @@ export declare function ShareModal({ projectId, initialRole, roles, canManage, c
48
52
  canCreate?: boolean;
49
53
  /** Whether the caller may REVOKE a link. Defaults to `canManage`. */
50
54
  canRevoke?: boolean;
55
+ /**
56
+ * Whether to render the public-link section. Defaults to `true`; pass `false`
57
+ * when the caller may not even LIST links (the host gates the list above
58
+ * them) but the dialog still has host `children` to show.
59
+ */
60
+ showLinks?: boolean;
61
+ /** Changing this value re-fetches the link list (e.g. another client changed it). */
62
+ refreshSignal?: number;
63
+ /** Host sections rendered below the links, inside the dialog. */
64
+ children?: ReactNode;
51
65
  onClose: () => void;
52
66
  onCreated?: (result: ShareLinkResult) => void;
53
67
  }): JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"ShareModal.d.ts","sourceRoot":"","sources":["../../src/components/ShareModal.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAMhC,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAI3E;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,EACzB,SAAS,EACT,WAAgC,EAChC,KAA4B,EAC5B,SAAgB,EAChB,SAAqB,EACrB,SAAqB,EACrB,OAAO,EACP,SAAS,GACV,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,SAAS,EAAE,CAAA;IAC5B;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAA;CAC9C,GAAG,GAAG,CAAC,OAAO,CA4Fd"}
1
+ {"version":3,"file":"ShareModal.d.ts","sourceRoot":"","sources":["../../src/components/ShareModal.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAM3C,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAI3E;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,EACzB,SAAS,EACT,WAAgC,EAChC,KAA4B,EAC5B,SAAgB,EAChB,SAAqB,EACrB,SAAqB,EACrB,SAAgB,EAChB,aAAa,EACb,QAAQ,EACR,OAAO,EACP,SAAS,GACV,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,SAAS,EAAE,CAAA;IAC5B;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAA;CAC9C,GAAG,GAAG,CAAC,OAAO,CAoGd"}
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect } from 'react';
3
3
  import { t } from '@molecule/app-i18n';
4
4
  import { getClassMap } from '@molecule/app-ui';
@@ -11,7 +11,7 @@ import { ShareLinkManager } from './ShareLinkManager.js';
11
11
  * @param props - Component props.
12
12
  * @returns The rendered share modal.
13
13
  */
14
- export function ShareModal({ projectId, initialRole = DEFAULT_SHARE_ROLE, roles = [DEFAULT_SHARE_ROLE], canManage = true, canCreate = canManage, canRevoke = canManage, onClose, onCreated, }) {
14
+ export function ShareModal({ projectId, initialRole = DEFAULT_SHARE_ROLE, roles = [DEFAULT_SHARE_ROLE], canManage = true, canCreate = canManage, canRevoke = canManage, showLinks = true, refreshSignal, children, onClose, onCreated, }) {
15
15
  const cm = getClassMap();
16
16
  // Escape closes the modal.
17
17
  useEffect(() => {
@@ -42,12 +42,12 @@ export function ShareModal({ projectId, initialRole = DEFAULT_SHARE_ROLE, roles
42
42
  borderRadius: 8,
43
43
  padding: 16,
44
44
  boxShadow: '0 10px 40px rgba(0,0,0,0.35)',
45
- }, children: [_jsx("div", { className: cm.cn(cm.fontWeight('medium'), cm.textSize('lg')), style: { marginBottom: 4 }, children: t('ide.chat.share.heading', undefined, { defaultValue: 'Share project' }) }), _jsx("div", { className: cm.textMuted, style: { marginBottom: 12, lineHeight: 1.4 }, children: offeredRoles.length > 1
46
- ? t('ide.chat.share.subheading', undefined, {
47
- defaultValue: 'Create a public link. Anyone with the link gets the role you choose — a viewer link is read-only.',
48
- })
49
- : t(`ide.chat.share.subheading.${offeredRoles[0]}`, { role: offeredRoles[0] }, {
50
- defaultValue: 'Create a public link. Anyone with the link can act as {{role}}.',
51
- }) }), _jsx(ShareLinkManager, { projectId: projectId, roles: offeredRoles, initialRole: initialRole, canManage: canManage, canCreate: canCreate, canRevoke: canRevoke, onCreated: onCreated }), _jsx("div", { style: { display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 16 }, children: _jsx("button", { type: "button", "data-mol-id": "share-close", onClick: onClose, className: cm.cn(cm.button({ variant: 'ghost', size: 'sm' }), cm.touchTargetCompact), children: t('common.done', undefined, { defaultValue: 'Done' }) }) })] }) }));
45
+ }, children: [_jsx("div", { className: cm.cn(cm.fontWeight('medium'), cm.textSize('lg')), style: { marginBottom: 4 }, children: t('ide.chat.share.heading', undefined, { defaultValue: 'Share project' }) }), showLinks && (_jsxs(_Fragment, { children: [_jsx("div", { className: cm.textMuted, style: { marginBottom: 12, lineHeight: 1.4 }, children: offeredRoles.length > 1
46
+ ? t('ide.chat.share.subheading', undefined, {
47
+ defaultValue: 'Create a public link. Anyone with the link gets the role you choose — a viewer link is read-only.',
48
+ })
49
+ : t(`ide.chat.share.subheading.${offeredRoles[0]}`, { role: offeredRoles[0] }, {
50
+ defaultValue: 'Create a public link. Anyone with the link can act as {{role}}.',
51
+ }) }), _jsx(ShareLinkManager, { projectId: projectId, roles: offeredRoles, initialRole: initialRole, canManage: canManage, canCreate: canCreate, canRevoke: canRevoke, onCreated: onCreated, refreshSignal: refreshSignal })] })), children, _jsx("div", { style: { display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 16 }, children: _jsx("button", { type: "button", "data-mol-id": "share-close", onClick: onClose, className: cm.cn(cm.button({ variant: 'ghost', size: 'sm' }), cm.touchTargetCompact), children: t('common.done', undefined, { defaultValue: 'Done' }) }) })] }) }));
52
52
  }
53
53
  //# sourceMappingURL=ShareModal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ShareModal.js","sourceRoot":"","sources":["../../src/components/ShareModal.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ShareModal.js","sourceRoot":"","sources":["../../src/components/ShareModal.tsx"],"names":[],"mappings":"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"}
@@ -8,12 +8,15 @@
8
8
  * commit-message generator) and `compactModel` (conversation compaction), which
9
9
  * fall back to the server's own fast default (never `chatModel`) when unset.
10
10
  * These helpers parse the mode flag, map a mode to its settings field, resolve
11
- * the effective model for a mode, and compute the free-tier clamp (plan →
12
- * `deepseek-v4-pro`, execute → `deepseek-v4-flash`, commit/compact → any
13
- * free-tier-flagged model) against the live catalog. The clamp ids mirror the
14
- * server's FREE_TIER_MODELS in molecule-dev's `model-selection.ts` — keep the
15
- * two in sync (a stale Sonnet-plan assumption here once highlighted the wrong
16
- * "current" model in the picker).
11
+ * the effective model for a mode, and compute the free-tier clamp.
12
+ *
13
+ * The clamp is entirely SERVER-DRIVEN — no model id is ever named here. A
14
+ * free/anon user may use, in any mode, a model the catalog flags `freeTier`,
15
+ * plus the server-sent per-mode default for that mode (`GET /ai/models`
16
+ * `defaults`, which the server resolves from its own free-tier policy). Two
17
+ * earlier generations of this file hardcoded the clamp ids (first a Sonnet
18
+ * planner, then `deepseek-v4-pro`); each went stale the moment the server's
19
+ * policy moved and the picker advertised a model the server would not use.
17
20
  *
18
21
  * Everything here is deterministic and side-effect free so it can be unit tested
19
22
  * without rendering or a backend. The component owns persistence (`PATCH
@@ -21,9 +24,15 @@
21
24
  *
22
25
  * @module
23
26
  */
24
- import type { AppModelDefinition } from '@molecule/app-ai-models';
27
+ import type { AppModelDefinition, AppModeModelDefaults } from '@molecule/app-ai-models';
25
28
  /** A conversation mode or auxiliary job that can have its own model. */
26
29
  export type ModelMode = 'plan' | 'execute' | 'commit' | 'compact';
30
+ /**
31
+ * The server-sent per-mode defaults (`GET /ai/models` `defaults`) — the
32
+ * server's own resolution of what each mode uses for this requester's tier.
33
+ * Partial/absent while the catalog is loading or on servers that don't send it.
34
+ */
35
+ export type ServerModeDefaults = Partial<AppModeModelDefaults> | undefined;
27
36
  /** The subset of project settings this module reads for model resolution. */
28
37
  export interface PerModeModelSettings {
29
38
  /** Model id used in plan mode (falls back to {@link PerModeModelSettings.chatModel}). */
@@ -71,20 +80,18 @@ export declare function modeSettingKey(mode: ModelMode): 'planModel' | 'executeM
71
80
  */
72
81
  export declare function resolveModeModel(settings: PerModeModelSettings, mode: ModelMode): string | undefined;
73
82
  /**
74
- * Computes the free-tier-allowed model id for a mode from the live catalog. The
75
- * free/anon tier is clamped — with no mixing — to `deepseek-v4-pro` in plan
76
- * mode and `deepseek-v4-flash` in execute mode (the auxiliary commit/compact
77
- * jobs share the execute clamp), mirroring the server's FREE_TIER_MODELS.
78
- * Matching is catalog-driven (by id/provider) so it survives id churn; when no
79
- * specific match exists it falls back to the supplied `fallback` (the
80
- * catalog's free-tier model id).
83
+ * The model a free/anon user gets in a mode when nothing else applies: the
84
+ * server-sent default for that mode, else the catalog's `freeTier`-flagged
85
+ * model, else the supplied `fallback`. Never names a model id — the server's
86
+ * free-tier policy (and the catalog flag it publishes) is the only source.
81
87
  *
82
88
  * @param models - The available models from the catalog.
83
89
  * @param mode - The conversation mode or auxiliary job.
84
- * @param fallback - The free-tier model id to use when no match is found.
85
- * @returns The clamped model id for the mode.
90
+ * @param fallback - The free-tier model id to use when neither source has one.
91
+ * @param serverDefaults - Server-sent per-mode defaults (`GET /ai/models`).
92
+ * @returns The free-tier model id for the mode.
86
93
  */
87
- export declare function freeTierModeModelId(models: readonly AppModelDefinition[], mode: ModelMode, fallback: string): string;
94
+ export declare function freeTierModeModelId(models: readonly AppModelDefinition[], mode: ModelMode, fallback: string, serverDefaults?: ServerModeDefaults): string;
88
95
  /**
89
96
  * The model id that will ACTUALLY serve a conversation mode, for display.
90
97
  *
@@ -92,81 +99,71 @@ export declare function freeTierModeModelId(models: readonly AppModelDefinition[
92
99
  * per-request override, which the UI never has): the project's per-mode model,
93
100
  * then the project's SAVED legacy `chatModel`, each skipped when the free-tier
94
101
  * clamp would reject it — then the server-sent per-mode default (which already
95
- * folds in the owner's account-level settings and tier), then the catalog
96
- * clamp as the last resort.
102
+ * folds in the owner's account-level settings and tier), then the catalog's
103
+ * free-tier model as the last resort.
97
104
  *
98
105
  * `settings.chatModel` must be the PERSISTED value only — never a UI-seeded
99
- * default. Seeding the catalog's single free-tier model (the executor) as
100
- * "current" is exactly the bug this exists to fix: every plan-mode surface
101
- * then labeled the planner as the executor model while the server planned
102
- * with its own plan default (observed on prod 2026-08-13 — the UI said
103
- * "DeepSeek V4 Flash" for a plan turn that DeepSeek V4 Pro served).
106
+ * default. Seeding the catalog's free-tier model as "current" once made every
107
+ * plan-mode surface label the wrong model while the server planned with its
108
+ * own plan default.
104
109
  *
105
110
  * @param mode - The conversation mode to resolve.
106
111
  * @param settings - Persisted per-mode + legacy model settings (saved only).
107
112
  * @param serverDefaults - Server-sent per-mode defaults (`GET /ai/models`).
108
113
  * @param isFreeTier - Whether the current user is on the free/anon tier.
109
114
  * @param models - The available models from the catalog.
110
- * @param fallback - The free-tier model id to use when no clamp match exists.
115
+ * @param fallback - The free-tier model id to use when no other source exists.
111
116
  * @returns The model id the mode resolves to.
112
117
  */
113
- export declare function effectiveModeModelId(mode: 'plan' | 'execute', settings: PerModeModelSettings, serverDefaults: {
114
- plan?: string;
115
- execute?: string;
116
- } | undefined, isFreeTier: boolean, models: readonly AppModelDefinition[], fallback: string): string;
118
+ export declare function effectiveModeModelId(mode: 'plan' | 'execute', settings: PerModeModelSettings, serverDefaults: ServerModeDefaults, isFreeTier: boolean, models: readonly AppModelDefinition[], fallback: string): string;
117
119
  /**
118
120
  * Why a model is locked for a free-tier user in a given mode — `'paid'` for a
119
121
  * genuinely paid model, `'mode'` for a model the free tier CAN use, just in a
120
- * different mode (e.g. the execute clamp shown in the plan-scoped picker).
122
+ * different mode (e.g. another mode's server default shown in this picker).
121
123
  */
122
124
  export type FreeTierLockReason = 'paid' | 'mode';
123
125
  /**
124
126
  * The lock reason for a model in a mode under the free-tier clamp, or `null`
125
127
  * when it is selectable. Pro users and `provider: 'custom'` (bring-your-own
126
- * AI) models are never locked; a free/anon user may pick only the mode's
127
- * clamped model (plan/execute) or any free-tier-flagged model (the auxiliary
128
- * commit/compact jobs, mirroring the server's aux-model selection, which
129
- * ignores a non-free platform pick anyway).
128
+ * AI) models are never locked; a free/anon user may pick a `freeTier`-flagged
129
+ * model in any mode, or the server-sent default for the scoped mode.
130
130
  *
131
131
  * A locked model splits into two very different cases the UI must not
132
132
  * conflate: `'paid'` (upgrade actually unlocks it) versus `'mode'` (the model
133
- * is free-tier-usable in ANOTHER mode — it is a different mode's clamp, or
134
- * free-tier-flagged and thus selectable for commit/compact — so a "Pro" badge
135
- * would be flatly wrong).
133
+ * is free-tier-usable in ANOTHER mode, so a "Pro" badge would be flatly wrong).
136
134
  *
137
135
  * @param modelId - The candidate model id.
138
136
  * @param mode - The conversation mode the picker is scoped to.
139
137
  * @param isFreeTier - Whether the current user is on the free/anon tier.
140
138
  * @param models - The available models from the catalog.
141
- * @param fallback - The free-tier model id to use when no clamp match is found.
139
+ * @param serverDefaults - Server-sent per-mode defaults (`GET /ai/models`).
142
140
  * @returns `'paid'` / `'mode'` when locked, `null` when selectable.
143
141
  */
144
- export declare function freeTierLockReason(modelId: string, mode: ModelMode, isFreeTier: boolean, models: readonly AppModelDefinition[], fallback: string): FreeTierLockReason | null;
142
+ export declare function freeTierLockReason(modelId: string, mode: ModelMode, isFreeTier: boolean, models: readonly AppModelDefinition[], serverDefaults?: ServerModeDefaults): FreeTierLockReason | null;
145
143
  /**
146
144
  * The mode a free-tier user can actually use this model in — `'plan'` /
147
- * `'execute'` when it is that mode's clamp, `'commit'` (standing for both
148
- * auxiliary jobs) when it is merely free-tier-flagged, `null` when the free
145
+ * `'execute'` when the free tier allows it there, `'commit'` (standing for
146
+ * both auxiliary jobs) when only an aux job allows it, `null` when the free
149
147
  * tier can't use it anywhere. Drives the "free in <mode>" labeling next to a
150
148
  * `'mode'`-locked row.
151
149
  *
152
150
  * @param modelId - The candidate model id.
153
151
  * @param models - The available models from the catalog.
154
- * @param fallback - The free-tier model id to use when no clamp match is found.
152
+ * @param serverDefaults - Server-sent per-mode defaults (`GET /ai/models`).
155
153
  * @returns The mode the model is free-tier-usable in, or `null`.
156
154
  */
157
- export declare function freeTierUsableMode(modelId: string, models: readonly AppModelDefinition[], fallback: string): ModelMode | null;
155
+ export declare function freeTierUsableMode(modelId: string, models: readonly AppModelDefinition[], serverDefaults?: ServerModeDefaults): ModelMode | null;
158
156
  /**
159
157
  * Whether a model is locked (not selectable) for the given mode under the
160
158
  * free-tier clamp — the boolean view of {@link freeTierLockReason} (which see
161
- * for the rules: pro users and custom models never lock; plan/execute clamp to
162
- * one model; commit/compact accept any free-tier-flagged model).
159
+ * for the rules).
163
160
  *
164
161
  * @param modelId - The candidate model id.
165
162
  * @param mode - The conversation mode the picker is scoped to.
166
163
  * @param isFreeTier - Whether the current user is on the free/anon tier.
167
164
  * @param models - The available models from the catalog.
168
- * @param fallback - The free-tier model id to use when no clamp match is found.
165
+ * @param serverDefaults - Server-sent per-mode defaults (`GET /ai/models`).
169
166
  * @returns `true` when the model is locked for this user and mode.
170
167
  */
171
- export declare function isModeModelLocked(modelId: string, mode: ModelMode, isFreeTier: boolean, models: readonly AppModelDefinition[], fallback: string): boolean;
168
+ export declare function isModeModelLocked(modelId: string, mode: ModelMode, isFreeTier: boolean, models: readonly AppModelDefinition[], serverDefaults?: ServerModeDefaults): boolean;
172
169
  //# sourceMappingURL=chat-model-mode-utilities.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-model-mode-utilities.d.ts","sourceRoot":"","sources":["../../src/components/chat-model-mode-utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAEjE,wEAAwE;AACxE,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAA;AAEjE,6EAA6E;AAC7E,MAAM,WAAW,oBAAoB;IACnC,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4FAA4F;IAC5F,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAI9F;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS,GACd,WAAW,GAAG,cAAc,GAAG,aAAa,GAAG,cAAc,CAW/D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,oBAAoB,EAC9B,IAAI,EAAE,SAAS,GACd,MAAM,GAAG,SAAS,CAWpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,MAAM,GACf,MAAM,CAgBR;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,QAAQ,EAAE,oBAAoB,EAC9B,cAAc,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EAC/D,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,QAAQ,EAAE,MAAM,GACf,MAAM,CAcR;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,CAAA;AAKhD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,QAAQ,EAAE,MAAM,GACf,kBAAkB,GAAG,IAAI,CAe3B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,QAAQ,EAAE,MAAM,GACf,SAAS,GAAG,IAAI,CAKlB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,QAAQ,EAAE,MAAM,GACf,OAAO,CAET"}
1
+ {"version":3,"file":"chat-model-mode-utilities.d.ts","sourceRoot":"","sources":["../../src/components/chat-model-mode-utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAEvF,wEAAwE;AACxE,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAA;AAEjE;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,oBAAoB,CAAC,GAAG,SAAS,CAAA;AAE1E,6EAA6E;AAC7E,MAAM,WAAW,oBAAoB;IACnC,yFAAyF;IACzF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4FAA4F;IAC5F,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAI9F;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS,GACd,WAAW,GAAG,cAAc,GAAG,aAAa,GAAG,cAAc,CAW/D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,oBAAoB,EAC9B,IAAI,EAAE,SAAS,GACd,MAAM,GAAG,SAAS,CAWpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,MAAM,EAChB,cAAc,CAAC,EAAE,kBAAkB,GAClC,MAAM,CAER;AAuBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,QAAQ,EAAE,oBAAoB,EAC9B,cAAc,EAAE,kBAAkB,EAClC,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,QAAQ,EAAE,MAAM,GACf,MAAM,CAcR;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,CAAA;AAKhD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,cAAc,CAAC,EAAE,kBAAkB,GAClC,kBAAkB,GAAG,IAAI,CAS3B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,cAAc,CAAC,EAAE,kBAAkB,GAClC,SAAS,GAAG,IAAI,CAWlB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,cAAc,CAAC,EAAE,kBAAkB,GAClC,OAAO,CAET"}
@@ -8,12 +8,15 @@
8
8
  * commit-message generator) and `compactModel` (conversation compaction), which
9
9
  * fall back to the server's own fast default (never `chatModel`) when unset.
10
10
  * These helpers parse the mode flag, map a mode to its settings field, resolve
11
- * the effective model for a mode, and compute the free-tier clamp (plan →
12
- * `deepseek-v4-pro`, execute → `deepseek-v4-flash`, commit/compact → any
13
- * free-tier-flagged model) against the live catalog. The clamp ids mirror the
14
- * server's FREE_TIER_MODELS in molecule-dev's `model-selection.ts` — keep the
15
- * two in sync (a stale Sonnet-plan assumption here once highlighted the wrong
16
- * "current" model in the picker).
11
+ * the effective model for a mode, and compute the free-tier clamp.
12
+ *
13
+ * The clamp is entirely SERVER-DRIVEN — no model id is ever named here. A
14
+ * free/anon user may use, in any mode, a model the catalog flags `freeTier`,
15
+ * plus the server-sent per-mode default for that mode (`GET /ai/models`
16
+ * `defaults`, which the server resolves from its own free-tier policy). Two
17
+ * earlier generations of this file hardcoded the clamp ids (first a Sonnet
18
+ * planner, then `deepseek-v4-pro`); each went stale the moment the server's
19
+ * policy moved and the picker advertised a model the server would not use.
17
20
  *
18
21
  * Everything here is deterministic and side-effect free so it can be unit tested
19
22
  * without rendering or a backend. The component owns persistence (`PATCH
@@ -79,39 +82,34 @@ export function resolveModeModel(settings, mode) {
79
82
  }
80
83
  }
81
84
  /**
82
- * Computes the free-tier-allowed model id for a mode from the live catalog. The
83
- * free/anon tier is clamped — with no mixing — to `deepseek-v4-pro` in plan
84
- * mode and `deepseek-v4-flash` in execute mode (the auxiliary commit/compact
85
- * jobs share the execute clamp), mirroring the server's FREE_TIER_MODELS.
86
- * Matching is catalog-driven (by id/provider) so it survives id churn; when no
87
- * specific match exists it falls back to the supplied `fallback` (the
88
- * catalog's free-tier model id).
85
+ * The model a free/anon user gets in a mode when nothing else applies: the
86
+ * server-sent default for that mode, else the catalog's `freeTier`-flagged
87
+ * model, else the supplied `fallback`. Never names a model id — the server's
88
+ * free-tier policy (and the catalog flag it publishes) is the only source.
89
89
  *
90
90
  * @param models - The available models from the catalog.
91
91
  * @param mode - The conversation mode or auxiliary job.
92
- * @param fallback - The free-tier model id to use when no match is found.
93
- * @returns The clamped model id for the mode.
92
+ * @param fallback - The free-tier model id to use when neither source has one.
93
+ * @param serverDefaults - Server-sent per-mode defaults (`GET /ai/models`).
94
+ * @returns The free-tier model id for the mode.
94
95
  */
95
- export function freeTierModeModelId(models, mode, fallback) {
96
- if (mode === 'plan') {
97
- const exact = models.find((m) => m.id === 'deepseek-v4-pro');
98
- if (exact)
99
- return exact.id;
100
- const deepseekPro = models.find((m) => m.provider === 'deepseek' && /pro/i.test(m.id));
101
- if (deepseekPro)
102
- return deepseekPro.id;
103
- const anyDeepseek = models.find((m) => m.provider === 'deepseek');
104
- return anyDeepseek?.id ?? fallback;
105
- }
106
- // execute (and the commit/compact auxiliary jobs, which share its clamp)
107
- const exact = models.find((m) => m.id === 'deepseek-v4-flash');
108
- if (exact)
109
- return exact.id;
110
- const deepseekFlash = models.find((m) => m.provider === 'deepseek' && /flash/i.test(m.id));
111
- if (deepseekFlash)
112
- return deepseekFlash.id;
113
- const anyDeepseek = models.find((m) => m.provider === 'deepseek');
114
- return anyDeepseek?.id ?? fallback;
96
+ export function freeTierModeModelId(models, mode, fallback, serverDefaults) {
97
+ return serverDefaults?.[mode] || models.find((m) => m.freeTier === true)?.id || fallback;
98
+ }
99
+ /**
100
+ * Whether a free/anon user may use a (non-custom) model in a mode: the catalog
101
+ * flags it `freeTier` (free in every mode, as the server's `freeTierAllows`
102
+ * treats it), or it is the server-sent default for that very mode (the server
103
+ * only sends a free user defaults it would itself dispatch to).
104
+ *
105
+ * @param model - The candidate's catalog entry (undefined when unknown).
106
+ * @param modelId - The candidate model id.
107
+ * @param mode - The conversation mode or auxiliary job.
108
+ * @param serverDefaults - Server-sent per-mode defaults (`GET /ai/models`).
109
+ * @returns `true` when the free tier may use the model in that mode.
110
+ */
111
+ function freeTierAllowsIn(model, modelId, mode, serverDefaults) {
112
+ return model?.freeTier === true || (!!serverDefaults?.[mode] && serverDefaults[mode] === modelId);
115
113
  }
116
114
  /**
117
115
  * The model id that will ACTUALLY serve a conversation mode, for display.
@@ -120,22 +118,20 @@ export function freeTierModeModelId(models, mode, fallback) {
120
118
  * per-request override, which the UI never has): the project's per-mode model,
121
119
  * then the project's SAVED legacy `chatModel`, each skipped when the free-tier
122
120
  * clamp would reject it — then the server-sent per-mode default (which already
123
- * folds in the owner's account-level settings and tier), then the catalog
124
- * clamp as the last resort.
121
+ * folds in the owner's account-level settings and tier), then the catalog's
122
+ * free-tier model as the last resort.
125
123
  *
126
124
  * `settings.chatModel` must be the PERSISTED value only — never a UI-seeded
127
- * default. Seeding the catalog's single free-tier model (the executor) as
128
- * "current" is exactly the bug this exists to fix: every plan-mode surface
129
- * then labeled the planner as the executor model while the server planned
130
- * with its own plan default (observed on prod 2026-08-13 — the UI said
131
- * "DeepSeek V4 Flash" for a plan turn that DeepSeek V4 Pro served).
125
+ * default. Seeding the catalog's free-tier model as "current" once made every
126
+ * plan-mode surface label the wrong model while the server planned with its
127
+ * own plan default.
132
128
  *
133
129
  * @param mode - The conversation mode to resolve.
134
130
  * @param settings - Persisted per-mode + legacy model settings (saved only).
135
131
  * @param serverDefaults - Server-sent per-mode defaults (`GET /ai/models`).
136
132
  * @param isFreeTier - Whether the current user is on the free/anon tier.
137
133
  * @param models - The available models from the catalog.
138
- * @param fallback - The free-tier model id to use when no clamp match exists.
134
+ * @param fallback - The free-tier model id to use when no other source exists.
139
135
  * @returns The model id the mode resolves to.
140
136
  */
141
137
  export function effectiveModeModelId(mode, settings, serverDefaults, isFreeTier, models, fallback) {
@@ -147,85 +143,79 @@ export function effectiveModeModelId(mode, settings, serverDefaults, isFreeTier,
147
143
  continue;
148
144
  // Mirror the server: a candidate the free-tier clamp rejects falls
149
145
  // through to the next, it does not stick as the label.
150
- if (freeTierLockReason(candidate, mode, isFreeTier, models, fallback) === null) {
146
+ if (freeTierLockReason(candidate, mode, isFreeTier, models, serverDefaults) === null) {
151
147
  return candidate;
152
148
  }
153
149
  }
154
- return serverDefaults?.[mode] ?? freeTierModeModelId(models, mode, fallback);
150
+ return freeTierModeModelId(models, mode, fallback, serverDefaults);
155
151
  }
156
152
  /** Every mode a per-mode clamp exists for — used to test "free elsewhere". */
157
153
  const MODEL_MODES = ['plan', 'execute', 'commit', 'compact'];
158
154
  /**
159
155
  * The lock reason for a model in a mode under the free-tier clamp, or `null`
160
156
  * when it is selectable. Pro users and `provider: 'custom'` (bring-your-own
161
- * AI) models are never locked; a free/anon user may pick only the mode's
162
- * clamped model (plan/execute) or any free-tier-flagged model (the auxiliary
163
- * commit/compact jobs, mirroring the server's aux-model selection, which
164
- * ignores a non-free platform pick anyway).
157
+ * AI) models are never locked; a free/anon user may pick a `freeTier`-flagged
158
+ * model in any mode, or the server-sent default for the scoped mode.
165
159
  *
166
160
  * A locked model splits into two very different cases the UI must not
167
161
  * conflate: `'paid'` (upgrade actually unlocks it) versus `'mode'` (the model
168
- * is free-tier-usable in ANOTHER mode — it is a different mode's clamp, or
169
- * free-tier-flagged and thus selectable for commit/compact — so a "Pro" badge
170
- * would be flatly wrong).
162
+ * is free-tier-usable in ANOTHER mode, so a "Pro" badge would be flatly wrong).
171
163
  *
172
164
  * @param modelId - The candidate model id.
173
165
  * @param mode - The conversation mode the picker is scoped to.
174
166
  * @param isFreeTier - Whether the current user is on the free/anon tier.
175
167
  * @param models - The available models from the catalog.
176
- * @param fallback - The free-tier model id to use when no clamp match is found.
168
+ * @param serverDefaults - Server-sent per-mode defaults (`GET /ai/models`).
177
169
  * @returns `'paid'` / `'mode'` when locked, `null` when selectable.
178
170
  */
179
- export function freeTierLockReason(modelId, mode, isFreeTier, models, fallback) {
171
+ export function freeTierLockReason(modelId, mode, isFreeTier, models, serverDefaults) {
180
172
  if (!isFreeTier)
181
173
  return null;
182
174
  const candidate = models.find((m) => m.id === modelId);
183
175
  if (candidate?.provider === 'custom')
184
176
  return null;
185
- const allowedHere = mode === 'commit' || mode === 'compact'
186
- ? candidate?.freeTier === true
187
- : modelId === freeTierModeModelId(models, mode, fallback);
188
- if (allowedHere)
177
+ if (freeTierAllowsIn(candidate, modelId, mode, serverDefaults))
189
178
  return null;
190
- const freeElsewhere = candidate?.freeTier === true ||
191
- MODEL_MODES.some((other) => other !== mode && modelId === freeTierModeModelId(models, other, fallback));
179
+ const freeElsewhere = MODEL_MODES.some((other) => other !== mode && freeTierAllowsIn(candidate, modelId, other, serverDefaults));
192
180
  return freeElsewhere ? 'mode' : 'paid';
193
181
  }
194
182
  /**
195
183
  * The mode a free-tier user can actually use this model in — `'plan'` /
196
- * `'execute'` when it is that mode's clamp, `'commit'` (standing for both
197
- * auxiliary jobs) when it is merely free-tier-flagged, `null` when the free
184
+ * `'execute'` when the free tier allows it there, `'commit'` (standing for
185
+ * both auxiliary jobs) when only an aux job allows it, `null` when the free
198
186
  * tier can't use it anywhere. Drives the "free in <mode>" labeling next to a
199
187
  * `'mode'`-locked row.
200
188
  *
201
189
  * @param modelId - The candidate model id.
202
190
  * @param models - The available models from the catalog.
203
- * @param fallback - The free-tier model id to use when no clamp match is found.
191
+ * @param serverDefaults - Server-sent per-mode defaults (`GET /ai/models`).
204
192
  * @returns The mode the model is free-tier-usable in, or `null`.
205
193
  */
206
- export function freeTierUsableMode(modelId, models, fallback) {
207
- if (modelId === freeTierModeModelId(models, 'plan', fallback))
194
+ export function freeTierUsableMode(modelId, models, serverDefaults) {
195
+ const candidate = models.find((m) => m.id === modelId);
196
+ if (freeTierAllowsIn(candidate, modelId, 'plan', serverDefaults))
208
197
  return 'plan';
209
- if (modelId === freeTierModeModelId(models, 'execute', fallback))
198
+ if (freeTierAllowsIn(candidate, modelId, 'execute', serverDefaults))
210
199
  return 'execute';
211
- if (models.find((m) => m.id === modelId)?.freeTier === true)
200
+ if (freeTierAllowsIn(candidate, modelId, 'commit', serverDefaults) ||
201
+ freeTierAllowsIn(candidate, modelId, 'compact', serverDefaults)) {
212
202
  return 'commit';
203
+ }
213
204
  return null;
214
205
  }
215
206
  /**
216
207
  * Whether a model is locked (not selectable) for the given mode under the
217
208
  * free-tier clamp — the boolean view of {@link freeTierLockReason} (which see
218
- * for the rules: pro users and custom models never lock; plan/execute clamp to
219
- * one model; commit/compact accept any free-tier-flagged model).
209
+ * for the rules).
220
210
  *
221
211
  * @param modelId - The candidate model id.
222
212
  * @param mode - The conversation mode the picker is scoped to.
223
213
  * @param isFreeTier - Whether the current user is on the free/anon tier.
224
214
  * @param models - The available models from the catalog.
225
- * @param fallback - The free-tier model id to use when no clamp match is found.
215
+ * @param serverDefaults - Server-sent per-mode defaults (`GET /ai/models`).
226
216
  * @returns `true` when the model is locked for this user and mode.
227
217
  */
228
- export function isModeModelLocked(modelId, mode, isFreeTier, models, fallback) {
229
- return freeTierLockReason(modelId, mode, isFreeTier, models, fallback) !== null;
218
+ export function isModeModelLocked(modelId, mode, isFreeTier, models, serverDefaults) {
219
+ return freeTierLockReason(modelId, mode, isFreeTier, models, serverDefaults) !== null;
230
220
  }
231
221
  //# sourceMappingURL=chat-model-mode-utilities.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-model-mode-utilities.js","sourceRoot":"","sources":["../../src/components/chat-model-mode-utilities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat-model-mode-utilities.js","sourceRoot":"","sources":["../../src/components/chat-model-mode-utilities.ts"],"names":[],"mappings":"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"}
@@ -118,7 +118,7 @@ export const SETTINGS = [
118
118
  {
119
119
  id: 'autoApproveCommands',
120
120
  label: 'Auto-approve commands',
121
- description: "Skip the 'Proceed?' confirmation before {{agentName}} runs a bulk/destructive command (a hard reset, a recursive delete, an in-place edit). The network-exfiltration guard still asks before sending data off the box.",
121
+ description: "Skip the 'Proceed?' confirmation before {{agentName}} runs a bulk/destructive command (a hard reset, a recursive delete, an in-place edit). Network access still follows the project's allowlist unless Full access is on.",
122
122
  editCommand: 'autoapprove',
123
123
  },
124
124
  {
@@ -1 +1 @@
1
- {"version":3,"file":"settings-metadata.js","sourceRoot":"","sources":["../src/settings-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAA;AA+CvF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,QAAQ,GAA2B;IAC9C;QACE,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,oEAAoE;QACjF,WAAW,EAAE,OAAO;KACrB;IACD;QACE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,0EAA0E;QACvF,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,eAAe;KAC3B;IACD;QACE,EAAE,EAAE,cAAc;QAClB,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EAAE,6EAA6E;QAC1F,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,kBAAkB;KAC9B;IACD;QACE,EAAE,EAAE,aAAa;QACjB,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,iFAAiF;QAC9F,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,iBAAiB;KAC7B;IACD;QACE,EAAE,EAAE,cAAc;QAClB,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,kIAAkI;QACpI,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,kBAAkB;KAC9B;IACD;QACE,EAAE,EAAE,MAAM;QACV,KAAK,EAAE,MAAM;QACb,WAAW,EACT,oFAAoF;QACtF,WAAW,EAAE,MAAM;KACpB;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,yIAAyI;QAC3I,WAAW,EAAE,QAAQ;KACtB;IACD;QACE,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,wFAAwF;QAC1F,WAAW,EAAE,UAAU;KACxB;IACD;QACE,EAAE,EAAE,SAAS;QACb,KAAK,EAAE,UAAU;QACjB,WAAW,EACT,kGAAkG;QACpG,WAAW,EAAE,SAAS;KACvB;IACD;QACE,EAAE,EAAE,YAAY;QAChB,KAAK,EAAE,aAAa;QACpB,WAAW,EAAE,sGAAsG,2BAA2B,+LAA+L;QAC7U,WAAW,EAAE,YAAY;KAC1B;IACD;QACE,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,OAAO;QACd,WAAW,EACT,0MAA0M;KAC7M;IACD;QACE,EAAE,EAAE,qBAAqB;QACzB,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACT,wNAAwN;QAC1N,WAAW,EAAE,aAAa;KAC3B;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,8EAA8E;QAC3F,WAAW,EAAE,QAAQ;KACtB;IACD;QACE,EAAE,EAAE,YAAY;QAChB,KAAK,EAAE,YAAY;QACnB,WAAW,EACT,wIAAwI;QAC1I,WAAW,EAAE,YAAY;KAC1B;CACO,CAAA"}
1
+ {"version":3,"file":"settings-metadata.js","sourceRoot":"","sources":["../src/settings-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAA;AA+CvF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,QAAQ,GAA2B;IAC9C;QACE,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,oEAAoE;QACjF,WAAW,EAAE,OAAO;KACrB;IACD;QACE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,0EAA0E;QACvF,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,eAAe;KAC3B;IACD;QACE,EAAE,EAAE,cAAc;QAClB,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EAAE,6EAA6E;QAC1F,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,kBAAkB;KAC9B;IACD;QACE,EAAE,EAAE,aAAa;QACjB,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,iFAAiF;QAC9F,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,iBAAiB;KAC7B;IACD;QACE,EAAE,EAAE,cAAc;QAClB,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,kIAAkI;QACpI,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,kBAAkB;KAC9B;IACD;QACE,EAAE,EAAE,MAAM;QACV,KAAK,EAAE,MAAM;QACb,WAAW,EACT,oFAAoF;QACtF,WAAW,EAAE,MAAM;KACpB;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,yIAAyI;QAC3I,WAAW,EAAE,QAAQ;KACtB;IACD;QACE,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,wFAAwF;QAC1F,WAAW,EAAE,UAAU;KACxB;IACD;QACE,EAAE,EAAE,SAAS;QACb,KAAK,EAAE,UAAU;QACjB,WAAW,EACT,kGAAkG;QACpG,WAAW,EAAE,SAAS;KACvB;IACD;QACE,EAAE,EAAE,YAAY;QAChB,KAAK,EAAE,aAAa;QACpB,WAAW,EAAE,sGAAsG,2BAA2B,+LAA+L;QAC7U,WAAW,EAAE,YAAY;KAC1B;IACD;QACE,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,OAAO;QACd,WAAW,EACT,0MAA0M;KAC7M;IACD;QACE,EAAE,EAAE,qBAAqB;QACzB,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACT,4NAA4N;QAC9N,WAAW,EAAE,aAAa;KAC3B;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,8EAA8E;QAC3F,WAAW,EAAE,QAAQ;KACtB;IACD;QACE,EAAE,EAAE,YAAY;QAChB,KAAK,EAAE,YAAY;QACnB,WAAW,EACT,wIAAwI;QAC1I,WAAW,EAAE,YAAY;KAC1B;CACO,CAAA"}
package/dist/types.d.ts CHANGED
@@ -384,6 +384,17 @@ export interface ChatPanelProps {
384
384
  * false` (back-compat: hosts that gate the modal themselves see no change).
385
385
  */
386
386
  canShare?: boolean;
387
+ /**
388
+ * Whether the share dialog shows the public-link section. Defaults to
389
+ * {@link canShare}. Set it below `canShare` when a host lets more roles open
390
+ * the dialog (for {@link shareModalContent}) than may list links — the links
391
+ * section is then hidden instead of 403ing.
392
+ */
393
+ shareLinksAllowed?: boolean;
394
+ /** Changing this value re-fetches the share dialog's link list (another client changed the links). */
395
+ shareLinksRefreshSignal?: number;
396
+ /** Host sections rendered inside the share dialog, below the links. */
397
+ shareModalContent?: ReactNode;
387
398
  /** Spinner/busy indicator node to show for in-chat loading states (e.g. the "designing" indicator). Falls back to a built-in dots animation. */
388
399
  spinner?: ReactNode;
389
400
  /** Path of the currently focused file in the editor (shown first in @ picker). */