@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
@@ -0,0 +1,180 @@
1
+ import { planWriteReply as e } from "../writeReplySend.js";
2
+ import { COMMAND_FAMILIES as t } from "./types.js";
3
+ import { allOnManifest as n } from "./gate.js";
4
+ import { matchLocalUiCommand as r } from "../localUiCommands.js";
5
+ import { offerAssentFor as i } from "./assent.js";
6
+ import { EMPTY_CONTROL_SNAPSHOT as a } from "../appControls/snapshot.js";
7
+ //#region src/shared/assistant/localeCommands/evaluate.ts
8
+ var o = (e) => e.id;
9
+ function s(e) {
10
+ if (!e) return;
11
+ let t = { ...a.registered };
12
+ for (let n of e.registered ?? []) t[n] = !0;
13
+ let n = e.page ? {
14
+ name: e.page.name ?? "Page",
15
+ tabs: e.page.tabs ?? [],
16
+ filters: e.page.filters ?? [],
17
+ sorts: e.page.sorts ?? [],
18
+ searchable: e.page.searchable ?? !1,
19
+ openers: e.page.openers ?? []
20
+ } : null;
21
+ return {
22
+ ...a,
23
+ registered: t,
24
+ languages: e.languages ?? [],
25
+ sidebarEntries: e.sidebarEntries ?? [],
26
+ page: n
27
+ };
28
+ }
29
+ function c(e) {
30
+ if (!e) return null;
31
+ let t = e.links ?? [], n = e.list, r = new Set(e.offered ?? []);
32
+ return {
33
+ links: {
34
+ targets: [...t],
35
+ unresolved: e.unresolved ?? 0
36
+ },
37
+ pendingChoice: n ? {
38
+ candidates: n.map((e) => t.find((t) => t.id === e) ?? null),
39
+ candidateIds: [...n]
40
+ } : null,
41
+ ...r.size > 0 ? { offers: t.filter((e) => r.has(e.id)).map((e) => ({
42
+ path: e.path,
43
+ offerId: `uo_${e.id.padEnd(32, "0").slice(0, 32)}`
44
+ })) } : {}
45
+ };
46
+ }
47
+ function l(e) {
48
+ if (!e) return { result: "model" };
49
+ switch (e.kind) {
50
+ case "navigate": return {
51
+ result: "command",
52
+ kind: "navigate",
53
+ destinationId: e.destination.id,
54
+ ...e.via ? { via: e.via } : {},
55
+ ...e.via === "offer" ? { trigger: e.trigger } : {}
56
+ };
57
+ case "choose-destination":
58
+ case "choose-linked": return {
59
+ result: "command",
60
+ kind: e.kind,
61
+ candidateIds: e.candidates.map(o)
62
+ };
63
+ case "theme": return {
64
+ result: "command",
65
+ kind: "theme",
66
+ family: e.request.kind === "family" ? e.request.family : e.request.theme
67
+ };
68
+ case "app-control": return {
69
+ result: "command",
70
+ kind: "app-control",
71
+ control: e.request.control,
72
+ request: e.request
73
+ };
74
+ case "pick-from-list": return {
75
+ result: "command",
76
+ kind: "pick-from-list"
77
+ };
78
+ default: return {
79
+ result: "command",
80
+ kind: e.kind
81
+ };
82
+ }
83
+ }
84
+ function u(t, n) {
85
+ let a = t.inputLocale ?? t.uiLocale, o = t.origin === "spoken", u = o ? a : t.uiLocale;
86
+ if (t.yes) {
87
+ let r = t.yes, s = e({
88
+ text: t.text,
89
+ locale: u,
90
+ origin: o ? "spoken" : "typed",
91
+ hasAttachments: r.attachments === !0,
92
+ live: {
93
+ count: r.pending ?? 0,
94
+ execution: "enabled"
95
+ },
96
+ matchesLocalCommand: () => !1,
97
+ offer: r.offer ?? "none",
98
+ offerAssent: i({
99
+ text: t.text,
100
+ uiLocale: t.uiLocale,
101
+ inputLocale: a,
102
+ manifest: n,
103
+ leaveGuard: r.leaveGuard === !0
104
+ })
105
+ });
106
+ return s.kind === "accept_offer" ? {
107
+ result: "command",
108
+ kind: "accept_offer"
109
+ } : s.kind === "local_reply" ? {
110
+ result: "model",
111
+ plannedAs: "local_reply"
112
+ } : { result: "model" };
113
+ }
114
+ let d = s(t.controls), f = c(t.navigation), p = {
115
+ ...t.backRunnable === void 0 ? {} : { backRunnable: t.backRunnable },
116
+ ...f ? { navigation: f } : {},
117
+ ...d ? { controls: d } : {}
118
+ };
119
+ return l(r(t.text, t.sidebar ?? [], {
120
+ locale: u,
121
+ uiLocale: t.uiLocale,
122
+ inputLocale: a,
123
+ commandManifest: n,
124
+ ...t.themeWords ? { themeWords: t.themeWords } : {}
125
+ }, p));
126
+ }
127
+ function d(e, t) {
128
+ return typeof t == "string" ? e.result === t : Object.entries(t).every(([t, n]) => {
129
+ let r = e[t];
130
+ return JSON.stringify(r) === JSON.stringify(n);
131
+ });
132
+ }
133
+ function f(e, t) {
134
+ return t === void 0 ? "unscored" : (typeof t == "string" ? t === "model" : t.result === "model") ? e.result === "model" ? "pass" : "false-match" : e.result === "model" ? "miss" : d(e, t) ? "pass" : "wrong";
135
+ }
136
+ function p(e, t = n()) {
137
+ let r = u(e, t);
138
+ return {
139
+ id: e.id,
140
+ locale: e.uiLocale.toLowerCase().split(/[-_]/)[0] ?? e.uiLocale,
141
+ family: e.family ?? "unlabelled",
142
+ actual: r,
143
+ ...e.expected === void 0 ? {} : { expected: e.expected },
144
+ verdict: f(r, e.expected)
145
+ };
146
+ }
147
+ function m(e) {
148
+ let t = /* @__PURE__ */ new Map();
149
+ for (let n of e) {
150
+ if (n.verdict === "unscored") continue;
151
+ let e = `${n.locale}\u0000${n.family}`, r = t.get(e) ?? {
152
+ locale: n.locale,
153
+ family: n.family,
154
+ items: 0,
155
+ positives: 0,
156
+ negatives: 0,
157
+ truePositives: 0,
158
+ misses: 0,
159
+ wrong: 0,
160
+ falseMatches: 0,
161
+ precision: null,
162
+ recall: null
163
+ };
164
+ r.items += 1;
165
+ let i = typeof n.expected == "string" ? n.expected === "model" : n.expected?.result === "model";
166
+ i ? r.negatives += 1 : r.positives += 1, n.verdict === "pass" && !i && (r.truePositives += 1), n.verdict === "miss" && (r.misses += 1), n.verdict === "wrong" && (r.wrong += 1), n.verdict === "false-match" && (r.falseMatches += 1), t.set(e, r);
167
+ }
168
+ return [...t.values()].map((e) => {
169
+ let t = e.falseMatches + e.wrong, n = e.truePositives + t;
170
+ return {
171
+ ...e,
172
+ falseMatches: t,
173
+ precision: n === 0 ? null : e.truePositives / n,
174
+ recall: e.positives === 0 ? null : e.truePositives / e.positives
175
+ };
176
+ }).sort((e, t) => `${e.locale}${e.family}`.localeCompare(`${t.locale}${t.family}`));
177
+ }
178
+ var h = [...t];
179
+ //#endregion
180
+ export { h as EVAL_FAMILIES, u as actualOf, l as describeCommand, p as evaluateCommandItem, m as scoreboard, f as verdictOf };
@@ -0,0 +1,17 @@
1
+ import { CommandLocale } from './types';
2
+ /**
3
+ * The fold: lower-case, punctuation-free, single-spaced — and, for `zh`, with no
4
+ * space at all. Idempotent.
5
+ */
6
+ export declare function foldText(text: string, locale: CommandLocale | "en"): string;
7
+ /** One word of a sentence, as said and as folded (a word may fold to several, or to none). */
8
+ export interface FoldedWord {
9
+ said: string;
10
+ folded: string[];
11
+ }
12
+ /**
13
+ * The sentence split at its spaces, each word with its folded form(s), so a
14
+ * free-text slot can hand back the person's OWN words (case, inner
15
+ * punctuation) rather than the fold of them.
16
+ */
17
+ export declare function foldWords(text: string, locale: CommandLocale | "en"): FoldedWord[];
@@ -0,0 +1,66 @@
1
+ //#region src/shared/assistant/localeCommands/fold.ts
2
+ var e = /\p{Cf}/gu, t = [
3
+ 1632,
4
+ 1776,
5
+ 2406,
6
+ 3046
7
+ ];
8
+ function n(e) {
9
+ return e.replace(/\p{Nd}/gu, (e) => {
10
+ let n = e.codePointAt(0) ?? 0;
11
+ for (let e of t) if (n >= e && n <= e + 9) return String(n - e);
12
+ return e;
13
+ });
14
+ }
15
+ var r = /़/g, i = /ँ/g, a = [
16
+ [/ङ्(?=[क-घ])/g, "ं"],
17
+ [/ञ्(?=[च-झ])/g, "ं"],
18
+ [/ण्(?=[ट-ढ])/g, "ं"],
19
+ [/न्(?=[त-ध])/g, "ं"],
20
+ [/म्(?=[प-भ])/g, "ं"]
21
+ ];
22
+ function o(e) {
23
+ let t = e.replace(r, "").replace(i, "ं");
24
+ for (let [e, n] of a) t = t.replace(e, n);
25
+ return t;
26
+ }
27
+ var s = /[ً-ٰٟـ]/g, c = [
28
+ [/[أإآٱ]/g, "ا"],
29
+ [/ى/g, "ي"],
30
+ [/ة/g, "ه"],
31
+ [/ؤ/g, "و"],
32
+ [/ئ/g, "ي"],
33
+ [/ی/g, "ي"],
34
+ [/ک/g, "ك"]
35
+ ];
36
+ function l(e) {
37
+ let t = e.replace(s, "");
38
+ for (let [e, n] of c) t = t.replace(e, n);
39
+ return t;
40
+ }
41
+ function u(e) {
42
+ return e.replace(/\p{Script=Latin}\p{M}*/gu, (e) => {
43
+ let t = e.normalize("NFC");
44
+ return t === "ñ" ? t : e.normalize("NFD").replace(/[̀-ͯ]/g, "");
45
+ });
46
+ }
47
+ var d = {
48
+ en: (e) => e,
49
+ hi: o,
50
+ ta: (e) => e,
51
+ ar: l,
52
+ es: u,
53
+ zh: (e) => e
54
+ };
55
+ function f(t, r) {
56
+ let i = n(t.normalize("NFKC").replace(e, "").toLowerCase().normalize("NFKC")), a = d[r](i).replace(/&/g, " and ").replace(/[^\p{L}\p{N}\p{M}\s]/gu, " ").replace(/\s+/g, " ").trim();
57
+ return r === "zh" ? a.replace(/\s+/g, "") : a;
58
+ }
59
+ function p(t, n) {
60
+ return t.normalize("NFKC").replace(e, "").split(/\s+/).filter(Boolean).map((e) => ({
61
+ said: e.replace(/^[^\p{L}\p{N}]+|[^\p{L}\p{N}]+$/gu, ""),
62
+ folded: f(e, n).split(" ").filter(Boolean)
63
+ }));
64
+ }
65
+ //#endregion
66
+ export { f as foldText, p as foldWords };
@@ -0,0 +1,23 @@
1
+ import { CommandLocale } from './types';
2
+ /** The words a closed slot may be: a map from the FOLDED word to its value. */
3
+ export type ClosedSlots = Readonly<Record<string, ReadonlyMap<string, string | number>>>;
4
+ /** What a template captured: slot name → folded text. */
5
+ export type Captures = Readonly<Record<string, string>>;
6
+ export interface CompiledFrame {
7
+ readonly template: string;
8
+ /** Lazy then greedy; identical when the template has no open slot. */
9
+ readonly expressions: readonly RegExp[];
10
+ readonly slots: readonly string[];
11
+ }
12
+ /** Compile a template for `locale`. Throws on a malformed template (a table bug). */
13
+ export declare function compileFrame(template: string, locale: CommandLocale | "en", closed?: ClosedSlots): CompiledFrame;
14
+ /** Every distinct parse of the whole folded utterance by this frame. */
15
+ export declare function matchFrame(frame: CompiledFrame, folded: string): Captures[];
16
+ /** A map from folded word to value, for a closed slot. */
17
+ export declare function closedSlot(entries: ReadonlyArray<readonly [readonly string[], string | number]>, locale: CommandLocale | "en"): ReadonlyMap<string, string | number>;
18
+ /**
19
+ * Every sentence a template can say, with each slot filled from `slots` (a
20
+ * closed slot may be left out: its table words are used). For the tests and the
21
+ * evaluation harness — the engine never enumerates, it matches.
22
+ */
23
+ export declare function expandTemplate(template: string, locale: CommandLocale | "en", slots: Readonly<Record<string, readonly string[]>>, closed?: ClosedSlots): string[];
@@ -0,0 +1,150 @@
1
+ import { foldText as e } from "./fold.js";
2
+ //#region src/shared/assistant/localeCommands/frames.ts
3
+ var t = new Set([
4
+ "x",
5
+ "q",
6
+ "lang"
7
+ ]), n = new Set([
8
+ "p",
9
+ "o",
10
+ "n",
11
+ "d"
12
+ ]), r = 6, i = 12, a = (e) => e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
13
+ function o(t, n) {
14
+ let r = 0, i = (a) => {
15
+ let o = [[]], s = "", c = () => {
16
+ if (!s) return;
17
+ let t = e(s, n);
18
+ if (s = "", !t) return;
19
+ let r = o[o.length - 1];
20
+ for (let e of t.split(" ")) r.push({
21
+ type: "lit",
22
+ text: e
23
+ });
24
+ };
25
+ for (; r < t.length;) {
26
+ let e = t.charAt(r);
27
+ if (a !== null && e === a) return c(), o;
28
+ let n = o[o.length - 1];
29
+ if (e === " ") c(), r += 1;
30
+ else if (e === "(") {
31
+ c(), r += 1;
32
+ let e = i(")");
33
+ if (r += 1, e.some((e) => e.length === 0)) throw Error(`empty alternative in template "${t}"`);
34
+ n.push({
35
+ type: "alt",
36
+ options: e
37
+ });
38
+ } else if (e === "[") {
39
+ c(), r += 1;
40
+ let e = i("]");
41
+ r += 1;
42
+ let [a, ...o] = e;
43
+ if (o.length > 0 || !a || a.length === 0) throw Error(`bad optional group in template "${t}"`);
44
+ n.push({
45
+ type: "opt",
46
+ seq: a
47
+ });
48
+ } else if (e === "{") {
49
+ c();
50
+ let e = t.indexOf("}", r);
51
+ if (e < 0) throw Error(`unclosed slot in template "${t}"`);
52
+ n.push({
53
+ type: "slot",
54
+ name: t.slice(r + 1, e)
55
+ }), r = e + 1;
56
+ } else if (e === "|" && a === ")") c(), r += 1, o.push([]);
57
+ else if (e === "|" && a === "]") throw Error(`alternatives inside [ ] in template "${t}": use [(a|b)]`);
58
+ else s += e, r += 1;
59
+ }
60
+ if (a !== null) throw Error(`unclosed group in template "${t}"`);
61
+ return c(), o;
62
+ }, [a] = i(null);
63
+ return a ?? [];
64
+ }
65
+ function s(e, o) {
66
+ if (o.slots.add(e), n.has(e)) {
67
+ let t = [...o.closed[e]?.keys() ?? []].sort((e, t) => t.length - e.length);
68
+ if (t.length === 0) throw Error(`no words for the closed slot {${e}}`);
69
+ return `(?<${e}>${t.map(a).join("|")})`;
70
+ }
71
+ if (!t.has(e)) throw Error(`unknown slot {${e}}`);
72
+ let s = o.lazy ? "?" : "";
73
+ return e === "q" ? `(?<q>.+${s})` : o.zh ? `(?<${e}>.{1,${i}}${s})` : `(?<${e}>\\S+(?: \\S+){0,${r - 1}}${s})`;
74
+ }
75
+ function c(e, t) {
76
+ let n = "", r = !1;
77
+ for (let i of e) {
78
+ if (i.type === "opt") {
79
+ let e = c(i.seq, t);
80
+ n += r ? `(?:${t.sep}${e})?` : `(?:${e}${t.sep})?`;
81
+ continue;
82
+ }
83
+ let e;
84
+ if (i.type === "lit") e = a(i.text);
85
+ else if (i.type === "slot") e = s(i.name, t);
86
+ else {
87
+ let n = i.options.map((e) => c(e, t));
88
+ n.sort((e, t) => t.length - e.length), e = `(?:${n.join("|")})`;
89
+ }
90
+ n += (r ? t.sep : "") + e, r = !0;
91
+ }
92
+ return n;
93
+ }
94
+ function l(e, n, r = {}) {
95
+ let i = o(e, n), a = n === "zh", s = /* @__PURE__ */ new Set(), l = (e) => RegExp(`^${c(i, {
96
+ sep: a ? "" : " ",
97
+ lazy: e,
98
+ closed: r,
99
+ zh: a,
100
+ slots: s
101
+ })}$`, "u"), u = l(!0), d = l(!1);
102
+ return {
103
+ template: e,
104
+ expressions: [...s].some((e) => t.has(e)) ? [u, d] : [u],
105
+ slots: [...s]
106
+ };
107
+ }
108
+ function u(e, t) {
109
+ let n = [], r = /* @__PURE__ */ new Set();
110
+ for (let i of e.expressions) {
111
+ let e = i.exec(t);
112
+ if (!e) continue;
113
+ let a = {};
114
+ for (let [t, n] of Object.entries(e.groups ?? {})) typeof n == "string" && (a[t] = n);
115
+ let o = JSON.stringify(a);
116
+ r.has(o) || (r.add(o), n.push(a));
117
+ }
118
+ return n;
119
+ }
120
+ function d(t, n) {
121
+ let r = /* @__PURE__ */ new Map();
122
+ for (let [i, a] of t) for (let t of i) {
123
+ let i = e(t, n);
124
+ i && r.set(i, a);
125
+ }
126
+ return r;
127
+ }
128
+ var f = 2e4;
129
+ function p(e, t, n, r = {}) {
130
+ let i = o(e, t), a = t === "zh" ? "" : " ", s = (t) => {
131
+ let i = n[t];
132
+ if (i) return i;
133
+ let a = r[t];
134
+ if (a) return [...a.keys()];
135
+ throw Error(`no values for slot {${t}} in "${e}"`);
136
+ }, c = (t) => {
137
+ let n = [""];
138
+ for (let r of t) {
139
+ let t;
140
+ t = r.type === "lit" ? [r.text] : r.type === "slot" ? [...s(r.name)] : r.type === "alt" ? r.options.flatMap((e) => c(e)) : ["", ...c(r.seq)];
141
+ let i = [];
142
+ for (let r of n) for (let n of t) if (i.push(r === "" ? n : n === "" ? r : `${r}${a}${n}`), i.length > f) throw Error(`too many expansions of "${e}"`);
143
+ n = i;
144
+ }
145
+ return n;
146
+ };
147
+ return c(i);
148
+ }
149
+ //#endregion
150
+ export { d as closedSlot, l as compileFrame, p as expandTemplate, u as matchFrame };
@@ -0,0 +1,37 @@
1
+ import { CommandFamily, CommandManifest, ManifestLocale } from './types';
2
+ /**
3
+ * What the shipped build turns on: only the cells that passed the round-3 blind
4
+ * gate (0 false matches, recall over the floor; evidence in `frozen/`, report
5
+ * `audit/platform/assistant/2026-10-09-multilingual-commands/eval/round3.md`).
6
+ */
7
+ export declare const COMMAND_MANIFEST: CommandManifest;
8
+ /** The families each manifest locale can carry. `en` carries only the English additions. */
9
+ export declare const MANIFEST_FAMILIES: Readonly<Record<ManifestLocale, readonly (CommandFamily | "frames")[]>>;
10
+ /** Design §3.2 G4: the recall an entry needs to be enabled for go-to, there and yes. */
11
+ export declare const RECALL_FLOOR = 0.6;
12
+ /**
13
+ * A manifest with every entry on. For the evaluation harness and the tests
14
+ * ONLY: it carries no evidence on purpose, so `validateManifest` rejects it —
15
+ * it can never be mistaken for a shippable one.
16
+ */
17
+ export declare function allOnManifest(): CommandManifest;
18
+ /** A manifest with only the listed `locale:family` pairs on (tests, evaluation of one family). */
19
+ export declare function manifestWith(on: readonly string[]): CommandManifest;
20
+ /**
21
+ * The manifest a matcher actually uses for a caller-supplied one. Absent: the
22
+ * shipped manifest. One the evaluation builders made (the harness, the tests):
23
+ * as given. Anything else: only the cells that are ON in BOTH it and the
24
+ * shipped manifest, with the shipped entry's evidence, so a product may narrow
25
+ * what shipped but never widen it past the evidence.
26
+ */
27
+ export declare function effectiveManifest(supplied: CommandManifest | undefined, shipped?: CommandManifest): CommandManifest;
28
+ /** Is `family` of `locale` on in this manifest? */
29
+ export declare function isEnabled(manifest: CommandManifest, locale: ManifestLocale, family: CommandFamily | "frames"): boolean;
30
+ /** Does this locale have any family on? (A table with nothing on is not active.) */
31
+ export declare function localeHasAnyOn(manifest: CommandManifest, locale: ManifestLocale): boolean;
32
+ /**
33
+ * The evidence rule, as a list of problems (empty: the manifest may ship).
34
+ * `corpusShaOf` reads the sha256 of the frozen blind file an entry names, or
35
+ * null when that file does not exist.
36
+ */
37
+ export declare function validateManifest(manifest: CommandManifest, corpusShaOf: (locale: ManifestLocale, family: CommandFamily | "frames") => string | null): string[];
@@ -0,0 +1,137 @@
1
+ import { COMMAND_FAMILIES as e, COMMAND_LOCALES as t } from "./types.js";
2
+ //#region src/shared/assistant/localeCommands/gate.ts
3
+ function n(e) {
4
+ return Object.freeze({
5
+ enabled: !0,
6
+ ...e
7
+ });
8
+ }
9
+ var r = Object.freeze({
10
+ en: Object.freeze({}),
11
+ hi: Object.freeze({ language: n({
12
+ corpusSha256: "c15bed2eabee0fece15456f96923bd12abf3e6f8884619a8a90d2e9a99c0acac",
13
+ positives: 8,
14
+ negatives: 195,
15
+ falseMatches: 0,
16
+ recall: 1
17
+ }) }),
18
+ ta: Object.freeze({}),
19
+ ar: Object.freeze({
20
+ goto: n({
21
+ corpusSha256: "9c39b609525a616bcba5992f6a30279af8023bd478d2c3f5692bba9b668893be",
22
+ positives: 26,
23
+ negatives: 188,
24
+ falseMatches: 0,
25
+ recall: .769
26
+ }),
27
+ language: n({
28
+ corpusSha256: "86a23a6e8920558576fd2f73cb3504a766103b8b58d0255ff4a4b27ccff46414",
29
+ positives: 8,
30
+ negatives: 188,
31
+ falseMatches: 0,
32
+ recall: .75
33
+ })
34
+ }),
35
+ es: Object.freeze({
36
+ goto: n({
37
+ corpusSha256: "5b67ba87a2a69dd6ec656c8f1d76c65a001043059fc7b0d4d971e641b52f9746",
38
+ positives: 26,
39
+ negatives: 188,
40
+ falseMatches: 0,
41
+ recall: .769
42
+ }),
43
+ language: n({
44
+ corpusSha256: "9bc791353a258d3e22bf28f505b9b34065d9b24c5c657a69fc8ce5625e846d7d",
45
+ positives: 8,
46
+ negatives: 188,
47
+ falseMatches: 0,
48
+ recall: .625
49
+ })
50
+ }),
51
+ zh: Object.freeze({
52
+ goto: n({
53
+ corpusSha256: "94f7b5b11bfd843695674cd86840cb6b59be291c7c9dcdaa83ec9b12d5bc0d16",
54
+ positives: 26,
55
+ negatives: 188,
56
+ falseMatches: 0,
57
+ recall: .769
58
+ }),
59
+ language: n({
60
+ corpusSha256: "edefba601427357299751db7a0cebd603d8945d981c61fb663b0e958f30e00bb",
61
+ positives: 8,
62
+ negatives: 188,
63
+ falseMatches: 0,
64
+ recall: .875
65
+ })
66
+ })
67
+ }), i = Object.freeze({
68
+ en: [
69
+ "frames",
70
+ "goto",
71
+ "language"
72
+ ],
73
+ hi: e,
74
+ ta: e,
75
+ ar: e,
76
+ es: e,
77
+ zh: e
78
+ }), a = .6, o = "0".repeat(64);
79
+ function s() {
80
+ let e = (e) => Object.fromEntries(e.map((e) => [e, { enabled: !0 }]));
81
+ return u({
82
+ en: e(i.en),
83
+ hi: e(i.hi),
84
+ ta: e(i.ta),
85
+ ar: e(i.ar),
86
+ es: e(i.es),
87
+ zh: e(i.zh)
88
+ });
89
+ }
90
+ function c(e) {
91
+ let t = new Set(e), n = (e) => Object.fromEntries(i[e].filter((n) => t.has(`${e}:${n}`)).map((e) => [e, { enabled: !0 }]));
92
+ return u({
93
+ en: n("en"),
94
+ hi: n("hi"),
95
+ ta: n("ta"),
96
+ ar: n("ar"),
97
+ es: n("es"),
98
+ zh: n("zh")
99
+ });
100
+ }
101
+ var l = /* @__PURE__ */ new WeakSet();
102
+ function u(e) {
103
+ let t = Object.freeze(e);
104
+ return l.add(t), t;
105
+ }
106
+ function d(e, t = r) {
107
+ if (!e || e === t) return t;
108
+ if (l.has(e)) return e;
109
+ let n = (n) => Object.fromEntries(Object.entries(t[n]).filter(([t, r]) => r?.enabled === !0 && e[n]?.[t]?.enabled === !0));
110
+ return Object.freeze({
111
+ en: Object.freeze(n("en")),
112
+ hi: Object.freeze(n("hi")),
113
+ ta: Object.freeze(n("ta")),
114
+ ar: Object.freeze(n("ar")),
115
+ es: Object.freeze(n("es")),
116
+ zh: Object.freeze(n("zh"))
117
+ });
118
+ }
119
+ function f(e, t, n) {
120
+ return e[t][n]?.enabled === !0;
121
+ }
122
+ function p(e, t) {
123
+ return Object.values(e[t]).some((e) => e?.enabled === !0);
124
+ }
125
+ function m(e, n) {
126
+ let r = [];
127
+ for (let s of ["en", ...t]) for (let [t, c] of Object.entries(e[s])) {
128
+ if (!c?.enabled) continue;
129
+ let e = `${s}:${t}`;
130
+ i[s].includes(t) || r.push(`${e}: not a family of ${s}`), (!c.corpusSha256 || !/^[0-9a-f]{64}$/.test(c.corpusSha256)) && r.push(`${e}: enabled with no corpus sha256`), c.corpusSha256 === o && r.push(`${e}: placeholder sha256`), (c.falseMatches === void 0 || c.falseMatches !== 0) && r.push(`${e}: enabled without a recorded 0 false matches`), (c.negatives === void 0 || c.negatives <= 0) && r.push(`${e}: enabled without a negative count`), (t === "goto" || t === "there" || t === "yes") && (c.recall === void 0 || c.recall < .6) && r.push(`${e}: recall is under the ${a} floor`);
131
+ let l = n(s, t);
132
+ l === null ? r.push(`${e}: its corpus file is missing`) : c.corpusSha256 && l !== c.corpusSha256 && r.push(`${e}: its corpus file has a different hash`);
133
+ }
134
+ return r;
135
+ }
136
+ //#endregion
137
+ export { r as COMMAND_MANIFEST, i as MANIFEST_FAMILIES, a as RECALL_FLOOR, s as allOnManifest, d as effectiveManifest, f as isEnabled, p as localeHasAnyOn, c as manifestWith, m as validateManifest };
@@ -0,0 +1,11 @@
1
+ import { UiLanguage } from '../appControls/types';
2
+ import { CommandLocale, LanguageCode, LocaleTable } from './types';
3
+ /**
4
+ * Folded name → the one language it names. `fold` is the fold of the table the
5
+ * sentence is read with; the names of every `tables` locale are added.
6
+ */
7
+ export declare function languageNameMap(input: {
8
+ tables: readonly LocaleTable[];
9
+ appLanguages: readonly UiLanguage[];
10
+ fold: CommandLocale | "en";
11
+ }): ReadonlyMap<string, LanguageCode>;
@@ -0,0 +1,53 @@
1
+ import { uiLanguageWords as e } from "../appControls/languages.js";
2
+ import { foldText as t } from "./fold.js";
3
+ import { UI_LANGUAGE_CODES as n } from "../appControls/types.js";
4
+ //#region src/shared/assistant/localeCommands/languageNames.ts
5
+ var r = {
6
+ en: "en",
7
+ ar: "ar",
8
+ es: "es",
9
+ hi: "hi",
10
+ ta: "ta",
11
+ zh: "zh"
12
+ }, i = /* @__PURE__ */ new Map();
13
+ function a(e) {
14
+ let t = i.get(e);
15
+ if (t) return t;
16
+ let a = [];
17
+ try {
18
+ let t = new Intl.DisplayNames([e], { type: "language" });
19
+ for (let e of n) {
20
+ let n = t.of(r[e]);
21
+ n && a.push(`${e}\u0000${n}`);
22
+ }
23
+ } catch {}
24
+ return i.set(e, a), a;
25
+ }
26
+ var o = (e) => n.includes(e);
27
+ function s(r) {
28
+ let i = /* @__PURE__ */ new Map(), s = (e, n) => {
29
+ let a = t(e, r.fold);
30
+ if (!a) return;
31
+ let o = i.get(a) ?? /* @__PURE__ */ new Set();
32
+ o.add(n), i.set(a, o);
33
+ };
34
+ for (let t of n) for (let n of e(t)) s(n, t);
35
+ for (let e of r.appLanguages) {
36
+ let t = e.code.toLowerCase().split(/[-_]/)[0] ?? "";
37
+ o(t) && s(e.label, t);
38
+ }
39
+ let c = ["en", ...r.tables.map((e) => e.locale)];
40
+ for (let e of c) for (let t of a(e)) {
41
+ let [e, n] = t.split("\0");
42
+ s(n, e);
43
+ }
44
+ for (let e of r.tables) for (let [t, n] of Object.entries(e.languageNames)) for (let e of n) s(e, t);
45
+ let l = /* @__PURE__ */ new Map();
46
+ for (let [e, t] of i) {
47
+ let [n] = [...t];
48
+ t.size === 1 && n && l.set(e, n);
49
+ }
50
+ return l;
51
+ }
52
+ //#endregion
53
+ export { s as languageNameMap };