@burdenoff/fe-libs 2026.1003.1 → 2026.1003.3

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 (61) hide show
  1. package/dist/chrome/mobileTabBar/selectTabs.d.ts.map +1 -1
  2. package/dist/chrome/mobileTabBar/selectTabs.js +9 -8
  3. package/dist/chrome/sideNavigation/NavItemRenderer.d.ts.map +1 -1
  4. package/dist/chrome/sideNavigation/NavItemRenderer.js +62 -61
  5. package/dist/shared/assistant/conversation.d.ts +20 -6
  6. package/dist/shared/assistant/conversation.d.ts.map +1 -1
  7. package/dist/shared/assistant/history/historyMapping.d.ts.map +1 -1
  8. package/dist/shared/assistant/history/historyMapping.js +43 -24
  9. package/dist/shared/assistant/i18nManifest.d.ts +9 -0
  10. package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
  11. package/dist/shared/assistant/i18nManifest.js +9 -0
  12. package/dist/shared/assistant/index.d.ts +4 -0
  13. package/dist/shared/assistant/index.d.ts.map +1 -1
  14. package/dist/shared/assistant/localUiCommandCopy.d.ts +28 -0
  15. package/dist/shared/assistant/localUiCommandCopy.d.ts.map +1 -1
  16. package/dist/shared/assistant/localUiCommandCopy.js +54 -1
  17. package/dist/shared/assistant/localUiCommands.d.ts +33 -3
  18. package/dist/shared/assistant/localUiCommands.d.ts.map +1 -1
  19. package/dist/shared/assistant/localUiCommands.js +110 -59
  20. package/dist/shared/assistant/prewarm.d.ts +71 -0
  21. package/dist/shared/assistant/prewarm.d.ts.map +1 -1
  22. package/dist/shared/assistant/prewarm.js +49 -2
  23. package/dist/shared/assistant/speech/speechFeed.d.ts +63 -0
  24. package/dist/shared/assistant/speech/speechFeed.d.ts.map +1 -0
  25. package/dist/shared/assistant/speech/speechFeed.js +40 -0
  26. package/dist/shared/assistant/turnTimeline.d.ts +22 -2
  27. package/dist/shared/assistant/turnTimeline.d.ts.map +1 -1
  28. package/dist/shared/assistant/turnTimeline.js +18 -1
  29. package/dist/shared/assistant/turnTimingReport.d.ts.map +1 -1
  30. package/dist/shared/assistant/turnTimingReport.js +5 -4
  31. package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
  32. package/dist/shared/assistant/ui/AssistantChatArea.js +1096 -914
  33. package/dist/shared/assistant/ui/AssistantMarkdownRenderer.d.ts +18 -1
  34. package/dist/shared/assistant/ui/AssistantMarkdownRenderer.d.ts.map +1 -1
  35. package/dist/shared/assistant/ui/AssistantSpeechProvider.d.ts.map +1 -1
  36. package/dist/shared/assistant/ui/AssistantSpeechProvider.js +198 -169
  37. package/dist/shared/assistant/ui/assistantOverlayState.d.ts +2 -1
  38. package/dist/shared/assistant/ui/assistantOverlayState.d.ts.map +1 -1
  39. package/dist/shared/assistant/ui/assistantOverlayState.js +1 -7
  40. package/dist/shared/assistant/ui/useVoiceSession.d.ts.map +1 -1
  41. package/dist/shared/assistant/ui/useVoiceSession.js +165 -153
  42. package/dist/shared/assistant/uiActions/backStack.d.ts +35 -0
  43. package/dist/shared/assistant/uiActions/backStack.d.ts.map +1 -0
  44. package/dist/shared/assistant/uiActions/backStack.js +28 -0
  45. package/dist/shared/assistant/uiActions/navigateAction.d.ts +41 -0
  46. package/dist/shared/assistant/uiActions/navigateAction.d.ts.map +1 -0
  47. package/dist/shared/assistant/uiActions/navigateAction.js +40 -0
  48. package/dist/shared/assistant/uiActions/navigationOutcome.d.ts +52 -0
  49. package/dist/shared/assistant/uiActions/navigationOutcome.d.ts.map +1 -0
  50. package/dist/shared/assistant/uiActions/navigationOutcome.js +61 -0
  51. package/dist/shared/assistant/voice/speakableText.d.ts +16 -1
  52. package/dist/shared/assistant/voice/speakableText.d.ts.map +1 -1
  53. package/dist/shared/assistant/voice/speakableText.js +116 -102
  54. package/dist/shared/assistant/voice/voiceSession.d.ts +12 -0
  55. package/dist/shared/assistant/voice/voiceSession.d.ts.map +1 -1
  56. package/dist/shared/assistant/voice/voiceSession.js +6 -0
  57. package/dist/shared/navigation/navTargetPath.d.ts +23 -0
  58. package/dist/shared/navigation/navTargetPath.d.ts.map +1 -0
  59. package/dist/shared/navigation/navTargetPath.js +6 -0
  60. package/dist/shared-assistant.js +154 -150
  61. package/package.json +1 -1
@@ -33,5 +33,58 @@ function c(e, t, i) {
33
33
  return `${r(e ?? "", { page: a(t) })}\n\n${n.join("\n")}`;
34
34
  });
