@burdenoff/fe-libs 2026.1009.2 → 2026.1010.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.
Files changed (51) hide show
  1. package/dist/shared/assistant/appControls/languages.d.ts +2 -0
  2. package/dist/shared/assistant/appControls/languages.js +8 -5
  3. package/dist/shared/assistant/index.d.ts +18 -0
  4. package/dist/shared/assistant/localUiCommands.d.ts +33 -0
  5. package/dist/shared/assistant/localUiCommands.js +159 -88
  6. package/dist/shared/assistant/localeCommands/active.d.ts +19 -0
  7. package/dist/shared/assistant/localeCommands/active.js +25 -0
  8. package/dist/shared/assistant/localeCommands/assent.d.ts +25 -0
  9. package/dist/shared/assistant/localeCommands/assent.js +78 -0
  10. package/dist/shared/assistant/localeCommands/engine.d.ts +89 -0
  11. package/dist/shared/assistant/localeCommands/engine.js +351 -0
  12. package/dist/shared/assistant/localeCommands/evaluate.d.ts +77 -0
  13. package/dist/shared/assistant/localeCommands/evaluate.js +180 -0
  14. package/dist/shared/assistant/localeCommands/fold.d.ts +17 -0
  15. package/dist/shared/assistant/localeCommands/fold.js +66 -0
  16. package/dist/shared/assistant/localeCommands/frames.d.ts +23 -0
  17. package/dist/shared/assistant/localeCommands/frames.js +150 -0
  18. package/dist/shared/assistant/localeCommands/gate.d.ts +37 -0
  19. package/dist/shared/assistant/localeCommands/gate.js +137 -0
  20. package/dist/shared/assistant/localeCommands/languageNames.d.ts +11 -0
  21. package/dist/shared/assistant/localeCommands/languageNames.js +53 -0
  22. package/dist/shared/assistant/localeCommands/nameForms.d.ts +21 -0
  23. package/dist/shared/assistant/localeCommands/nameForms.js +44 -0
  24. package/dist/shared/assistant/localeCommands/normalise.d.ts +49 -0
  25. package/dist/shared/assistant/localeCommands/normalise.js +87 -0
  26. package/dist/shared/assistant/localeCommands/symbols.d.ts +8 -0
  27. package/dist/shared/assistant/localeCommands/symbols.js +6 -0
  28. package/dist/shared/assistant/localeCommands/tables/ar.d.ts +10 -0
  29. package/dist/shared/assistant/localeCommands/tables/ar.js +343 -0
  30. package/dist/shared/assistant/localeCommands/tables/en.d.ts +12 -0
  31. package/dist/shared/assistant/localeCommands/tables/en.js +28 -0
  32. package/dist/shared/assistant/localeCommands/tables/es.d.ts +7 -0
  33. package/dist/shared/assistant/localeCommands/tables/es.js +356 -0
  34. package/dist/shared/assistant/localeCommands/tables/hi.d.ts +9 -0
  35. package/dist/shared/assistant/localeCommands/tables/hi.js +495 -0
  36. package/dist/shared/assistant/localeCommands/tables/ta.d.ts +10 -0
  37. package/dist/shared/assistant/localeCommands/tables/ta.js +429 -0
  38. package/dist/shared/assistant/localeCommands/tables/zh.d.ts +9 -0
  39. package/dist/shared/assistant/localeCommands/tables/zh.js +402 -0
  40. package/dist/shared/assistant/localeCommands/types.d.ts +172 -0
  41. package/dist/shared/assistant/localeCommands/types.js +19 -0
  42. package/dist/shared/assistant/ui/AssistantChatArea.js +1340 -1330
  43. package/dist/shared/assistant/uiActions/linkContext.d.ts +20 -1
  44. package/dist/shared/assistant/uiActions/linkContext.js +39 -21
  45. package/dist/shared/assistant/uiActions/offerYesOnSurface.d.ts +6 -0
  46. package/dist/shared/assistant/uiActions/offerYesOnSurface.js +1 -1
  47. package/dist/shared/assistant/writeReplyBinder.d.ts +1 -1
  48. package/dist/shared/assistant/writeReplySend.d.ts +16 -0
  49. package/dist/shared/assistant/writeReplySend.js +23 -1
  50. package/dist/shared-assistant.js +55 -37
  51. package/package.json +1 -1
@@ -1,4 +1,6 @@
1
1
  import { UiLanguageCode } from './types';
2
+ /** The words the table gives for one UI language (the English name, its own name). */
3
+ export declare function uiLanguageWords(code: UiLanguageCode): readonly string[];
2
4
  /** The UI language a phrase names ("Hindi", "the Tamil language"), or null. */
3
5
  export declare function uiLanguageFromWords(said: string): UiLanguageCode | null;
4
6
  /** The English name of a UI language, for saying that an app does not offer it. */
@@ -33,11 +33,14 @@ var t = {
33
33
  ]
34
34
  }, n = /* @__PURE__ */ new Map();
35
35
  for (let [r, i] of Object.entries(t)) for (let t of i) n.set(e(t), r);
