@burdenoff/fe-libs 2026.1028.4 → 2026.1028.5
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.
- package/dist/shared/assistant/appControls/grammar.d.ts +2 -0
- package/dist/shared/assistant/appControls/grammar.js +101 -93
- package/dist/shared/assistant/appControls/registry.d.ts +2 -0
- package/dist/shared/assistant/appControls/registry.js +20 -12
- package/dist/shared/assistant/commandCompletions.d.ts +9 -0
- package/dist/shared/assistant/commandCompletions.js +161 -0
- package/dist/shared/assistant/index.d.ts +3 -0
- package/dist/shared/assistant/localUiCommands.d.ts +16 -0
- package/dist/shared/assistant/localUiCommands.js +192 -105
- package/dist/shared/assistant/localeCommands/engine.d.ts +6 -0
- package/dist/shared/assistant/localeCommands/engine.js +212 -116
- package/dist/shared/assistant/ui/AssistantChatArea.js +1491 -1406
- package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts +8 -0
- package/dist/shared/assistant/ui/composer/AssistantComposer.js +142 -131
- package/dist/shared/assistant/ui/draftCommandCheck.d.ts +7 -0
- package/dist/shared/assistant/ui/draftCommandCheck.js +17 -0
- package/dist/shared/assistant/uiActions/backStack.d.ts +1 -0
- package/dist/shared/assistant/uiActions/backStack.js +13 -5
- package/dist/shared/assistant/uiActions/deixis.d.ts +2 -0
- package/dist/shared/assistant/uiActions/deixis.js +12 -1
- package/dist/shared/assistant/uiActions/draftPathname.d.ts +13 -0
- package/dist/shared/assistant/uiActions/draftPathname.js +31 -0
- package/dist/shared/assistant/uiActions/recordNames.js +33 -30
- package/dist/shared-assistant.js +329 -326
- package/package.json +1 -1
|
@@ -101,3 +101,5 @@ export declare function queryAsSaid(original: string, canonicalQuery: string): s
|
|
|
101
101
|
* transcribed — queries keep the person's own case and punctuation.
|
|
102
102
|
*/
|
|
103
103
|
export declare function matchAppControl(utterance: string, original: string, snapshot: ControlSnapshot): AppControlMatch | null;
|
|
104
|
+
/** Shared grammar patterns, gated by what the page actually registered. */
|
|
105
|
+
export declare function appControlPrefixPatterns(snapshot: ControlSnapshot): readonly RegExp[];
|
|
@@ -16,37 +16,37 @@ function c(e, t) {
|
|
|
16
16
|
for (let e of i.matchAll(r)) a = e[0];
|
|
17
17
|
return a ?? t;
|
|
18
18
|
}
|
|
19
|
-
var l = 60, u = /^(?:log ?out|sign ?out|(?:log|sign) (?:me )?out(?: of (?:the |my |this )?(?:app|application|account|session))?)$/, d = "(?:workspace|workspaces|context|contexts|organi[sz]ation|organi[sz]ations|org|project)",
|
|
19
|
+
var l = 60, u = /^(?:log ?out|sign ?out|(?:log|sign) (?:me )?out(?: of (?:the |my |this )?(?:app|application|account|session))?)$/, d = "(?:workspace|workspaces|context|contexts|organi[sz]ation|organi[sz]ations|org|project)", ee = "(?:switcher|selector|picker|menu|dropdown|list)", te = /^(?:another|other|a different|different|a new|new|a|the|another one|other one)$/, f = RegExp(`^(?:switch|change|move|go|jump|hop)(?: over)? to ${r}(.+?) ${d}$`), p = RegExp(`^(?:switch|change|move) ${r}${d} (?:to|over to) ${r}(.+)$`), m = RegExp(`^${i} ${r}${d} ${ee}$`), h = RegExp(`^(?:switch|change) ${r}${d}$`), g = RegExp(`^${i} ${r}(?:notification|notifications) (?:panel|bell|centre|center|menu|tray|drawer|list)$`), _ = RegExp(`^${i} ${r}(?:notification )?bell$`), v = RegExp(`^${i} ${r}notifications?$`), y = RegExp(`^${i} ${r}(?:help (?:menu|panel|dialog|dialogue|centre|center)|keyboard shortcuts|keyboard help|shortcuts)$`), b = RegExp(`^${i} ${r}help$`), x = RegExp(`^(?:open|show|start|use|pull up|bring up) ${r}(?:global |app )search(?: (?:bar|box|dialog|dialogue|panel))?$|^(?:open|show|start|use|pull up|bring up) ${r}search (?:bar|box|dialog|dialogue|panel)$`), S = /^(?:open|start|use|pull up|bring up) (?:(?:the|my) )?search$/, C = [
|
|
20
20
|
/^(?:open|start|use|pull up|bring up) (?:(?:the|my) )?(?:global |app )?search (?:for|with) (.+)$/,
|
|
21
21
|
/^(?:global search|search everything|search everywhere|search globally|search the app|search all|search across the app) (?:for )?(.+)$/,
|
|
22
22
|
/^search (?:the app|everything|everywhere|globally|all|across the app) for (.+)$/
|
|
23
|
-
],
|
|
23
|
+
], w = "(?:side ?bar|side menu|side navigation|side nav|navigation (?:bar|menu|panel|drawer)|nav (?:bar|menu|panel|drawer)|left (?:menu|sidebar|panel))", T = RegExp(`^(?:collapse|close|hide|minimi[sz]e|shrink|fold) ${r}${w}$`), E = RegExp(`^(?:expand|open|show|reveal|unhide|bring up|widen|unfold) ${r}${w}$`), D = "(?: (?:group|section|menu|folder|submenu|sub menu|list|dropdown))?", O = RegExp(`^(expand|unfold|open up|open|show) ${r}(.+?)${D}$`), k = RegExp(`^(collapse|fold up|close|hide) ${r}(.+?)${D}$`), A = [
|
|
24
24
|
RegExp(`^(?:change|switch|set|update|turn|put|make)(?: over)? ${r}(?:(?:app|ui|user interface|interface|screen|display|site|system|menu|application) )?language (?:to|into|as|over to) (.+)$`),
|
|
25
25
|
RegExp(`^(?:switch|change|set|put|turn) ${r}(?:app|ui|user interface|interface|screen|display|site|application|menus?) (?:language )?(?:to|into) (.+)$`),
|
|
26
26
|
RegExp(`^(?:show|display|use|run) ${r}(?:app|ui|user interface|interface|screen|display|site|application)(?: menus?)? in (.+)$`)
|
|
27
|
-
],
|
|
27
|
+
], j = RegExp(`^(?:switch|change)(?: over)? to ${r}(.+)$`), M = RegExp(`^${i} ${r}(?:(?:assistant|ai|conversation|conversations|chat) history|history of (?:my )?(?:conversations|chats)|(?:past|previous|old|earlier) conversations)$`), N = RegExp(`^${i} ${r}history$`), P = RegExp(`^${i} ${r}(?:voice|spoken|speech) transcript$`), F = RegExp(`^${i} ${r}transcript$`), ne = RegExp(`^${i} ${r}(?:ai|assistant) preview(?: panel| pane| surface)?$`), I = RegExp(`^${i} ${r}preview(?: panel| pane)?$`), L = RegExp(`^(?:close|hide|dismiss) ${r}(?:ai|assistant) preview(?: panel| pane| surface)?$`), R = RegExp(`^(?:close|hide) ${r}preview(?: panel| pane)?$`), z = /^(?:(?:start|begin|open) (?:a |an |another )?(?:new |fresh |blank )?conversation|new conversation|(?:start|begin) (?:a )?(?:new|fresh) conversation with you)$/, B = [RegExp(`^(?:go to|open|show|show me|switch to|select|view|change to|move to|take me to|bring up) ${r}(.+) tab$`), /^(?:switch|change|move) tabs? to (.+)$/], V = "(?:filter|narrow|limit)(?: down)?", H = [RegExp(`^${V}(?: ${r}(?:page|list|table|results|items|rows|view))? (?:by|to|for|on) ${r}(.+)$`)], U = [/^(?:show|display|list|keep) only (.+)$/, /^only (?:show|display|list|keep) (.+)$/], W = [
|
|
28
28
|
RegExp(`^(?:set|change|switch|put|make) ${r}(.+?) filter (?:to|as|on) (.+)$`),
|
|
29
|
-
RegExp(`^${
|
|
29
|
+
RegExp(`^${V} ${r}(.+?) (?:by|to|for|on) (.+)$`),
|
|
30
30
|
RegExp(`^(?:use|apply) ${r}(.+?) filter (?:of|with|for|set to) (.+)$`)
|
|
31
|
-
],
|
|
31
|
+
], G = RegExp(`^(?:clear|remove|reset|drop|turn off) ${r}(?:(?:all|every) )?(?:(.+?) )?filters?$`), K = [
|
|
32
32
|
[/(?: in)? (?:ascending|asc)(?: order)?$/, "asc"],
|
|
33
33
|
[/(?: in)? (?:descending|desc)(?: order)?$/, "desc"],
|
|
34
34
|
[/ (?:a to z|low to high|lowest first|smallest first|oldest first)$/, "asc"],
|
|
35
35
|
[/ (?:z to a|high to low|highest first|largest first|biggest first|newest first|latest first)$/, "desc"]
|
|
36
|
-
],
|
|
36
|
+
], q = RegExp(`^(?:sort|order|arrange|rank)(?: ${r}(?:page|list|table|results|items|rows|view|it|them))? by (.+)$`), re = K.map(([e]) => new RegExp(q.source.slice(0, -1) + e.source)), J = /^(?:sort|order)(?: it| them)? (ascending|descending|asc|desc)$/, Y = [
|
|
37
37
|
/^(?:search|find|look)(?: (?:this page|the page|the list|the table|this list|this table|here|these|them))? for (.+)$/,
|
|
38
38
|
/^(?:find|search for) (.+?) (?:on|in) (?:this|the) (?:page|list|table)$/,
|
|
39
39
|
/^search (?:this page|the page|the list|the table|here) (?:for )?(.+)$/
|
|
40
|
-
],
|
|
41
|
-
function
|
|
40
|
+
], X = /^(?:clear|reset|empty|remove|stop) (?:the |my |this )?(?:page )?search(?:ing)?$/, Z = [RegExp(`^(?:open|show|start|bring up|pull up) ${r}(.+?) (?:form|dialog|dialogue|modal)$`)], Q = RegExp(`^(?:open|show|start|bring up|pull up) ${r}(.+)$`), ie = /\b(?:and then|then|and also|also|after that|afterwards|and open|and show|and go|and sort|and filter)\b/;
|
|
41
|
+
function $(e, t) {
|
|
42
42
|
for (let n of e) {
|
|
43
43
|
let e = n.exec(t);
|
|
44
44
|
if (e) return e;
|
|
45
45
|
}
|
|
46
46
|
return null;
|
|
47
47
|
}
|
|
48
|
-
function
|
|
49
|
-
for (let [t, n] of
|
|
48
|
+
function ae(e) {
|
|
49
|
+
for (let [t, n] of K) {
|
|
50
50
|
let r = t.exec(e);
|
|
51
51
|
if (r) return {
|
|
52
52
|
field: e.slice(0, r.index).trim(),
|
|
@@ -58,110 +58,110 @@ function Q(e) {
|
|
|
58
58
|
direction: null
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
|
-
function
|
|
61
|
+
function oe(e) {
|
|
62
62
|
let t = e.replace(/\b(?:please|pls)$/, "").trim();
|
|
63
63
|
return !t || t.length > l ? null : t;
|
|
64
64
|
}
|
|
65
|
-
function
|
|
66
|
-
let
|
|
67
|
-
if (
|
|
68
|
-
if (
|
|
69
|
-
if (
|
|
70
|
-
let e =
|
|
71
|
-
if (e &&
|
|
65
|
+
function se(r, i, s) {
|
|
66
|
+
let l = s.registered;
|
|
67
|
+
if (ie.test(r)) return null;
|
|
68
|
+
if (l["account.logout"] && u.test(r)) return a({ control: "account.logout" });
|
|
69
|
+
if (l["header.workspace"] || l["header.context"]) {
|
|
70
|
+
let e = f.exec(r) ?? p.exec(r);
|
|
71
|
+
if (e && l["header.workspace"]) {
|
|
72
72
|
let t = (e[1] ?? "").trim();
|
|
73
|
-
if (t && !
|
|
73
|
+
if (t && !te.test(t)) return a({
|
|
74
74
|
control: "header.workspace",
|
|
75
75
|
target: t
|
|
76
76
|
});
|
|
77
|
-
if (
|
|
77
|
+
if (l["header.context"]) return a({ control: "header.context" });
|
|
78
78
|
}
|
|
79
|
-
if (
|
|
79
|
+
if (l["header.context"] && (m.test(r) || h.test(r))) return a({ control: "header.context" });
|
|
80
80
|
}
|
|
81
|
-
if (
|
|
82
|
-
if (
|
|
83
|
-
if (
|
|
81
|
+
if (l["header.notifications"]) {
|
|
82
|
+
if (g.test(r) || _.test(r)) return a({ control: "header.notifications" });
|
|
83
|
+
if (v.test(r)) return o({ control: "header.notifications" });
|
|
84
84
|
}
|
|
85
|
-
if (
|
|
86
|
-
if (
|
|
87
|
-
if (
|
|
85
|
+
if (l["header.help"]) {
|
|
86
|
+
if (y.test(r)) return a({ control: "header.help" });
|
|
87
|
+
if (b.test(r)) return o({ control: "header.help" });
|
|
88
88
|
}
|
|
89
|
-
if (
|
|
90
|
-
for (let e of
|
|
91
|
-
let t = e.exec(
|
|
89
|
+
if (l["header.search"]) {
|
|
90
|
+
for (let e of C) {
|
|
91
|
+
let t = e.exec(r), n = t ? oe(t[1] ?? "") : null;
|
|
92
92
|
if (n) return a({
|
|
93
93
|
control: "header.search",
|
|
94
|
-
query: c(
|
|
94
|
+
query: c(i, n)
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
|
-
if (
|
|
97
|
+
if (x.test(r)) return a({
|
|
98
98
|
control: "header.search",
|
|
99
99
|
query: null
|
|
100
100
|
});
|
|
101
|
-
if (
|
|
101
|
+
if (S.test(r)) return o({
|
|
102
102
|
control: "header.search",
|
|
103
103
|
query: null
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
|
-
if (
|
|
107
|
-
if (
|
|
106
|
+
if (l.sidebar) {
|
|
107
|
+
if (T.test(r)) return a({
|
|
108
108
|
control: "sidebar",
|
|
109
109
|
collapsed: !0
|
|
110
110
|
});
|
|
111
|
-
if (
|
|
111
|
+
if (E.test(r)) return a({
|
|
112
112
|
control: "sidebar",
|
|
113
113
|
collapsed: !1
|
|
114
114
|
});
|
|
115
|
-
let e =
|
|
116
|
-
if (
|
|
117
|
-
let t = (
|
|
118
|
-
if (t && n(t,
|
|
115
|
+
let e = O.exec(r), t = e ? null : k.exec(r), i = e ?? t;
|
|
116
|
+
if (i && s.sidebarEntries.length > 0) {
|
|
117
|
+
let t = (i[2] ?? "").trim(), r = i[1] ?? "";
|
|
118
|
+
if (t && n(t, s.sidebarEntries).kind !== "none") return {
|
|
119
119
|
request: {
|
|
120
120
|
control: "sidebar.entry",
|
|
121
121
|
name: t,
|
|
122
122
|
expanded: e !== null
|
|
123
123
|
},
|
|
124
|
-
weak: !/^(?:expand|unfold|open up|collapse|fold up)$/.test(
|
|
124
|
+
weak: !/^(?:expand|unfold|open up|collapse|fold up)$/.test(r)
|
|
125
125
|
};
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
if (
|
|
129
|
-
for (let e of
|
|
130
|
-
let n = e.exec(
|
|
128
|
+
if (l.language) {
|
|
129
|
+
for (let e of A) {
|
|
130
|
+
let n = e.exec(r);
|
|
131
131
|
if (!n) continue;
|
|
132
|
-
let
|
|
133
|
-
if (
|
|
132
|
+
let i = t(n[1] ?? "");
|
|
133
|
+
if (i) return a({
|
|
134
134
|
control: "language",
|
|
135
|
-
code:
|
|
135
|
+
code: i
|
|
136
136
|
});
|
|
137
137
|
}
|
|
138
|
-
let e =
|
|
138
|
+
let e = j.exec(r), n = e ? t(e[1] ?? "") : null;
|
|
139
139
|
if (n) return o({
|
|
140
140
|
control: "language",
|
|
141
141
|
code: n
|
|
142
142
|
});
|
|
143
143
|
}
|
|
144
|
-
if (
|
|
145
|
-
if (
|
|
146
|
-
if (
|
|
147
|
-
}
|
|
148
|
-
if (
|
|
149
|
-
if (
|
|
150
|
-
if (
|
|
151
|
-
}
|
|
152
|
-
if (
|
|
153
|
-
if (
|
|
154
|
-
if (
|
|
155
|
-
if (
|
|
156
|
-
if (
|
|
157
|
-
}
|
|
158
|
-
if (
|
|
159
|
-
let
|
|
160
|
-
if (!
|
|
161
|
-
if (
|
|
162
|
-
let e =
|
|
144
|
+
if (l["assistant.history"]) {
|
|
145
|
+
if (M.test(r)) return a({ control: "assistant.history" });
|
|
146
|
+
if (N.test(r)) return o({ control: "assistant.history" });
|
|
147
|
+
}
|
|
148
|
+
if (l["assistant.transcript"]) {
|
|
149
|
+
if (P.test(r)) return a({ control: "assistant.transcript" });
|
|
150
|
+
if (F.test(r)) return o({ control: "assistant.transcript" });
|
|
151
|
+
}
|
|
152
|
+
if (l["assistant.preview"]) {
|
|
153
|
+
if (ne.test(r)) return a({ control: "assistant.preview" });
|
|
154
|
+
if (I.test(r)) return o({ control: "assistant.preview" });
|
|
155
|
+
if (L.test(r)) return a({ control: "assistant.preview.close" });
|
|
156
|
+
if (R.test(r)) return o({ control: "assistant.preview.close" });
|
|
157
|
+
}
|
|
158
|
+
if (l["assistant.conversation.new"] && z.test(r)) return a({ control: "assistant.conversation.new" });
|
|
159
|
+
let d = s.page;
|
|
160
|
+
if (!d) return null;
|
|
161
|
+
if (d.tabs.length > 0) {
|
|
162
|
+
let e = $(B, r), t = e ? (e[1] ?? "").trim() : "";
|
|
163
163
|
if (t) {
|
|
164
|
-
let e = n(t,
|
|
164
|
+
let e = n(t, d.tabs).kind !== "none";
|
|
165
165
|
return {
|
|
166
166
|
request: {
|
|
167
167
|
control: "page.tab",
|
|
@@ -171,30 +171,30 @@ function ne(s, l, x) {
|
|
|
171
171
|
};
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
|
-
if (
|
|
175
|
-
let e =
|
|
174
|
+
if (d.filters.length > 0) {
|
|
175
|
+
let e = G.exec(r);
|
|
176
176
|
if (e) return a({
|
|
177
177
|
control: "page.filter.clear",
|
|
178
178
|
filter: (e[1] ?? "").trim() || null
|
|
179
179
|
});
|
|
180
|
-
let t =
|
|
180
|
+
let t = $(W, r);
|
|
181
181
|
if (t) {
|
|
182
182
|
let e = (t[1] ?? "").trim(), r = (t[2] ?? "").trim();
|
|
183
|
-
if (e && r && n(e,
|
|
183
|
+
if (e && r && n(e, d.filters).kind !== "none") return a({
|
|
184
184
|
control: "page.filter",
|
|
185
185
|
filter: e,
|
|
186
186
|
option: r
|
|
187
187
|
});
|
|
188
188
|
}
|
|
189
|
-
let
|
|
190
|
-
if (
|
|
189
|
+
let i = $(H, r);
|
|
190
|
+
if (i && (i[1] ?? "").trim()) return a({
|
|
191
191
|
control: "page.filter",
|
|
192
192
|
filter: null,
|
|
193
|
-
option: (
|
|
193
|
+
option: (i[1] ?? "").trim()
|
|
194
194
|
});
|
|
195
|
-
let
|
|
196
|
-
if (
|
|
197
|
-
let e = (
|
|
195
|
+
let o = $(U, r);
|
|
196
|
+
if (o) {
|
|
197
|
+
let e = (o[1] ?? "").trim(), t = d.filters.some((t) => n(e, t.options).kind !== "none");
|
|
198
198
|
if (e && t) return a({
|
|
199
199
|
control: "page.filter",
|
|
200
200
|
filter: null,
|
|
@@ -202,16 +202,16 @@ function ne(s, l, x) {
|
|
|
202
202
|
});
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
|
-
if (
|
|
206
|
-
let e =
|
|
205
|
+
if (d.sorts.length > 0) {
|
|
206
|
+
let e = J.exec(r);
|
|
207
207
|
if (e) return a({
|
|
208
208
|
control: "page.sort",
|
|
209
209
|
field: null,
|
|
210
210
|
direction: /^asc/.test(e[1] ?? "") ? "asc" : "desc"
|
|
211
211
|
});
|
|
212
|
-
let t =
|
|
212
|
+
let t = q.exec(r);
|
|
213
213
|
if (t) {
|
|
214
|
-
let { field: e, direction: n } =
|
|
214
|
+
let { field: e, direction: n } = ae((t[1] ?? "").trim());
|
|
215
215
|
if (e) return a({
|
|
216
216
|
control: "page.sort",
|
|
217
217
|
field: e,
|
|
@@ -219,27 +219,35 @@ function ne(s, l, x) {
|
|
|
219
219
|
});
|
|
220
220
|
}
|
|
221
221
|
}
|
|
222
|
-
if (
|
|
223
|
-
if (
|
|
224
|
-
let e =
|
|
222
|
+
if (d.searchable) {
|
|
223
|
+
if (X.test(r)) return a({ control: "page.search.clear" });
|
|
224
|
+
let e = $(Y, r), t = e ? oe(e[1] ?? "") : null;
|
|
225
225
|
if (t) return a({
|
|
226
226
|
control: "page.search",
|
|
227
|
-
query: c(
|
|
227
|
+
query: c(i, t)
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
|
-
if (
|
|
231
|
-
let t = Z
|
|
232
|
-
if (
|
|
230
|
+
if (d.openers.length > 0) {
|
|
231
|
+
let t = $(Z, r), i = t ? (t[1] ?? "").trim() : "";
|
|
232
|
+
if (i && n(i, d.openers).kind !== "none") return a({
|
|
233
233
|
control: "page.open",
|
|
234
|
-
name:
|
|
234
|
+
name: i
|
|
235
235
|
});
|
|
236
|
-
let
|
|
237
|
-
if (c &&
|
|
236
|
+
let s = Q.exec(r), c = s ? (s[1] ?? "").trim() : "";
|
|
237
|
+
if (c && d.openers.filter((t) => e(t.label) === c).length > 0) return o({
|
|
238
238
|
control: "page.open",
|
|
239
239
|
name: c
|
|
240
240
|
});
|
|
241
241
|
}
|
|
242
242
|
return null;
|
|
243
243
|
}
|
|
244
|
+
function ce(e) {
|
|
245
|
+
let t = e.registered, n = [], r = (e, ...t) => {
|
|
246
|
+
e && n.push(...t);
|
|
247
|
+
};
|
|
248
|
+
r(t["account.logout"], u), r(t["header.workspace"], f, p), r(t["header.context"], m, h), r(t["header.notifications"], g, _, v), r(t["header.help"], y, b), r(t["header.search"], x, S, ...C), r(t.sidebar, T, E, O, k), r(t.language, ...A, j), r(t["assistant.history"], M, N), r(t["assistant.transcript"], P, F), r(t["assistant.preview"], ne, I, L, R), r(t["assistant.conversation.new"], z);
|
|
249
|
+
let i = e.page;
|
|
250
|
+
return i && (r(i.tabs.length > 0, ...B), r(i.filters.length > 0, ...H, ...U, ...W, G), r(i.sorts.length > 0, q, ...re, J), r(i.searchable, X, ...Y), r(i.openers.length > 0, ...Z, Q)), n;
|
|
251
|
+
}
|
|
244
252
|
//#endregion
|
|
245
|
-
export {
|
|
253
|
+
export { ce as appControlPrefixPatterns, se as matchAppControl, c as queryAsSaid };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { ControlKey, ControlMap } from './types';
|
|
2
|
+
/** Wake retained draft checks when registered controls mount, change or unmount. */
|
|
3
|
+
export declare function subscribeAssistantControls(listener: () => void): () => void;
|
|
2
4
|
/** Register `impl` for `key`. Returns the cleanup that removes exactly this entry. */
|
|
3
5
|
export declare function registerAssistantControl<K extends ControlKey>(key: K, impl: ControlMap[K]): () => void;
|
|
4
6
|
/** The handler in force for `key` (the newest registration), or null. */
|
|
@@ -13,26 +13,34 @@ var e = {
|
|
|
13
13
|
"assistant.preview": [],
|
|
14
14
|
"assistant.conversation.new": [],
|
|
15
15
|
page: []
|
|
16
|
+
}, t = /* @__PURE__ */ new Set(), n = () => {
|
|
17
|
+
for (let e of t) e();
|
|
16
18
|
};
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
token: r,
|
|
21
|
-
impl: n
|
|
22
|
-
}), () => {
|
|
23
|
-
let e = i.findIndex((e) => e.token === r);
|
|
24
|
-
e >= 0 && i.splice(e, 1);
|
|
19
|
+
function r(e) {
|
|
20
|
+
return t.add(e), () => {
|
|
21
|
+
t.delete(e);
|
|
25
22
|
};
|
|
26
23
|
}
|
|
27
|
-
function
|
|
24
|
+
function i(t, r) {
|
|
25
|
+
let i = Symbol(t), a = e[t];
|
|
26
|
+
return a.push({
|
|
27
|
+
token: i,
|
|
28
|
+
impl: r
|
|
29
|
+
}), n(), () => {
|
|
30
|
+
let e = a.findIndex((e) => e.token === i);
|
|
31
|
+
e >= 0 && (a.splice(e, 1), n());
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function a(t) {
|
|
28
35
|
let n = e[t];
|
|
29
36
|
return n.length > 0 ? n[n.length - 1]?.impl ?? null : null;
|
|
30
37
|
}
|
|
31
|
-
function
|
|
38
|
+
function o(t) {
|
|
32
39
|
return e[t].length > 0;
|
|
33
40
|
}
|
|
34
|
-
function
|
|
41
|
+
function s() {
|
|
35
42
|
for (let t of Object.keys(e)) e[t].length = 0;
|
|
43
|
+
n();
|
|
36
44
|
}
|
|
37
45
|
//#endregion
|
|
38
|
-
export {
|
|
46
|
+
export { s as clearAssistantControls, a as getAssistantControl, o as hasAssistantControl, i as registerAssistantControl, r as subscribeAssistantControls };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface CompletionOptions {
|
|
2
|
+
maxLength: number;
|
|
3
|
+
/** Exact live names for an open capture; an absent capture is free text. */
|
|
4
|
+
slots?: Readonly<Record<string, readonly string[]>>;
|
|
5
|
+
/** Also try live labels for legacy, unnamed open captures. */
|
|
6
|
+
names?: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
/** Is there a continuation of prefix that the real matcher accepts? */
|
|
9
|
+
export declare function hasCommandCompletion(pattern: RegExp, prefix: string, options: CompletionOptions, accepts: (completion: string) => boolean): boolean;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
//#region src/shared/assistant/commandCompletions.ts
|
|
2
|
+
var e = /* @__PURE__ */ new WeakMap(), t = " abcdefghijklmnopqrstuvwxyz0123456789";
|
|
3
|
+
function n(n) {
|
|
4
|
+
let r = e.get(n);
|
|
5
|
+
if (r) return r;
|
|
6
|
+
let i = n.source, a = 0, o = () => {
|
|
7
|
+
let e = [], n = [];
|
|
8
|
+
for (; a < i.length && i[a] !== ")";) {
|
|
9
|
+
let r = i[a++];
|
|
10
|
+
if (r === "|") {
|
|
11
|
+
e.push({
|
|
12
|
+
kind: "seq",
|
|
13
|
+
nodes: n
|
|
14
|
+
}), n = [];
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
let s;
|
|
18
|
+
if (r === "^" || r === "$") continue;
|
|
19
|
+
if (r === "(") {
|
|
20
|
+
let e;
|
|
21
|
+
if (i.startsWith("?:", a)) a += 2;
|
|
22
|
+
else if (i.startsWith("?<", a)) {
|
|
23
|
+
let t = i.indexOf(">", a);
|
|
24
|
+
if (t < 0) throw Error("Invalid command capture");
|
|
25
|
+
e = i.slice(a + 2, t), a = t + 1;
|
|
26
|
+
} else if (i[a] === "?") throw Error("Unsupported command assertion");
|
|
27
|
+
if (s = o(), i[a++] !== ")") throw Error("Unclosed command group");
|
|
28
|
+
e && (s = {
|
|
29
|
+
kind: "slot",
|
|
30
|
+
name: e,
|
|
31
|
+
node: s
|
|
32
|
+
});
|
|
33
|
+
} else if (r === ".") s = {
|
|
34
|
+
kind: "free",
|
|
35
|
+
min: 1,
|
|
36
|
+
max: 1
|
|
37
|
+
};
|
|
38
|
+
else if (r === "[") {
|
|
39
|
+
let e = a - 1;
|
|
40
|
+
for (; a < i.length && i[a] !== "]";) i[a] === "\\" && (a += 1), a += 1;
|
|
41
|
+
let n = RegExp(`^${i.slice(e, ++a)}$`, "u");
|
|
42
|
+
s = {
|
|
43
|
+
kind: "choice",
|
|
44
|
+
nodes: [...t].filter((e) => n.test(e)).map((e) => ({
|
|
45
|
+
kind: "text",
|
|
46
|
+
text: e
|
|
47
|
+
}))
|
|
48
|
+
};
|
|
49
|
+
} else if (r === "\\") {
|
|
50
|
+
let e = i[a++];
|
|
51
|
+
if (e === "b") continue;
|
|
52
|
+
if (e === "s") s = {
|
|
53
|
+
kind: "text",
|
|
54
|
+
text: " "
|
|
55
|
+
};
|
|
56
|
+
else if (e === "S") s = {
|
|
57
|
+
kind: "free",
|
|
58
|
+
min: 1,
|
|
59
|
+
max: 1
|
|
60
|
+
};
|
|
61
|
+
else if (e === "d") s = {
|
|
62
|
+
kind: "choice",
|
|
63
|
+
nodes: [..."0123456789"].map((e) => ({
|
|
64
|
+
kind: "text",
|
|
65
|
+
text: e
|
|
66
|
+
}))
|
|
67
|
+
};
|
|
68
|
+
else if (e && !/[a-zA-Z0-9]/.test(e)) s = {
|
|
69
|
+
kind: "text",
|
|
70
|
+
text: e
|
|
71
|
+
};
|
|
72
|
+
else throw Error("Unsupported command escape");
|
|
73
|
+
} else s = {
|
|
74
|
+
kind: "text",
|
|
75
|
+
text: r ?? ""
|
|
76
|
+
};
|
|
77
|
+
let c = 1, l = 1, u = i[a];
|
|
78
|
+
if (u === "?" || u === "*" || u === "+") a += 1, c = +(u === "+"), l = u === "?" ? 1 : Infinity;
|
|
79
|
+
else if (u === "{") {
|
|
80
|
+
let e = /^\{(\d+)(?:,(\d*))?\}/.exec(i.slice(a));
|
|
81
|
+
if (!e) throw Error("Unsupported command repetition");
|
|
82
|
+
a += e[0].length, c = Number(e[1]), l = e[2] === void 0 ? c : e[2] === "" ? Infinity : Number(e[2]);
|
|
83
|
+
}
|
|
84
|
+
i[a] === "?" && (c !== 1 || l !== 1) && (a += 1), (c !== 1 || l !== 1) && (s = s.kind === "free" ? {
|
|
85
|
+
kind: "free",
|
|
86
|
+
min: c,
|
|
87
|
+
max: l
|
|
88
|
+
} : {
|
|
89
|
+
kind: "repeat",
|
|
90
|
+
node: s,
|
|
91
|
+
min: c,
|
|
92
|
+
max: l
|
|
93
|
+
}), n.push(s);
|
|
94
|
+
}
|
|
95
|
+
return e.push({
|
|
96
|
+
kind: "seq",
|
|
97
|
+
nodes: n
|
|
98
|
+
}), e.length === 1 ? e[0] : {
|
|
99
|
+
kind: "choice",
|
|
100
|
+
nodes: e
|
|
101
|
+
};
|
|
102
|
+
}, s = o();
|
|
103
|
+
if (a !== i.length) throw Error("Unexpected command pattern suffix");
|
|
104
|
+
return e.set(n, s), s;
|
|
105
|
+
}
|
|
106
|
+
function r(e, t, r, i) {
|
|
107
|
+
if (t.length > r.maxLength) return !1;
|
|
108
|
+
let a = 0, o = (e) => e.length <= r.maxLength && (t.startsWith(e) || e.startsWith(t));
|
|
109
|
+
function* s(e, n) {
|
|
110
|
+
if (++a > 2e4) throw Error("Command completion budget");
|
|
111
|
+
if (e.kind === "text") {
|
|
112
|
+
let t = n + e.text;
|
|
113
|
+
o(t) && (yield t);
|
|
114
|
+
} else if (e.kind === "choice") for (let t of e.nodes) yield* s(t, n);
|
|
115
|
+
else if (e.kind === "seq") {
|
|
116
|
+
let { nodes: t } = e;
|
|
117
|
+
function* r(e, n) {
|
|
118
|
+
let i = t[e];
|
|
119
|
+
if (!i) {
|
|
120
|
+
yield n;
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
for (let t of s(i, n)) yield* r(e + 1, t);
|
|
124
|
+
}
|
|
125
|
+
yield* r(0, n);
|
|
126
|
+
} else if (e.kind === "slot" && r.slots?.[e.name] !== void 0) for (let t of r.slots[e.name] ?? []) yield* s({
|
|
127
|
+
kind: "text",
|
|
128
|
+
text: t
|
|
129
|
+
}, n);
|
|
130
|
+
else if (e.kind === "slot") yield* s(e.node, n);
|
|
131
|
+
else if (e.kind === "repeat") {
|
|
132
|
+
let { min: t, max: i, node: a } = e;
|
|
133
|
+
function* o(e, n) {
|
|
134
|
+
if (e >= t && (yield n), !(e >= Math.min(i, r.maxLength + 1))) for (let t of s(a, n)) t !== n && (yield* o(e + 1, t));
|
|
135
|
+
}
|
|
136
|
+
yield* o(0, n);
|
|
137
|
+
} else {
|
|
138
|
+
let i = t.slice(Math.min(n.length, t.length)), a = new Set([
|
|
139
|
+
i,
|
|
140
|
+
i + "item",
|
|
141
|
+
"item",
|
|
142
|
+
"x",
|
|
143
|
+
...r.names ?? []
|
|
144
|
+
]), s = i.replace(/ /g, "");
|
|
145
|
+
for (let e of r.names ?? []) {
|
|
146
|
+
let t = e.replace(/ /g, "");
|
|
147
|
+
t.startsWith(s) && a.add(i + t.slice(s.length));
|
|
148
|
+
}
|
|
149
|
+
for (let e = i.length; e >= 0; --e) a.add(i.slice(0, e));
|
|
150
|
+
for (let t of a) t.length < e.min || t.length > e.max || o(n + t) && (yield n + t);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
for (let r of s(n(e), "")) if (r.startsWith(t) && e.test(r) && i(r)) return !0;
|
|
155
|
+
return !1;
|
|
156
|
+
} catch {
|
|
157
|
+
return !0;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//#endregion
|
|
161
|
+
export { r as hasCommandCompletion };
|
|
@@ -253,6 +253,7 @@ export * from './turnTimingReport';
|
|
|
253
253
|
export * from './turnTimingReporter';
|
|
254
254
|
export * from './prewarm';
|
|
255
255
|
export * from './localUiCommands';
|
|
256
|
+
export * from './commandCompletions';
|
|
256
257
|
export * from './localeCommands/types';
|
|
257
258
|
export * from './localeCommands/fold';
|
|
258
259
|
export * from './localeCommands/frames';
|
|
@@ -274,6 +275,7 @@ export * from './localeCommands/tables/en';
|
|
|
274
275
|
export * from './localUiCommandCopy';
|
|
275
276
|
export * from './uiActions/navigationOutcome';
|
|
276
277
|
export * from './uiActions/backStack';
|
|
278
|
+
export * from './uiActions/draftPathname';
|
|
277
279
|
export * from './uiActions/navigateAction';
|
|
278
280
|
export * from './uiActions/assistantHref';
|
|
279
281
|
export * from './uiActions/inAppLinks';
|
|
@@ -320,6 +322,7 @@ export * from './useAssistantHeartbeat';
|
|
|
320
322
|
export * from './useAssistantKeyboardShortcuts';
|
|
321
323
|
export * from './ui/AssistantApiCallsConsentDialog';
|
|
322
324
|
export * from './ui/AssistantChatArea';
|
|
325
|
+
export * from './ui/draftCommandCheck';
|
|
323
326
|
export * from './ui/AIAssistantPanel';
|
|
324
327
|
export * from './ui/assistantOverlayState';
|
|
325
328
|
export * from './ui/useAssistantLauncherLift';
|
|
@@ -212,6 +212,17 @@ export interface LocalUiCommandContext {
|
|
|
212
212
|
* Absent: no app-control grammar runs, and the matcher is what it was.
|
|
213
213
|
*/
|
|
214
214
|
controls?: ControlSnapshot;
|
|
215
|
+
/**
|
|
216
|
+
* Live host integrations for speculative drafts. Omitted by grammar-only
|
|
217
|
+
* callers; Send still checks the actual provider before running a command.
|
|
218
|
+
*/
|
|
219
|
+
executors?: {
|
|
220
|
+
theme: boolean;
|
|
221
|
+
navigation: boolean;
|
|
222
|
+
conversationDelete?: boolean;
|
|
223
|
+
/** Build the current plan only; never run or confirm it during speculation. */
|
|
224
|
+
appControl?: (request: AppControlRequest) => boolean;
|
|
225
|
+
};
|
|
215
226
|
}
|
|
216
227
|
/**
|
|
217
228
|
* The command this whole utterance is, or null to send it to the model.
|
|
@@ -222,6 +233,11 @@ export interface LocalUiCommandContext {
|
|
|
222
233
|
* only for what the manifest has switched on.
|
|
223
234
|
*/
|
|
224
235
|
export declare function matchLocalUiCommand(text: string, destinations: readonly LocalDestination[], options?: LocalUiCommandOptions, context?: LocalUiCommandContext): LocalUiCommand | null;
|
|
236
|
+
/**
|
|
237
|
+
* Pure speculative check for typed drafts. A complete command, or a prefix
|
|
238
|
+
* with a completion accepted by the SAME matcher, must not acquire a sandbox.
|
|
239
|
+
*/
|
|
240
|
+
export declare function couldBeLocalUiCommand(text: string, destinations: readonly LocalDestination[], options?: LocalUiCommandOptions, context?: LocalUiCommandContext): boolean;
|
|
225
241
|
/**
|
|
226
242
|
* ★ BOFF-8060 / BOFF-8867: could this sentence be "take me there" or a pick —
|
|
227
243
|
* in English or in an active language? The panel builds the offered-navigation
|