35
35
  }
36
+ var l = (e) => [e("localCommand.opened", "Opened {{page}}."), "Opened {{page}}."], u = (e) => [e("localCommand.redirected", "{{page}} didn't open. You're on {{landed}} instead."), "{{page}} didn't open. You're on {{landed}} instead."], d = (e) => [e("localCommand.notOpened", "Couldn't open {{page}}."), "Couldn't open {{page}}."], f = (e) => [e("localCommand.newTab", "{{page}} opens in a separate tab. If nothing opened, use this link: {{link}}"), "{{page}} opens in a separate tab. If nothing opened, use this link: {{link}}"], p = (e) => [e("localCommand.backDone", "Back on {{page}}."), "Back on {{page}}."], m = (e) => [e("localCommand.linkNotOpenable", "I can't open that link from here."), "I can't open that link from here."], h = (e) => [e("localCommand.chooseLinked", "My last reply links more than one page. Which one?"), "My last reply links more than one page. Which one?"], g = (e) => [e("localCommand.pickFromList", "Pick one of the pages listed above."), "Pick one of the pages listed above."], _ = (e) => [e("localCommand.previousPage", "the previous page"), "the previous page"], v = (e) => [e("localCommand.anotherPage", "another page"), "another page"];
37
+ function y(e, t, i, o = () => ({})) {
38
+ let s = [t], c = Object.entries(i).map(([t, { label: n, fallback: r }]) => ({
39
+ name: t,
40
+ label: n,
41
+ index: n ? -1 : s.push(r(e)) - 1
42
+ }));
43
+ return n(s, (e) => {
44
+ let t = {};
45
+ for (let n of c) t[n.name] = a(n.label ? n.label : e[n.index] ?? "");
46
+ return r(e[0] ?? "", {
47
+ ...t,
48
+ ...o(t)
49
+ });
50
+ });
51
+ }
52
+ function b(e, t, n) {
53
+ let r = {
54
+ label: n.page,
55
+ fallback: v
56
+ };
57
+ switch (t.status) {
58
+ case "arrived": return y(e, l(e), { page: r });
59
+ case "redirected": return y(e, u(e), {
60
+ page: r,
61
+ landed: {
62
+ label: n.landed,
63
+ fallback: v
64
+ }
65
+ });
66
+ case "new-tab": return y(e, f(e), { page: r }, ({ page: e }) => ({ link: n.path ? `[${e ?? ""}](${o(n.path)})` : e ?? "" }));
67
+ case "refused":
68
+ case "unconfirmed": return y(e, d(e), { page: r });
69
+ }
70
+ }
71
+ function x(e, t) {
72
+ return y(e, p(e), { page: {
73
+ label: t,
74
+ fallback: _
75
+ } });
76
+ }
77
+ function S(e) {
78
+ return n([m(e)], ([e]) => e ?? "");
79
+ }
80
+ function C(e, t) {
81
+ return n([h(e)], ([e]) => {
82
+ let n = t.map((e, t) => `${t + 1}. [${a(e.label)}](${o(e.path)})${e.context ? ` — ${a(e.context)}` : ""}`);
83
+ return `${e ?? ""}\n\n${n.join("\n")}`;
84
+ });
85
+ }
86
+ function w(e) {
87
+ return n([g(e)], ([e]) => e ?? "");
88
+ }
36
89
  //#endregion
