import { AssistantModeConfig } from './conversation'; import { AssistantTr } from './i18n'; import { AssistantMode } from './types'; /** * The single flag this module replaces, as it sits in storage written by * fe-libs 2026.919.1 and earlier. */ export declare const LEGACY_WRITE_CONSENT_KEY = "apiCallsAcknowledged"; /** * The write-capable modes this profile has accepted, read back from storage. * * - A stored list is kept, minus anything that is not a mode id and any repeat. * Storage is data from another build, so it is checked, not trusted. * - Otherwise a stored legacy flag of exactly `true` becomes `["api-calls"]`. * - Otherwise nothing is acknowledged. * * ★ A stored list WINS over the legacy flag, and is never merged with it. This * build never writes the flag, and an older build drops the list the next time * it persists (its `partialize` does not know the key), so the two are not * stored side by side by either. Should they ever be, the list is the newer * decision. After a rollback and a roll-forward, the flag the older build wrote * is migrated again, exactly as on first upgrade. */ export declare function restoreAcknowledgedWriteModes(persisted: unknown): AssistantMode[]; /** Has this profile accepted the write consent for `mode`? */ export declare function isWriteModeAcknowledged(acknowledged: readonly AssistantMode[], mode: AssistantMode): boolean; /** Send-time consent and voice checks against the validated post-wait mode. */ export declare function writeModeSendRefusal(mode: AssistantMode, config: Pick | undefined, acknowledged: readonly AssistantMode[], { dictated, confirmsWrites }: { dictated: boolean; confirmsWrites: boolean; }): string | null; /** `acknowledged` plus `mode`, unchanged (same array) if it is already there. */ export declare function withWriteModeAcknowledged(acknowledged: readonly AssistantMode[], mode: AssistantMode): readonly AssistantMode[]; /** A mode as the dialog needs it: the product's config, or just an id. */ export type WriteConsentMode = Pick & Partial>; /** Every line of the dialog, already translated. */ export interface WriteModeConsentCopy { title: string; body: string; /** Whether the assistant stops for approval before a change — true or false, said plainly. */ safeguard: string; confirm: string; cancel: string; } /** * fe-libs' own English for the `apiCalls.consent*` keys — the exact strings the * `tr()` calls in `writeModeConsentCopy` pass as their fallbacks. * * ★ Written out twice ON PURPOSE. `i18nManifest.test.ts` reads the fallback * ARGUMENT of every `tr()` call with the TypeScript parser, so a call site that * passed this table's value instead of a literal would drop out of the manifest * — and a key missing from the manifest is a key no product seeds, which is how * a string silently goes English in every locale. That test pins each call site * to the manifest, and `writeModeConsent.test.ts` pins this table to the * manifest too, so the three cannot drift apart without CI failing. */ export declare const TAKE_ACTION_ENGLISH: { readonly "apiCalls.consentTitle": "Switch to Take action mode?"; readonly "apiCalls.consentBody": "In Take action mode the assistant can read AND change your data — creating records, logging activity, updating details, and more, on your behalf."; readonly "apiCalls.consentConfirm": "Enable Take action"; readonly "apiCalls.consentCancel": "Stay in Ask"; }; /** A consent key whose English fe-libs writes itself. */ export type TakeActionConsentKey = keyof typeof TAKE_ACTION_ENGLISH; /** * What the consent dialog says when switching from `current` into `target`. * * ★★ A PRODUCT'S OWN WORDS ALWAYS WIN. `apiCalls.consent*` predate per-mode * wording, and products have seeded them: FluidGrids authored all five in six * languages FOR ITS OWN NAME for `api-calls` ("In Workflow mode … your * FluidGrids data"), HealthyBowl's body names "your HealthyBowl data". So for * `api-calls` those keys are asked FIRST, and whatever comes back that is not * fe-libs' own English is what renders — in the reader's language, byte for * byte as before this change. * * ★★ `writeConsent.*` renders only where there is no product copy to lose: a * mode that is not `api-calls` (a build mode has no seeded consent copy at all), * or an `api-calls` whose dictionary gave our own sentence back. It says the * same thing through `{{mode}}`, which names the mode as its pill does — so a * product that calls `api-calls` "Build" stops being told "Take action" without * any product's translation turning English. * * ★ The cancel button keeps `apiCalls.consentCancel` ("Stay in Ask") only when * the mode being LEFT is the one called Ask — that sentence is about `current`, * not `target`. Leaving Build names Build. * * ★★ `confirmsWrites` decides the safeguard line, and the caller must derive it * from what the SANDBOX does (`modeRequiresConfirmWrites`), never from a product * flag. The old dialog promised a confirmation step for every write-capable * mode; only `api-calls` boots with AI_ASSISTANT_CONFIRM_WRITES, so for any * other mode that promise was false. It now says the opposite, plainly. */ export declare function writeModeConsentCopy(tr: AssistantTr, { target, current, confirmsWrites, }: { target: WriteConsentMode; /** The mode being left; absent is read as Ask, the mode everyone starts in. */ current?: WriteConsentMode | null; confirmsWrites: boolean; }): WriteModeConsentCopy; //# sourceMappingURL=writeModeConsent.d.ts.map