36
- function r(t) {
36
+ function r(e) {
37
+ return t[e];
38
+ }
39
+ function i(t) {
37
40
  let r = e(t).replace(/^(?:the|a) /, "").replace(/ language$/, "").trim();
38
41
  return n.get(r) ?? null;
39
42
  }
40
- var i = {
43
+ var a = {
41
44
  en: "English",
42
45
  ar: "Arabic",
43
46
  es: "Spanish",
@@ -45,8 +48,8 @@ var i = {
45
48
  ta: "Tamil",
46
49
  zh: "Chinese"
47
50
  };
48
- function a(e) {
49
- return i[e];
51
+ function o(e) {
52
+ return a[e];
50
53
  }
51
54
  //#endregion
52
- export { a as uiLanguageEnglishName, r as uiLanguageFromWords };
55
+ export { o as uiLanguageEnglishName, i as uiLanguageFromWords, r as uiLanguageWords };
@@ -237,6 +237,24 @@ export * from './turnTimingReport';
237
237
  export * from './turnTimingReporter';
238
238
  export * from './prewarm';
239
239
  export * from './localUiCommands';
240
+ export * from './localeCommands/types';
241
+ export * from './localeCommands/fold';
242
+ export * from './localeCommands/frames';
243
+ export * from './localeCommands/gate';
244
+ export * from './localeCommands/symbols';
245
+ export * from './localeCommands/nameForms';
246
+ export * from './localeCommands/normalise';
247
+ export * from './localeCommands/active';
248
+ export * from './localeCommands/languageNames';
249
+ export * from './localeCommands/assent';
250
+ export * from './localeCommands/engine';
251
+ export * from './localeCommands/evaluate';
252
+ export * from './localeCommands/tables/hi';
253
+ export * from './localeCommands/tables/ta';
254
+ export * from './localeCommands/tables/ar';
255
+ export * from './localeCommands/tables/es';
256
+ export * from './localeCommands/tables/zh';
257
+ export * from './localeCommands/tables/en';
240
258
  export * from './localUiCommandCopy';
241
259
  export * from './uiActions/navigationOutcome';
242
260
  export * from './uiActions/backStack';
@@ -1,4 +1,5 @@
1
1
  import { AppControlRequest } from './appControls/grammar';
2
+ import { CommandManifest } from './localeCommands/types';
2
3
  import { ControlSnapshot } from './appControls/snapshot';
3
4
  import { AssistantEntityRoute } from './uiActions/entityRoutes';
4
5
  import { NavigationContext, PendingChoice } from './uiActions/linkContext';
@@ -168,6 +169,28 @@ export interface LocalUiCommandOptions {
168
169
  * as the editors' adoption, with a seam test that pins both.
169
170
  */
170
171
  leaveGuard?: boolean;
172
+ /**
173
+ * ★ BOFF-8867 (multilingual commands): the app's UI language, when it differs
174
+ * from `locale` (a spoken sentence is judged by the input language; the app
175
+ * and the assistant's input language are BOTH read by the per-language
176
+ * tables). Absent: `locale`.
177
+ */
178
+ uiLocale?: string;
179
+ /** ★ BOFF-8867: the assistant's input language (what the recogniser listens for). */
180
+ inputLocale?: string;
181
+ /**
182
+ * ★ BOFF-8867: narrow the languages with a table to these primary subtags
183
+ * (`hi`, `ta`, `ar`, `es`, `zh`). Absent: every language the manifest turned on.
184
+ */
185
+ commandLocales?: readonly string[];
186
+ /**
187
+ * ★ BOFF-8867: INTERNAL — the manifest of what is switched on. Products never
188
+ * set it; the evaluation harness and the tests do. Absent: the shipped
189
+ * manifest (`COMMAND_MANIFEST`), which turns on only what passed the blind
190
+ * gate. A manifest a product writes itself can only NARROW the shipped one
191
+ * (`effectiveManifest`): a cell the shipped manifest has off stays off.
192
+ */
193
+ commandManifest?: CommandManifest;
171
194
  }
172
195
  /**
173
196
  * What only the panel knows at the moment of sending. Optional, so every
@@ -193,8 +216,18 @@ export interface LocalUiCommandContext {
193
216
  /**
194
217
  * The command this whole utterance is, or null to send it to the model.
195
218
  * `destinations` is what the person can see in the app's navigation.
219
+ *
220
+ * ★ BOFF-8867: the English grammar runs FIRST and byte for byte; only when it
221
+ * finds nothing is the per-language engine (`localeCommands`) consulted, and
222
+ * only for what the manifest has switched on.
196
223
  */
197
224
  export declare function matchLocalUiCommand(text: string, destinations: readonly LocalDestination[], options?: LocalUiCommandOptions, context?: LocalUiCommandContext): LocalUiCommand | null;
225
+ /**
226
+ * ★ BOFF-8060 / BOFF-8867: could this sentence be "take me there" or a pick —
227
+ * in English or in an active language? The panel builds the offered-navigation
228
+ * context (a parse of the newest reply) only for such a sentence.
229
+ */
230
+ export declare function mayBeNavigationFollowUp(text: string, options?: LocalUiCommandOptions): boolean;
198
231
  /** The most pages one clarification offers. */
199
232
  export declare const LINKED_CHOICE_MAX = 4;
200
233
  /** The shape of a navigation entry this needs (`VisibleNavItem` fits it). */
@@ -1,19 +1,22 @@
1
1
  import { navTargetPath as e } from "../navigation/navTargetPath.js";
2
2
  import { canonical as t } from "./appControls/text.js";
3
3
  import { matchAppControl as n } from "./appControls/grammar.js";
4
- import { isBackRequest as r, isThereRequest as i, parseChoice as a } from "./uiActions/deixis.js";
5
- import { parseRecordRequest as o } from "./uiActions/recordNames.js";
4
+ import { effectiveManifest as r, isEnabled as i } from "./localeCommands/gate.js";
5
+ import { carriesSymbolOrEmoticon as a } from "./localeCommands/symbols.js";
6
+ import { matchLocaleIntents as o, mayBeThereOrPick as s } from "./localeCommands/engine.js";
7
+ import { isBackRequest as c, isThereRequest as l, parseChoice as u } from "./uiActions/deixis.js";
8
+ import { parseRecordRequest as d } from "./uiActions/recordNames.js";
6
9
  //#region src/shared/assistant/localUiCommands.ts
7
- var s = /^(?:(?:hey|hi|so|now|and|then|you know|just|actually|basically)\b ?|(?:please|pls|kindly)\b ?|(?:can|could|would|will) (?:you|u)\b(?: please)? ?|i (?:want|would like|d like)(?: you)?(?: to)?\b ?|let s\b ?)/, c = /^(?:(?:hey|hi|so|ok|okay)\W+)*(?:please\W+)?(?:can|could|would|will) (?:you|u)\b/i, l = / (?:please|pls|for me|now|thanks|thank you|right now)$/;
8
- function u(e, n = {}) {
10
+ var f = /^(?:(?:hey|hi|so|now|and|then|you know|just|actually|basically)\b ?|(?:please|pls|kindly)\b ?|(?:can|could|would|will) (?:you|u)\b(?: please)? ?|i (?:want|would like|d like)(?: you)?(?: to)?\b ?|let s\b ?)/, p = /^(?:(?:hey|hi|so|ok|okay)\W+)*(?:please\W+)?(?:can|could|would|will) (?:you|u)\b/i, m = / (?:please|pls|for me|now|thanks|thank you|right now)$/;
11
+ function h(e, n = {}) {
9
12
  let r = t(e).replace(/\b(?:um+|uh+|erm|er|hmm+)\b/g, " ").replace(/\s+/g, " ").replace(/\b(\w+)(?: \1\b)+/g, "$1").trim();
10
13
  for (;;) {
11
- let e = r.replace(s, "");
12
- if (n.keepEnding || (e = e.replace(l, "")), e = e.trim(), e === r) return r;
14
+ let e = r.replace(f, "");
15
+ if (n.keepEnding || (e = e.replace(m, "")), e = e.trim(), e === r) return r;
13
16
  r = e;
14
17
  }
15
18
  }
16
- var d = {
19
+ var g = {
17
20
  light: {
18
21
  kind: "family",
19
22
  family: "light"
@@ -54,27 +57,27 @@ var d = {
54
57
  kind: "named",
55
58
  theme: "system"
56
59
  }
57
- }, f = "(light|dark|forest|ocean|sunset|high contrast|highcontrast|system|device)", p = "(?:(?:the|my) )?(?:(?:app|ui|screen|display|interface|site) )?(?:theme|colou?r scheme|colou?r mode|appearance)", m = "(mode|theme|colou?r scheme|colou?r mode|appearance)", h = "(?:switch|change|set|turn|put|make|flip)", g = [
58
- { pattern: RegExp(`^(?:${h}(?: (?:over|back))? (?:to|into) |go (?:back )?to |(?:turn|switch) on |(?:use|enable|activate|apply|try|turn|switch|set) )?(?:(?:the|a) )?${f} ${m}(?: on)?$`) },
59
- { pattern: RegExp(`^${h} ${p} (?:to|into|back to) (?:(?:the|a) )?${f}(?: ${m})?$`) },
60
+ }, _ = "(light|dark|forest|ocean|sunset|high contrast|highcontrast|system|device)", v = "(?:(?:the|my) )?(?:(?:app|ui|screen|display|interface|site) )?(?:theme|colou?r scheme|colou?r mode|appearance)", y = "(mode|theme|colou?r scheme|colou?r mode|appearance)", b = "(?:switch|change|set|turn|put|make|flip)", x = [
61
+ { pattern: RegExp(`^(?:${b}(?: (?:over|back))? (?:to|into) |go (?:back )?to |(?:turn|switch) on |(?:use|enable|activate|apply|try|turn|switch|set) )?(?:(?:the|a) )?${_} ${y}(?: on)?$`) },
62
+ { pattern: RegExp(`^${b} ${v} (?:to|into|back to) (?:(?:the|a) )?${_}(?: ${y})?$`) },
60
63
  { pattern: /^(?:switch|change|go)(?: back)? to (light|dark)()$/ },
61
64
  {
62
- pattern: RegExp(`^(?:(?:turn|switch) off|disable|deactivate|exit|leave) (?:the )?(light|dark) ${m}$`),
65
+ pattern: RegExp(`^(?:(?:turn|switch) off|disable|deactivate|exit|leave) (?:the )?(light|dark) ${y}$`),
63
66
  invert: !0
64
67
  },
65
68
  {
66
- pattern: RegExp(`^(?:(?:turn|switch|set) )?(?:the )?(light|dark) ${m} off$`),
69
+ pattern: RegExp(`^(?:(?:turn|switch|set) )?(?:the )?(light|dark) ${y} off$`),
67
70
  invert: !0
68
71
  },
69
72
  { pattern: /^(?:set|make|change) (?:the |my )?(?:theme|appearance) (?:to )?(?:follow|match|use) (?:my|the) (device|system|os)()(?: (?:theme|appearance))?$/ },
70
73
  { pattern: /^(?:follow|match|use) (?:my|the) (device|system|os)() (?:theme|appearance)$/ },
71
74
  { pattern: /^(?:turn on|switch on|enable|use|activate|switch to) (?:the )?(high contrast|highcontrast)()$/ }
72
75
  ];
73
- function _(e) {
74
- for (let { pattern: t, invert: n } of g) {
76
+ function S(e) {
77
+ for (let { pattern: t, invert: n } of x) {
75
78
  let r = t.exec(e);
76
79
  if (!r) continue;
77
- let i = d[r[1] ?? ""];
80
+ let i = g[r[1] ?? ""];
78
81
  if (i) return i.kind === "named" && i.theme === "system" && r[2] === "mode" ? null : n ? i.kind === "family" ? {
79
82
  kind: "family",
80
83
  family: i.family === "dark" ? "light" : "dark"
@@ -82,8 +85,8 @@ function _(e) {
82
85
  }
83
86
  return null;
84
87
  }
85
- var v = /^(?:delete|remove|erase) (?:this|the|my|the current) conversation$/, y = /^(?:(?:(?:go|navigate|take me|bring me|jump|head|get me|move|switch)(?: back| over)?|back) (?:to|too)|open(?: up)?|(?:pull|bring) up|visit|show me)\s+(.+)$/, b = /^(?:the )?(.+) (?:page|screen)$/, x = /(?:^| )(?:tasks?|issues?|tickets?|orders?|invoices?|alerts?|requests?|jobs?|incidents?|bugs?|cases?|deals?|items?|questions?|sessions?|positions?|pull requests?|prs?|work orders?|approvals?|actions?|applications?)$/, S = /^(?:ai|a i|api|a p i|id|data|source|access|banking|graph|search|telemetry|stack|house|field|fields|space|market|mic)$/, C = / (?:page|screen|section|tab)$/;
86
- function w(e) {
88
+ var C = /^(?:delete|remove|erase) (?:this|the|my|the current) conversation$/, w = /^(?:(?:(?:go|navigate|take me|bring me|jump|head|get me|move|switch)(?: back| over)?|back) (?:to|too)|open(?: up)?|(?:pull|bring) up|visit|show me)\s+(.+)$/, T = /^(?:the )?(.+) (?:page|screen)$/, E = /(?:^| )(?:tasks?|issues?|tickets?|orders?|invoices?|alerts?|requests?|jobs?|incidents?|bugs?|cases?|deals?|items?|questions?|sessions?|positions?|pull requests?|prs?|work orders?|approvals?|actions?|applications?)$/, D = /^(?:ai|a i|api|a p i|id|data|source|access|banking|graph|search|telemetry|stack|house|field|fields|space|market|mic)$/, O = / (?:page|screen|section|tab)$/;
89
+ function k(e) {
87
90
  let n = /* @__PURE__ */ new Map(), r = (e, t) => {
88
91
  if (!e) return;
89
92
  let r = n.get(e) ?? [];
@@ -96,7 +99,7 @@ function w(e) {
96
99
  for (let [e, t] of [...n]) for (let n of t) r(`\u0000${e.replace(/ /g, "")}`, n);
97
100
  return n;
98
101
  }
99
- var T = new Set([
102
+ var A = new Set([
100
103
  "news",
101
104
  "series",
102
105
  "species",
@@ -115,18 +118,18 @@ var T = new Set([
115
118
  "process",
116
119
  "progress"
117
120
  ]);
118
- function E(e) {
121
+ function j(e) {
119
122
  let t = e.split(" "), n = t.pop() ?? "";
120
123
  if (n.length < 3) return [];
121
124
  let r = /* @__PURE__ */ new Set();
122
- return T.has(n) || (/[^aeiou]ies$/.test(n) && n.length > 4 ? r.add(`${n.slice(0, -3)}y`) : /(?:sses|shes|ches|xes|zes)$/.test(n) ? r.add(n.slice(0, -2)) : n.length >= 4 && /s$/.test(n) && !/(?:ss|us|is)$/.test(n) && r.add(n.slice(0, -1))), [...r].map((e) => [...t, e].join(" "));
125
+ return A.has(n) || (/[^aeiou]ies$/.test(n) && n.length > 4 ? r.add(`${n.slice(0, -3)}y`) : /(?:sses|shes|ches|xes|zes)$/.test(n) ? r.add(n.slice(0, -2)) : n.length >= 4 && /s$/.test(n) && !/(?:ss|us|is)$/.test(n) && r.add(n.slice(0, -1))), [...r].map((e) => [...t, e].join(" "));
123
126
  }
124
- function D(e, t, n) {
125
- let r = y.exec(e) ?? b.exec(e);
127
+ function M(e, t, n) {
128
+ let r = w.exec(e) ?? T.exec(e);
126
129
  if (!r) return null;
127
- let i = r[1] ?? "", a = e.startsWith("show me "), o = /^open /.test(e), s = i.replace(/^(?:the|my|our) /, ""), c = s.replace(C, ""), l = c !== s || b.test(e);
128
- if (a && !l || o && s === i && !l && (x.test(s) || S.test(s) || /^\w{1,3}$/.test(s))) return null;
129
- let u = w(t), d = (e) => {
130
+ let i = r[1] ?? "", a = e.startsWith("show me "), o = /^open /.test(e), s = i.replace(/^(?:the|my|our) /, ""), c = s.replace(O, ""), l = c !== s || T.test(e);
131
+ if (a && !l || o && s === i && !l && (E.test(s) || D.test(s) || /^\w{1,3}$/.test(s))) return null;
132
+ let u = k(t), d = (e) => {
130
133
  let t = u.get(e);
131
134
  if (t) return {
132
135
  key: e,
@@ -138,7 +141,7 @@ function D(e, t, n) {
138
141
  list: r
139
142
  } : void 0;
140
143
  }, f = c === s ? [s] : [s, c], p = f.reduce((e, t) => e ?? d(t), void 0);
141
- if (!p && n && (p = f.flatMap(E).reduce((e, t) => e ?? d(t), void 0)), !p || p.list.length === 0) return null;
144
+ if (!p && n && (p = f.flatMap(j).reduce((e, t) => e ?? d(t), void 0)), !p || p.list.length === 0) return null;
142
145
  let m = p.list;
143
146
  return m.length === 1 ? {
144
147
  kind: "navigate",
@@ -149,38 +152,42 @@ function D(e, t, n) {
149
152
  candidates: m
150
153
  };
151
154
  }
152
- var O = (e) => e === void 0 || /^en(?:[-_]|$)/i.test(e.trim());
153
- function k(e, t, i = {}, a = {}) {
155
+ var N = (e) => e === void 0 || /^en(?:[-_]|$)/i.test(e.trim());
156
+ function P(e, t, n = {}, a = {}) {
157
+ let o = r(n.commandManifest);
158
+ return F(e, t, n, a, i(o, "en", "frames")) || L(e, t, n, a, o);
159
+ }
160
+ function F(e, t, r, i, o) {
154
161
  let s = e.normalize("NFKC").trim();
155
- if (/[\p{Extended_Pictographic}\p{So}]/u.test(s) || /(?:^|\s)>?[:;=][-'^]?[()[\]/\\|pPdDoO3*@$]+(?=\s|$)/.test(s) || /(?:^|\s)(?:xD|XD|-_-|T_T|<\/?3)(?=\s|$)/.test(s) || /[?¿؟][^\p{L}\p{N}]*$/u.test(s) && !c.test(s)) return null;
156
- let l = u(e);
162
+ if (a(s) || /[?¿؟][^\p{L}\p{N}]*$/u.test(s) && !p.test(s)) return null;
163
+ let l = h(e);
157
164
  if (!l || l.length > 80) return null;
158
- if (v.test(l)) return { kind: "conversation-delete" };
159
- let d = _(l);
160
- if (d) return i.themeWords === "mode-only" && /\b(?:theme|appearance|colou?r scheme)\b/.test(l) && !/\b(?:app|ui|interface)\b/.test(l) ? null : {
165
+ if (C.test(l)) return { kind: "conversation-delete" };
166
+ let u = S(l);
167
+ if (u) return r.themeWords === "mode-only" && /\b(?:theme|appearance|colou?r scheme)\b/.test(l) && !/\b(?:app|ui|interface)\b/.test(l) ? null : {
161
168
  kind: "theme",
162
- request: d
169
+ request: u
163
170
  };
164
- if (a.backRunnable && r(l)) return { kind: "back" };
165
- let f = O(i.locale), p = f ? a.navigation ?? null : null, m = p ? M(l, p) : null;
166
- if (m) return m;
167
- let h = f && a.controls ? n(l, s, a.controls) : null;
168
- if (h && !h.weak) return {
171
+ if (i.backRunnable && c(l)) return { kind: "back" };
172
+ let f = N(r.locale), m = f || o, g = m ? i.navigation ?? null : null, _ = g ? V(l, g) : null;
173
+ if (_) return _;
174
+ let v = m && i.controls ? n(l, s, i.controls) : null;
175
+ if (v && !v.weak) return {
169
176
  kind: "app-control",
170
- request: h.request
177
+ request: v.request
171
178
  };
172
- let g = D(u(e, { keepEnding: !0 }), t, f) ?? D(l, t, f), y = p ? N(l, p) : null;
173
- if (y && g) return P(y, g);
179
+ let y = M(h(e, { keepEnding: !0 }), t, f) ?? M(l, t, f), b = g ? U(l, g) : null;
180
+ if (b && y) return G(b, y);
181
+ if (b) return b;
174
182
  if (y) return y;
175
- if (g) return g;
176
- if (h) return {
183
+ if (v) return {
177
184
  kind: "app-control",
178
- request: h.request
185
+ request: v.request
179
186
  };
180
- if (!a.skipRecords && f && i.records?.length) {
187
+ if (!i.skipRecords && m && r.records?.length) {
181
188
  let e;
182
189
  try {
183
- e = o(l, i.records);
190
+ e = d(l, r.records);
184
191
  } catch {
185
192
  e = null;
186
193
  }
@@ -191,64 +198,128 @@ function k(e, t, i = {}, a = {}) {
191
198
  }
192
199
  return null;
193
200
  }
194
- var A = 4, j = (e) => ` ${t(e)} `;
195
- function M(e, t) {
201
+ function I(e, t, n) {
202
+ if (e.theme) return {
203
+ kind: "theme",
204
+ request: e.theme
205
+ };
206
+ if (n && e.back) return { kind: "back" };
207
+ let r = t && e.pick ? H(e.pick, t) : null;
208
+ if (r) return r;
209
+ let i = e.control;
210
+ if (i && !i.weak) return {
211
+ kind: "app-control",
212
+ request: i.request
213
+ };
214
+ let a = e.goto ? e.goto.destinations.length === 1 ? {
215
+ kind: "navigate",
216
+ destination: e.goto.destinations[0]
217
+ } : {
218
+ kind: "choose-destination",
219
+ query: e.goto.query,
220
+ candidates: e.goto.destinations
221
+ } : null, o = t && e.there ? W(t) : null;
222
+ return o && a ? G(o, a) : o || a || (i ? {
223
+ kind: "app-control",
224
+ request: i.request
225
+ } : null);
226
+ }
227
+ function L(e, t, n, r, i) {
228
+ let s = e.normalize("NFKC").trim();
229
+ if (!s || a(s)) return null;
230
+ let c = o({
231
+ said: s,
232
+ destinations: t,
233
+ uiLocale: n.uiLocale ?? n.locale,
234
+ inputLocale: n.inputLocale ?? n.locale,
235
+ commandLocales: n.commandLocales,
236
+ manifest: i,
237
+ themeWords: n.themeWords,
238
+ navigation: r.navigation != null,
239
+ backRunnable: r.backRunnable === !0,
240
+ controls: r.controls
241
+ }).map((e) => I(e.intents, r.navigation ?? null, r.backRunnable === !0)).filter((e) => e !== null), [l] = c;
242
+ if (!l) return null;
243
+ let u = JSON.stringify(l);
244
+ return c.every((e) => JSON.stringify(e) === u) ? l : null;
245
+ }
246
+ function R(e, t = {}) {
247
+ let n = h(e);
248
+ if (l(n) || u(n) !== null) return !0;
249
+ let i = r(t.commandManifest), o = e.normalize("NFKC").trim();
250
+ return !o || a(o) ? !1 : s({
251
+ said: o,
252
+ uiLocale: t.uiLocale ?? t.locale,
253
+ inputLocale: t.inputLocale ?? t.locale,
254
+ commandLocales: t.commandLocales,
255
+ manifest: i,
256
+ themeWords: t.themeWords,
257
+ navigation: !0,
258
+ backRunnable: !1
259
+ });
260
+ }
261
+ var z = 4, B = (e) => ` ${t(e)} `;
262
+ function V(e, t) {
263
+ let n = u(e);
264
+ return n ? H(n, t) : null;
265
+ }
266
+ function H(e, t) {
196
267
  let n = t.pendingChoice;
197
268
  if (!n) return null;
198
- let r = a(e);
199
- if (!r) return null;
200
- let i = n.candidates;
201
- if (i === null) return {
269
+ let r = n.candidates;
270
+ if (r === null) return {
202
271
  kind: "pick-from-list",
203
272
  candidates: null,
204
273
  candidateIds: n.candidateIds
205
274
  };
206
- let o;
207
- if (r.kind === "ordinal") o = i[r.position - 1];
208
- else if (r.kind === "last") o = i[i.length - 1];
275
+ let i;
276
+ if (e.kind === "ordinal") i = r[e.position - 1];
277
+ else if (e.kind === "last") i = r[r.length - 1];
209
278
  else {
210
- let e = j(r.context), t = i.filter((t) => t !== null && [t.context, t.group].some((t) => t !== void 0 && j(t).includes(e)));
211
- o = t.length === 1 ? t[0] : void 0;
279
+ let t = B(e.context), n = r.filter((e) => e !== null && [e.context, e.group].some((e) => e !== void 0 && B(e).includes(t)));
280
+ i = n.length === 1 ? n[0] : void 0;
212
281
  }
213
- return o === void 0 ? {
282
+ return i === void 0 ? {
214
283
  kind: "pick-from-list",
215
- candidates: i,
284
+ candidates: r,
216
285
  candidateIds: n.candidateIds
217
- } : o === null ? { kind: "link-not-openable" } : {
286
+ } : i === null ? { kind: "link-not-openable" } : {
218
287
  kind: "navigate",
219
- destination: o,
288
+ destination: i,
220
289
  via: "choice"
221
290
  };
222
291
  }
223
- function N(e, t) {
224
- if (!i(e)) return null;
225
- if (t.pendingChoice) return {
292
+ function U(e, t) {
293
+ return l(e) ? W(t) : null;
294
+ }
295
+ function W(e) {
296
+ if (e.pendingChoice) return {
226
297
  kind: "pick-from-list",
227
- candidates: t.pendingChoice.candidates,
228
- candidateIds: t.pendingChoice.candidateIds
298
+ candidates: e.pendingChoice.candidates,
299
+ candidateIds: e.pendingChoice.candidateIds
229
300
  };
230
- let { targets: n, unresolved: r } = t.links, [a] = n;
231
- if (!a) return r > 0 ? { kind: "link-not-openable" } : null;
232
- if (n.length === 1) {
233
- let e = t.offers?.find((e) => e.path === a.path)?.offerId;
234
- return e ? {
301
+ let { targets: t, unresolved: n } = e.links, [r] = t;
302
+ if (!r) return n > 0 ? { kind: "link-not-openable" } : null;
303
+ if (t.length === 1) {
304
+ let t = e.offers?.find((e) => e.path === r.path)?.offerId;
305
+ return t ? {
235
306
  kind: "navigate",
236
- destination: a,
307
+ destination: r,
237
308
  via: "offer",
238
- offerId: e,
309
+ offerId: t,
239
310
  trigger: "deixis"
240
311
  } : {
241
312
  kind: "navigate",
242
- destination: a,
313
+ destination: r,
243
314
  via: "link"
244
315
  };
245
316
  }
246
317
  return {
247
318
  kind: "choose-linked",
248
- candidates: n.slice(0, 4)
319
+ candidates: t.slice(0, 4)
249
320
  };
250
321
  }
251
- function P(e, t) {
322
+ function G(e, t) {
252
323
  let n = (e) => e.kind === "navigate" ? [e.destination] : e.kind === "choose-linked" || e.kind === "choose-destination" ? e.candidates : null, r = n(e), i = n(t);
253
324
  if (!r || !i) return t;
254
325
  let a = [];
@@ -263,11 +334,11 @@ function P(e, t) {
263
334
  candidates: a.slice(0, 4)
264
335
  };
265
336
  }
266
- var F = /^__nav_more__:/;
267
- function I(t, n) {
337
+ var K = /^__nav_more__:/;
338
+ function q(t, n) {
268
339
  let r = [];
269
340
  for (let i of t) {
270
- let t = F.test(i.id), a = e(i);
341
+ let t = K.test(i.id), a = e(i);
271
342
  !t && i.path.startsWith("/") && !i.path.startsWith("//") && a.startsWith("/") && !a.startsWith("//") && i.label.trim() && r.push({
272
343
  id: i.id,
273
344
  label: i.label,
@@ -275,11 +346,11 @@ function I(t, n) {
275
346
  ...a === i.path ? {} : { aliases: [i.path] },
276
347
  ...n ? { context: n } : {},
277
348
  ...i.group ? { group: i.group } : {}
278
- }), i.children?.length && r.push(...I(i.children, t ? n : i.label));
349
+ }), i.children?.length && r.push(...q(i.children, t ? n : i.label));
279
350
  }
280
351
  return r;
281
352
  }
282
- function L(e, t) {
353
+ function J(e, t) {
283
354
  return e.kind === "family" ? {
284
355
  alreadyApplied: t.resolvedTheme === e.family,
285
356
  mode: e.family
@@ -288,7 +359,7 @@ function L(e, t) {
288
359
  mode: e.theme
289
360
  };
290
361
  }
291
- function R(e, t) {
362
+ function Y(e, t) {
292
363
  let n = (e) => {
293
364
  let [t = ""] = e.split("#"), [n = "", r = ""] = t.split("?"), i = n.length > 1 ? n.replace(/\/+$/, "") : n, a = new URLSearchParams(r);
294
365
  return a.sort(), {
@@ -298,11 +369,11 @@ function R(e, t) {
298
369
  }, r = n(e), i = n(t);
299
370
  return r.pathname === i.pathname ? r.query === "" || r.query === i.query : !1;
300
371
  }
301
- function z(e, t, n) {
302
- let r = [e.path, ...e.aliases ?? []].find((e) => R(e, t));
303
- return r === void 0 ? !1 : r.includes("?") ? !0 : !n.some((e) => e.path !== r && e.path.includes("?") && B(e.path, t));
372
+ function X(e, t, n) {
373
+ let r = [e.path, ...e.aliases ?? []].find((e) => Y(e, t));
374
+ return r === void 0 ? !1 : r.includes("?") ? !0 : !n.some((e) => e.path !== r && e.path.includes("?") && Z(e.path, t));
304
375
  }
305
- function B(e, t) {
376
+ function Z(e, t) {
306
377
  let n = (e) => {
307
378
  let [t = ""] = e.split("#"), [n = "", r = ""] = t.split("?");
308
379
  return {
@@ -315,4 +386,4 @@ function B(e, t) {
315
386
  return !0;
316
387
  }
317
388
  //#endregion
318
- export { A as LINKED_CHOICE_MAX, z as isAlreadyThere, R as isCurrentPath, k as matchLocalUiCommand, I as navDestinations, u as normaliseUtterance, L as planThemeChange, E as singularVariants };
389
+ export { z as LINKED_CHOICE_MAX, X as isAlreadyThere, Y as isCurrentPath, P as matchLocalUiCommand, R as mayBeNavigationFollowUp, q as navDestinations, h as normaliseUtterance, J as planThemeChange, j as singularVariants };
@@ -0,0 +1,19 @@
1
+ import { CommandLocale, CommandManifest, LocaleTable } from './types';
2
+ /** The tables, by locale. Data only. */
3
+ export declare const LOCALE_TABLES: Readonly<Record<CommandLocale, LocaleTable>>;
4
+ export interface ActiveLocaleInput {
5
+ /** The app's UI language (a BCP-47 tag or code). */
6
+ ui?: string | undefined;
7
+ /** The assistant's input language (what the recogniser listens for). */
8
+ input?: string | undefined;
9
+ /** A product narrowing the set (`localUiCommands.commandLocales`). Absent: every gated locale. */
10
+ narrow?: readonly string[] | undefined;
11
+ manifest: CommandManifest;
12
+ }
13
+ /**
14
+ * The tables in force for one sentence (design §2.2): the primary subtags of
15
+ * the UI language and of the assistant's input language, when they have a table
16
+ * with a family switched on. Typed text is judged by the UI language and spoken
17
+ * text by the input language today; the union makes both surfaces behave alike.
18
+ */
19
+ export declare function activeCommandLocales(input: ActiveLocaleInput): CommandLocale[];
@@ -0,0 +1,25 @@
1
+ import { COMMAND_LOCALES as e } from "./types.js";
2
+ import { effectiveManifest as t, localeHasAnyOn as n } from "./gate.js";
3
+ import { ARABIC_COMMANDS as r } from "./tables/ar.js";
4
+ import { SPANISH_COMMANDS as i } from "./tables/es.js";
5
+ import { HINDI_COMMANDS as a } from "./tables/hi.js";
6
+ import { TAMIL_COMMANDS as o } from "./tables/ta.js";
7
+ import { CHINESE_COMMANDS as s } from "./tables/zh.js";
8
+ //#region src/shared/assistant/localeCommands/active.ts
9
+ var c = Object.freeze({
10
+ hi: a,
11
+ ta: o,
12
+ ar: r,
13
+ es: i,
14
+ zh: s
15
+ }), l = (e) => (e ?? "").trim().toLowerCase().split(/[-_]/)[0] ?? "";
16
+ function u(r) {
17
+ let i = t(r.manifest), a = r.narrow?.map(l), o = [];
18
+ for (let t of [r.ui, r.input]) {
19
+ let r = l(t), s = e.find((e) => e === r);
20
+ !s || o.includes(s) || a && !a.includes(s) || n(i, s) && o.push(s);
21
+ }
22
+ return o;
23
+ }
24
+ //#endregion
25
+ export { c as LOCALE_TABLES, u as activeCommandLocales };
@@ -0,0 +1,25 @@
1
+ import { CommandManifest } from './types';
2
+ /** At most this many tokens (Chinese: characters) make a bare yes. */
3
+ export declare const ASSENT_MAX_TOKENS = 3;
4
+ export declare const ASSENT_MAX_ZH_CHARS = 6;
5
+ export interface OfferAssentInput {
6
+ /** What the person typed or said. */
7
+ text: string;
8
+ /** The app's UI language. */
9
+ uiLocale?: string | undefined;
10
+ /** The assistant's input language. */
11
+ inputLocale?: string | undefined;
12
+ /** A product narrowing the languages (`localUiCommands.commandLocales`). */
13
+ commandLocales?: readonly string[] | undefined;
14
+ /** Defaults to the shipped manifest; only the evaluation builders' manifests are believed beyond it. */
15
+ manifest?: CommandManifest | undefined;
16
+ /** A3: the product attests N4 (`localUiCommands.leaveGuard`). */
17
+ leaveGuard: boolean | undefined;
18
+ }
19
+ /**
20
+ * Whether this utterance is a bare yes the offer rows may act on. `false` for
21
+ * every English utterance an English table would have handled (the English
22
+ * affirm row is the binder's own and untouched), for a product without the
23
+ * leave guard, and whenever any doubt remains.
24
+ */
25
+ export declare function offerAssentFor(input: OfferAssentInput): boolean;