37
- export { c as chooseDestinationCopy, s as navigationCommandCopy, i as themeCommandCopy };
90
+ export { x as backDoneCopy, c as chooseDestinationCopy, C as chooseLinkedCopy, S as linkNotOpenableCopy, s as navigationCommandCopy, b as navigationOutcomeCopy, w as pickFromListCopy, i as themeCommandCopy };
@@ -37,7 +37,13 @@ export type ThemeRequest = {
37
37
  export interface LocalDestination {
38
38
  id: string;
39
39
  label: string;
40
+ /**
41
+ * Where the SIDEBAR takes the person (`navTargetPath`): a parent entry opens
42
+ * its home path or first child, not necessarily its own `path`.
43
+ */
40
44
  path: string;
45
+ /** The entry's own `path`, when it differs from `path` ("you are here" matches either). */
46
+ aliases?: string[];
41
47
  /** The parent entry's label, shown when two destinations share a label. */
42
48
  context?: string;
43
49
  /** The sidebar group's id: a word a person may say ("workspace settings"), never shown. */
@@ -61,6 +67,14 @@ export type LocalUiCommand = {
61
67
  */
62
68
  | {
63
69
  kind: "conversation-delete";
70
+ }
71
+ /**
72
+ * ★ BOFF-8060 (R2): "go back" — undo the assistant's OWN last navigation.
73
+ * Only ever returned when the caller said it is runnable
74
+ * (`LocalUiCommandContext.backRunnable`).
75
+ */
76
+ | {
77
+ kind: "back";
64
78
  };
65
79
  /**
66
80
  * `canonical`, with courtesy words at either end removed, so "Could you switch
@@ -70,6 +84,7 @@ export type LocalUiCommand = {
70
84
  export declare function normaliseUtterance(text: string, options?: {
71
85
  keepEnding?: boolean;
72
86
  }): string;
87
+ export declare function singularVariants(words: string): string[];
73
88
  /** Per-product tuning of the grammar (see `AssistantProductCapabilities`). */
74
89
  export interface LocalUiCommandOptions {
75
90
  /**
@@ -79,19 +94,34 @@ export interface LocalUiCommandOptions {
79
94
  * theme. Default `any`.
80
95
  */
81
96
  themeWords?: "any" | "mode-only";
97
+ /**
98
+ * The language the sentence was typed or said in (a BCP-47 tag or the
99
+ * assistant's code). Plural/singular page matching (BOFF-8247) is English
100
+ * grammar: it applies only when this is absent or English.
101
+ */
102
+ locale?: string;
103
+ }
104
+ /**
105
+ * What only the panel knows at the moment of sending. Optional, so every
106
+ * caller without one behaves exactly as v1 did.
107
+ */
108
+ export interface LocalUiCommandContext {
109
+ /** "go back" can be carried out now (see `isBackRunnable`). */
110
+ backRunnable?: boolean;
82
111
  }
83
112
  /**
84
113
  * The command this whole utterance is, or null to send it to the model.
85
114
  * `destinations` is what the person can see in the app's navigation.
86
115
  */
87
- export declare function matchLocalUiCommand(text: string, destinations: readonly LocalDestination[], options?: LocalUiCommandOptions): LocalUiCommand | null;
116
+ export declare function matchLocalUiCommand(text: string, destinations: readonly LocalDestination[], options?: LocalUiCommandOptions, context?: LocalUiCommandContext): LocalUiCommand | null;
88
117
  /** The shape of a navigation entry this needs (`VisibleNavItem` fits it). */
89
118
  export interface NavEntryLike {
90
119
  id: string;
91
120
  label: string;
92
121
  path: string;
93
- group?: string;
94
- children?: readonly NavEntryLike[];
122
+ homePath?: string | undefined;
123
+ group?: string | undefined;
124
+ children?: readonly NavEntryLike[] | undefined;
95
125
  }
96
126
  /**
97
127
  * Every in-app place in a navigation tree, children included. Only real
@@ -1 +1 @@
1
- {"version":3,"file":"localUiCommands.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/localUiCommands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAC3C,6EAA6E;AAC7E,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,eAAe,GAAG,QAAQ,CAAC;AAEpF,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC;AAEzC,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2FAA2F;IAC3F,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,WAAW,EAAE,gBAAgB,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,gBAAgB,EAAE,CAAA;CAAE;AAC/E;;;;GAIG;GACD;IAAE,IAAI,EAAE,qBAAqB,CAAA;CAAE,CAAC;AAwBpC;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GACrC,MAAM,CAeR;AA6KD,8EAA8E;AAC9E,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,KAAK,GAAG,WAAW,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,SAAS,gBAAgB,EAAE,EACzC,OAAO,GAAE,qBAA0B,GAClC,cAAc,GAAG,IAAI,CAoCvB;AAED,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CACpC;AAKD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,MAAM,CAAC,EAAE,MAAM,GACd,gBAAgB,EAAE,CAuBpB;AAID,0CAA0C;AAC1C,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;AAE3D;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,WAAW,CAAA;CAAE,GACpD;IAAE,cAAc,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,cAAc,CAAA;CAAE,CAOnD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAapE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,gBAAgB,EAC7B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,SAAS,gBAAgB,EAAE,GACxC,OAAO,CAST"}
1
+ {"version":3,"file":"localUiCommands.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/localUiCommands.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,18 @@
1
+ import { navTargetPath as e } from "../navigation/navTargetPath.js";
1
2
  //#region src/shared/assistant/localUiCommands.ts
2
- var e = /^(?:(?: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 ?)/, t = /^(?:(?:hey|hi|so|ok|okay)\W+)*(?:please\W+)?(?:can|could|would|will) (?:you|u)\b/i, n = / (?:please|pls|for me|now|thanks|thank you|right now)$/;
3
- function r(e) {
3
+ var t = /^(?:(?: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 ?)/, n = /^(?:(?:hey|hi|so|ok|okay)\W+)*(?:please\W+)?(?:can|could|would|will) (?:you|u)\b/i, r = / (?:please|pls|for me|now|thanks|thank you|right now)$/;
4
+ function i(e) {
4
5
  return e.normalize("NFKC").toLowerCase().replace(/&/g, " and ").replace(/[^\p{L}\p{N}\s]/gu, " ").replace(/\s+/g, " ").trim();
5
6
  }
6
- function i(t, i = {}) {
7
- let a = r(t).replace(/\b(?:um+|uh+|erm|er|hmm+)\b/g, " ").replace(/\s+/g, " ").replace(/\b(\w+)(?: \1\b)+/g, "$1").trim();
7
+ function a(e, n = {}) {
8
+ let a = i(e).replace(/\b(?:um+|uh+|erm|er|hmm+)\b/g, " ").replace(/\s+/g, " ").replace(/\b(\w+)(?: \1\b)+/g, "$1").trim();
8
9
  for (;;) {
9
- let t = a.replace(e, "");
10
- if (i.keepEnding || (t = t.replace(n, "")), t = t.trim(), t === a) return a;
11
- a = t;
10
+ let e = a.replace(t, "");
11
+ if (n.keepEnding || (e = e.replace(r, "")), e = e.trim(), e === a) return a;
12
+ a = e;
12
13
  }
13
14
  }
14
- var a = {
15
+ var o = {
15
16
  light: {
16
17
  kind: "family",
17
18
  family: "light"
@@ -52,27 +53,27 @@ var a = {
52
53
  kind: "named",
53
54
  theme: "system"
54
55
  }
55
- }, o = "(light|dark|forest|ocean|sunset|high contrast|highcontrast|system|device)", s = "(?:(?:the|my) )?(?:(?:app|ui|screen|display|interface|site) )?(?:theme|colou?r scheme|colou?r mode|appearance)", c = "(mode|theme|colou?r scheme|colou?r mode|appearance)", l = "(?:switch|change|set|turn|put|make|flip)", u = [
56
- { pattern: RegExp(`^(?:${l}(?: (?:over|back))? (?:to|into) |go (?:back )?to |(?:turn|switch) on |(?:use|enable|activate|apply|try|turn|switch|set) )?(?:(?:the|a) )?${o} ${c}(?: on)?$`) },
57
- { pattern: RegExp(`^${l} ${s} (?:to|into|back to) (?:(?:the|a) )?${o}(?: ${c})?$`) },
56
+ }, s = "(light|dark|forest|ocean|sunset|high contrast|highcontrast|system|device)", c = "(?:(?:the|my) )?(?:(?:app|ui|screen|display|interface|site) )?(?:theme|colou?r scheme|colou?r mode|appearance)", l = "(mode|theme|colou?r scheme|colou?r mode|appearance)", u = "(?:switch|change|set|turn|put|make|flip)", d = [
57
+ { pattern: RegExp(`^(?:${u}(?: (?:over|back))? (?:to|into) |go (?:back )?to |(?:turn|switch) on |(?:use|enable|activate|apply|try|turn|switch|set) )?(?:(?:the|a) )?${s} ${l}(?: on)?$`) },
58
+ { pattern: RegExp(`^${u} ${c} (?:to|into|back to) (?:(?:the|a) )?${s}(?: ${l})?$`) },
58
59
  { pattern: /^(?:switch|change|go)(?: back)? to (light|dark)()$/ },
59
60
  {
60
- pattern: RegExp(`^(?:(?:turn|switch) off|disable|deactivate|exit|leave) (?:the )?(light|dark) ${c}$`),
61
+ pattern: RegExp(`^(?:(?:turn|switch) off|disable|deactivate|exit|leave) (?:the )?(light|dark) ${l}$`),
61
62
  invert: !0
62
63
  },
63
64
  {
64
- pattern: RegExp(`^(?:(?:turn|switch|set) )?(?:the )?(light|dark) ${c} off$`),
65
+ pattern: RegExp(`^(?:(?:turn|switch|set) )?(?:the )?(light|dark) ${l} off$`),
65
66
  invert: !0
66
67
  },
67
68
  { pattern: /^(?:set|make|change) (?:the |my )?(?:theme|appearance) (?:to )?(?:follow|match|use) (?:my|the) (device|system|os)()(?: (?:theme|appearance))?$/ },
68
69
  { pattern: /^(?:follow|match|use) (?:my|the) (device|system|os)() (?:theme|appearance)$/ },
69
70
  { pattern: /^(?:turn on|switch on|enable|use|activate|switch to) (?:the )?(high contrast|highcontrast)()$/ }
70
71
  ];
71
- function d(e) {
72
- for (let { pattern: t, invert: n } of u) {
72
+ function f(e) {
73
+ for (let { pattern: t, invert: n } of d) {
73
74
  let r = t.exec(e);
74
75
  if (!r) continue;
75
- let i = a[r[1] ?? ""];
76
+ let i = o[r[1] ?? ""];
76
77
  if (i) return i.kind === "named" && i.theme === "system" && r[2] === "mode" ? null : n ? i.kind === "family" ? {
77
78
  kind: "family",
78
79
  family: i.family === "dark" ? "light" : "dark"
@@ -80,63 +81,112 @@ function d(e) {
80
81
  }
81
82
  return null;
82
83
  }
83
- var f = /^(?:delete|remove|erase) (?:this|the|my|the current) conversation$/, p = /^(?:(?:(?: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+(.+)$/, m = /^(?:the )?(.+) (?:page|screen)$/, h = /(?:^| )(?:tasks?|issues?|tickets?|orders?|invoices?|alerts?|requests?|jobs?|incidents?|bugs?|cases?|deals?|items?|questions?|sessions?|positions?|pull requests?|prs?|work orders?|approvals?|actions?|applications?)$/, g = /^(?:ai|a i|api|a p i|id|data|source|access|banking|graph|search|telemetry|stack|house|field|fields|space|market|mic)$/, _ = / (?:page|screen|section|tab)$/;
84
- function v(e) {
84
+ var p = /^(?:delete|remove|erase) (?:this|the|my|the current) conversation$/, m = [
85
+ /^go back$/,
86
+ /^(?:take|bring) me back$/,
87
+ /^(?:(?:go|take me) )?back to the (?:previous|last) (?:page|screen)$/,
88
+ /^(?:the )?previous page$/,
89
+ /^go back to where i was$/
90
+ ], h = /^(?:(?:(?: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+(.+)$/, g = /^(?:the )?(.+) (?:page|screen)$/, _ = /(?:^| )(?:tasks?|issues?|tickets?|orders?|invoices?|alerts?|requests?|jobs?|incidents?|bugs?|cases?|deals?|items?|questions?|sessions?|positions?|pull requests?|prs?|work orders?|approvals?|actions?|applications?)$/, v = /^(?:ai|a i|api|a p i|id|data|source|access|banking|graph|search|telemetry|stack|house|field|fields|space|market|mic)$/, y = / (?:page|screen|section|tab)$/;
91
+ function b(e) {
85
92
  let t = /* @__PURE__ */ new Map(), n = (e, n) => {
86
93
  if (!e) return;
87
94
  let r = t.get(e) ?? [];
88
95
  r.some((e) => e.path === n.path) || r.push(n), t.set(e, r);
89
96
  };
90
97
  for (let t of e) {
91
- let e = r(t.label);
92
- n(e, t), t.context && n(`${r(t.context)} ${e}`, t), t.group && n(`${r(t.group)} ${e}`, t);
98
+ let e = i(t.label);
99
+ n(e, t), t.context && n(`${i(t.context)} ${e}`, t), t.group && n(`${i(t.group)} ${e}`, t);
93
100
  }
94
101
  for (let [e, r] of [...t]) for (let t of r) n(`\u0000${e.replace(/ /g, "")}`, t);
95
102
  return t;
96
103
  }
97
- function y(e, t) {
98
- let n = p.exec(e) ?? m.exec(e);
99
- if (!n) return null;
100
- let r = n[1] ?? "", i = e.startsWith("show me "), a = /^open /.test(e), o = r.replace(/^(?:the|my|our) /, ""), s = o.replace(_, ""), c = s !== o || m.test(e);
101
- if (i && !c || a && o === r && !c && (h.test(o) || g.test(o) || /^\w{1,3}$/.test(o))) return null;
102
- let l = v(t), u = (e) => l.get(e) ?? l.get(`\u0000${e.replace(/ /g, "")}`), d = u(o) ?? (s === o ? void 0 : u(s));
103
- return !d || d.length === 0 ? null : d.length === 1 ? {
104
+ var x = new Set([
105
+ "news",
106
+ "series",
107
+ "species",
108
+ "lens",
109
+ "bus",
110
+ "gas",
111
+ "plus",
112
+ "this",
113
+ "analysis",
114
+ "status",
115
+ "campus",
116
+ "canvas",
117
+ "access",
118
+ "business",
119
+ "address",
120
+ "process",
121
+ "progress"
122
+ ]);
123
+ function S(e) {
124
+ let t = e.split(" "), n = t.pop() ?? "";
125
+ if (n.length < 3) return [];
126
+ let r = /* @__PURE__ */ new Set();
127
+ return x.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(" "));
128
+ }
129
+ function C(e, t, n) {
130
+ let r = h.exec(e) ?? g.exec(e);
131
+ if (!r) return null;
132
+ let i = r[1] ?? "", a = e.startsWith("show me "), o = /^open /.test(e), s = i.replace(/^(?:the|my|our) /, ""), c = s.replace(y, ""), l = c !== s || g.test(e);
133
+ if (a && !l || o && s === i && !l && (_.test(s) || v.test(s) || /^\w{1,3}$/.test(s))) return null;
134
+ let u = b(t), d = (e) => {
135
+ let t = u.get(e);
136
+ if (t) return {
137
+ key: e,
138
+ list: t
139
+ };
140
+ let n = `\u0000${e.replace(/ /g, "")}`, r = u.get(n);
141
+ return r ? {
142
+ key: n,
143
+ list: r
144
+ } : void 0;
145
+ }, f = c === s ? [s] : [s, c], p = f.reduce((e, t) => e ?? d(t), void 0);
146
+ if (!p && n && (p = f.flatMap(S).reduce((e, t) => e ?? d(t), void 0)), !p || p.list.length === 0) return null;
147
+ let m = p.list;
148
+ return m.length === 1 ? {
104
149
  kind: "navigate",
105
- destination: d[0]
150
+ destination: m[0]
106
151
  } : {
107
152
  kind: "choose-destination",
108
- query: s,
109
- candidates: d
153
+ query: c,
154
+ candidates: m
110
155
  };
111
156
  }
112
- function b(e, n, r = {}) {
113
- let a = e.normalize("NFKC").trim();
114
- if (/[\p{Extended_Pictographic}\p{So}]/u.test(a) || /(?:^|\s)>?[:;=][-'^]?[()[\]/\\|pPdDoO3*@$]+(?=\s|$)/.test(a) || /(?:^|\s)(?:xD|XD|-_-|T_T|<\/?3)(?=\s|$)/.test(a) || /[?¿؟][^\p{L}\p{N}]*$/u.test(a) && !t.test(a)) return null;
115
- let o = i(e);
116
- if (!o || o.length > 80) return null;
117
- if (f.test(o)) return { kind: "conversation-delete" };
118
- let s = d(o);
119
- return s ? r.themeWords === "mode-only" && /\b(?:theme|appearance|colou?r scheme)\b/.test(o) && !/\b(?:app|ui|interface)\b/.test(o) ? null : {
157
+ var w = (e) => e === void 0 || /^en(?:[-_]|$)/i.test(e.trim());
158
+ function T(e, t, r = {}, i = {}) {
159
+ let o = e.normalize("NFKC").trim();
160
+ if (/[\p{Extended_Pictographic}\p{So}]/u.test(o) || /(?:^|\s)>?[:;=][-'^]?[()[\]/\\|pPdDoO3*@$]+(?=\s|$)/.test(o) || /(?:^|\s)(?:xD|XD|-_-|T_T|<\/?3)(?=\s|$)/.test(o) || /[?¿؟][^\p{L}\p{N}]*$/u.test(o) && !n.test(o)) return null;
161
+ let s = a(e);
162
+ if (!s || s.length > 80) return null;
163
+ if (p.test(s)) return { kind: "conversation-delete" };
164
+ let c = f(s);
165
+ if (c) return r.themeWords === "mode-only" && /\b(?:theme|appearance|colou?r scheme)\b/.test(s) && !/\b(?:app|ui|interface)\b/.test(s) ? null : {
120
166
  kind: "theme",
121
- request: s
122
- } : y(i(e, { keepEnding: !0 }), n) ?? y(o, n);
167
+ request: c
168
+ };
169
+ if (i.backRunnable && m.some((e) => e.test(s))) return { kind: "back" };
170
+ let l = w(r.locale);
171
+ return C(a(e, { keepEnding: !0 }), t, l) ?? C(s, t, l);
123
172
  }
124
- var x = /^__nav_more__:/;
125
- function S(e, t) {
126
- let n = [];
127
- for (let r of e) {
128
- let e = x.test(r.id);
129
- !e && r.path.startsWith("/") && !r.path.startsWith("//") && r.label.trim() && n.push({
130
- id: r.id,
131
- label: r.label,
132
- path: r.path,
133
- ...t ? { context: t } : {},
134
- ...r.group ? { group: r.group } : {}
135
- }), r.children?.length && n.push(...S(r.children, e ? t : r.label));
173
+ var E = /^__nav_more__:/;
174
+ function D(t, n) {
175
+ let r = [];
176
+ for (let i of t) {
177
+ let t = E.test(i.id), a = e(i);
178
+ !t && i.path.startsWith("/") && !i.path.startsWith("//") && a.startsWith("/") && !a.startsWith("//") && i.label.trim() && r.push({
179
+ id: i.id,
180
+ label: i.label,
181
+ path: a,
182
+ ...a === i.path ? {} : { aliases: [i.path] },
183
+ ...n ? { context: n } : {},
184
+ ...i.group ? { group: i.group } : {}
185
+ }), i.children?.length && r.push(...D(i.children, t ? n : i.label));
136
186
  }
137
- return n;
187
+ return r;
138
188
  }
139
- function C(e, t) {
189
+ function O(e, t) {
140
190
  return e.kind === "family" ? {
141
191
  alreadyApplied: t.resolvedTheme === e.family,
142
192
  mode: e.family
@@ -145,7 +195,7 @@ function C(e, t) {
145
195
  mode: e.theme
146
196
  };
147
197
  }
148
- function w(e, t) {
198
+ function k(e, t) {
149
199
  let n = (e) => {
150
200
  let [t = ""] = e.split("#"), [n = "", r = ""] = t.split("?"), i = n.length > 1 ? n.replace(/\/+$/, "") : n, a = new URLSearchParams(r);
151
201
  return a.sort(), {
@@ -155,10 +205,11 @@ function w(e, t) {
155
205
  }, r = n(e), i = n(t);
156
206
  return r.pathname === i.pathname ? r.query === "" || r.query === i.query : !1;
157
207
  }
158
- function T(e, t, n) {
159
- return w(e.path, t) ? e.path.includes("?") ? !0 : !n.some((n) => n.path !== e.path && n.path.includes("?") && E(n.path, t)) : !1;
208
+ function A(e, t, n) {
209
+ let r = [e.path, ...e.aliases ?? []].find((e) => k(e, t));
210
+ return r === void 0 ? !1 : r.includes("?") ? !0 : !n.some((e) => e.path !== r && e.path.includes("?") && j(e.path, t));
160
211
  }
161
- function E(e, t) {
212
+ function j(e, t) {
162
213
  let n = (e) => {
163
214
  let [t = ""] = e.split("#"), [n = "", r = ""] = t.split("?");
164
215
  return {
@@ -171,4 +222,4 @@ function E(e, t) {
171
222
  return !0;
172
223
  }
173
224
  //#endregion
174
- export { T as isAlreadyThere, w as isCurrentPath, b as matchLocalUiCommand, S as navDestinations, i as normaliseUtterance, C as planThemeChange };
225
+ export { A as isAlreadyThere, k as isCurrentPath, T as matchLocalUiCommand, D as navDestinations, a as normaliseUtterance, O as planThemeChange, S as singularVariants };
@@ -171,4 +171,75 @@ export declare function settleWarmBeforeSend(workspaceId: string, mode: Assistan
171
171
  export declare function consumeWarm(workspaceId: string, mode: AssistantMode, sandboxId: string): boolean;
172
172
  /** Tests only: forget every warm. */
173
173
  export declare function resetWarmsForTest(): void;
174
+ /** A pre-opened session no send has used is forgotten after this long. */
175
+ export declare const PREOPEN_MAX_AGE_MS: number;
176
+ /** At most this many in total; the oldest is evicted first. */
177
+ export declare const PREOPEN_MAX_ENTRIES = 8;
178
+ /**
179
+ * The key of a pre-opened session. All four parts matter: a session belongs to
180
+ * one sandbox, which belongs to one workspace, and carries one mode's docs
181
+ * note; the user is in the key so a switch of account never matches.
182
+ */
183
+ export declare function preopenKey(parts: {
184
+ workspaceId: string;
185
+ mode: AssistantMode;
186
+ sandboxId: string;
187
+ userId: string | null | undefined;
188
+ }): string;
189
+ export interface PreopenWantedInput {
190
+ /**
191
+ * The conversation the send would continue, if any. Absent: the send starts
192
+ * a conversation of its own (a voice session's, or none open).
193
+ */
194
+ active?: {
195
+ mode: AssistantMode;
196
+ backendSessionId?: string | null | undefined;
197
+ /** False for a read-only or another scope's conversation: never continued. */
198
+ continuable: boolean;
199
+ hasHistory: boolean;
200
+ } | undefined;
201
+ /** The mode the warm prepared. */
202
+ mode: AssistantMode;
203
+ }
204
+ /**
205
+ * Would the send this warm anticipates have to CREATE a session? Pure.
206
+ *
207
+ * True only when it would: no conversation is open, the open one is never
208
+ * continued, a conversation with history is open in another mode (the send
209
+ * starts a new one), or the conversation holds no session. A follow-up in a
210
+ * conversation that already holds a session issues no `POST /sessions`, so a
211
+ * pre-open there would only leave a session nobody adopts.
212
+ */
213
+ export declare function preopenWanted(input: PreopenWantedInput): boolean;
214
+ /**
215
+ * Open a session ahead of the send, at most once per key. `create` is called
216
+ * synchronously (the request is on the wire at once) and may throw or reject:
217
+ * a failed pre-open is silent, and the send creates its own session as today.
218
+ */
219
+ export declare function startPreopen(key: string, create: () => Promise<string>, now: number): void;
220
+ /**
221
+ * Take the pre-opened session for `key`. Atomic and single-use: the entry is
222
+ * deleted on claim, so a second claimer gets null. `ready` is adopted at once,
223
+ * `pending` is awaited (null if it fails), and a failed or absent one is null.
224
+ */
225
+ export declare function claimPreopenedSession(key: string, now: number): {
226
+ sessionId: string;
227
+ } | {
228
+ pending: Promise<string | null>;
229
+ } | null;
230
+ /** A sandbox was proved dead, cleared or retired: nothing opened on it is adopted. */
231
+ export declare function dropPreopenedFor(sandboxId: string): void;
232
+ /**
233
+ * The sandboxes a panel has proved dead (`deadSandboxIds`), which it never
234
+ * selects again. Adding one ALSO drops every session pre-opened on it, so that
235
+ * invariant holds at every site that quarantines a sandbox — the probe, the
236
+ * warm, the release, the replace and the failover — without each having to
237
+ * remember to say so. Every `clearSandbox` and `retireSandbox` site in the
238
+ * panel quarantines first, so none can leave a pre-opened session behind.
239
+ */
240
+ export declare class QuarantineSet extends Set<string> {
241
+ add(sandboxId: string): this;
242
+ }
243
+ /** Tests only: how many are held. */
244
+ export declare function preopenedCountForTest(): number;
174
245
  //# sourceMappingURL=prewarm.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prewarm.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/prewarm.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prewarm.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/prewarm.ts"],"names":[],"mappings":"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"}
@@ -110,7 +110,54 @@ function p(e, t, n) {
110
110
  }
111
111
  function m() {
112
112
  for (let e of a.values()) e.controller.abort();
113
- a.clear(), o.clear(), s.clear(), c.clear();
113
+ a.clear(), o.clear(), s.clear(), c.clear(), _.clear();
114
+ }
115
+ var h = 10 * 6e4, g = 8, _ = /* @__PURE__ */ new Map();
116
+ function v(e) {
117
+ return [
118
+ e.workspaceId,
119
+ e.mode,
120
+ e.sandboxId,
121
+ e.userId ?? ""
122
+ ].join("\0");
123
+ }
124
+ function y(e) {
125
+ let { active: t, mode: n } = e;
126
+ return !t || !t.continuable || t.mode !== n && t.hasHistory ? !0 : !t.backendSessionId;
127
+ }
128
+ function b(e) {
129
+ for (let [t, n] of _) e - n.createdAt > 6e5 && _.delete(t);
130
+ }
131
+ function x(e, t, n) {
132
+ if (b(n), _.has(e)) return;
133
+ for (; _.size >= 8;) {
134
+ let e = _.keys().next();
135
+ if (e.done) break;
136
+ _.delete(e.value);
137
+ }
138
+ let r = {
139
+ key: e,
140
+ state: "pending",
141
+ createdAt: n,
142
+ ready: Promise.resolve(null)
143
+ };
144
+ r.ready = new Promise((e) => e(t())).then((e) => (r.state = "ready", r.sessionId = e, e), () => (r.state = "failed", null)), _.set(e, r);
145
+ }
146
+ function S(e, t) {
147
+ b(t);
148
+ let n = _.get(e);
149
+ return n ? (_.delete(e), n.state === "ready" && n.sessionId ? { sessionId: n.sessionId } : n.state === "pending" ? { pending: n.ready } : null) : null;
150
+ }
151
+ function C(e) {
152
+ for (let t of [..._.keys()]) t.split("\0")[2] === e && _.delete(t);
153
+ }
154
+ var w = class extends Set {
155
+ add(e) {
156
+ return C(e), super.add(e);
157
+ }
158
+ };
159
+ function T() {
160
+ return _.size;
114
161
  }
115
162
  //#endregion
116
- export { n as PREWARM_COOLDOWN_MS, i as WarmCancelled, p as consumeWarm, r as prewarmTarget, m as resetWarmsForTest, f as settleWarmBeforeSend, d as startWarm, u as warmState };
163
+ export { h as PREOPEN_MAX_AGE_MS, g as PREOPEN_MAX_ENTRIES, n as PREWARM_COOLDOWN_MS, w as QuarantineSet, i as WarmCancelled, S as claimPreopenedSession, p as consumeWarm, C as dropPreopenedFor, v as preopenKey, y as preopenWanted, T as preopenedCountForTest, r as prewarmTarget, m as resetWarmsForTest, f as settleWarmBeforeSend, x as startPreopen, d as startWarm, u as warmState };
@@ -0,0 +1,63 @@
1
+ /**
2
+ * The speech feed (BOFF-8062, speed design 5.C / C1): how a finished answer
3
+ * reaches the speech provider BEFORE the turn's bookkeeping is done.
4
+ *
5
+ * Speech used to start on the store's in-flight to complete edge, which comes
6
+ * after the awaited artifacts read and the awaited usage report (~0.5 s in
7
+ * prod). The turn loop knows the answer is complete the moment the poll says
8
+ * so, so at that point — for voice-session turns only — it publishes the exact
9
+ * text `applyAssistantResponse` is about to write, and the provider speaks it.
10
+ *
11
+ * ★ DATA ONLY. This module holds no React, no audio and no store: a publisher
12
+ * (the turn loop) and a subscriber (the provider) that do not know each other,
13
+ * which is what lets it be tested without either.
14
+ *
15
+ * Contract:
16
+ * - `publish` is called only for text the person can already SEE. The poll
17
+ * writes every snapshot's content to the message before it reports done, so
18
+ * rule 4 of the design (never speak what has not been rendered) holds; the
19
+ * one addition `applyAssistantResponse` makes — the "photo not sent" note —
20
+ * is written by the publisher first.
21
+ * - `abort` is called on EVERY exit that follows a publish without completing
22
+ * the turn (abandonment, an error after the answer) — the same rule as the
23
+ * existing "never read a cancelled answer aloud" check.
24
+ * - A subscriber that throws never breaks the turn: speech is never worth an
25
+ * answer (BOFF-7283).
26
+ */
27
+ export interface SpeechFeedItem {
28
+ /** The conversation the message belongs to. */
29
+ conversationId: string;
30
+ channel: "voice" | "chat";
31
+ /** The live voice session that asked, when `channel` is voice. */
32
+ voiceSessionId?: string | undefined;
33
+ /** The reply as `applyAssistantResponse` stores it (sanitised, markdown). */
34
+ text: string;
35
+ /** The turn's reply language, stamped on the message as `metadata.lang`. */
36
+ lang?: string | undefined;
37
+ /** Always true in C1: only a finished answer is published. */
38
+ final: true;
39
+ }
40
+ export type SpeechFeedEvent = {
41
+ type: "publish";
42
+ messageId: string;
43
+ item: SpeechFeedItem;
44
+ } | {
45
+ type: "abort";
46
+ messageId: string;
47
+ };
48
+ type Listener = (event: SpeechFeedEvent) => void;
49
+ export declare const speechFeed: {
50
+ publish(messageId: string, item: SpeechFeedItem): void;
51
+ /** Forget a published message and tell the subscriber to stop speaking it. */
52
+ abort(messageId: string): void;
53
+ subscribe(listener: Listener): () => void;
54
+ /**
55
+ * The item published for `messageId`, if it is still live (not aborted). The
56
+ * voice session reads it to tell THIS turn's reply from any other speech.
57
+ */
58
+ peek(messageId: string): SpeechFeedItem | undefined;
59
+ };
60
+ /** Tests only. */
61
+ export declare function resetSpeechFeedForTest(): void;
62
+ export {};
63
+ //# sourceMappingURL=speechFeed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speechFeed.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/speech/speechFeed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC;IAC1B,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,8DAA8D;IAC9D,KAAK,EAAE,IAAI,CAAC;CACb;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,cAAc,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;AAmBjD,eAAO,MAAM,UAAU;uBACF,MAAM,QAAQ,cAAc,GAAG,IAAI;IAUtD,8EAA8E;qBAC7D,MAAM,GAAG,IAAI;wBAIV,QAAQ,GAAG,MAAM,IAAI;IAMzC;;;OAGG;oBACa,MAAM,GAAG,cAAc,GAAG,SAAS;CAGpD,CAAC;AAEF,kBAAkB;AAClB,wBAAgB,sBAAsB,IAAI,IAAI,CAG7C"}