@wix/himalaya-cli 0.1027.0 → 0.1029.0
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/cli.mjs +176 -31
- package/dist/preview-assets.generated.bin +0 -0
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +15 -3
- package/templates/beauty-salon-owner/dev/index.ts +22 -27
- package/templates/beauty-salon-owner/tier5-src/_shared/aria-chat.ts +23 -3
- package/templates/branded-lite/dev/index.ts +32 -4
- package/templates/community-club-owner/dev/index.ts +22 -27
- package/templates/community-club-owner/tier5-src/_shared/aria-chat.ts +23 -3
- package/templates/events-meetups-owner/dev/index.ts +22 -27
- package/templates/events-meetups-owner/tier5-src/_shared/aria-chat.ts +23 -3
- package/templates/gym-fitness/dev/index.ts +15 -3
- package/templates/gym-fitness-owner/dev/index.ts +22 -27
- package/templates/gym-fitness-owner/tier5-src/_shared/aria-chat.ts +23 -3
- package/templates/nonprofit-cause-owner/dev/index.ts +22 -27
- package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-chat.ts +23 -3
- package/templates/owner-lite/dev/index.ts +22 -27
- package/templates/owner-lite/tier5-src/_shared/aria-chat.ts +23 -3
- package/templates/podcast-creator-owner/dev/index.ts +22 -27
- package/templates/podcast-creator-owner/tier5-src/_shared/aria-chat.ts +23 -3
- package/templates/portfolio-creative-owner/dev/index.ts +22 -27
- package/templates/portfolio-creative-owner/tier5-src/_shared/aria-chat.ts +23 -3
- package/templates/restaurant-owner/dev/index.ts +22 -27
- package/templates/restaurant-owner/tier5-src/_shared/aria-chat.ts +23 -3
- package/templates/retail-store-owner/dev/index.ts +22 -27
- package/templates/retail-store-owner/tier5-src/_shared/aria-chat.ts +23 -3
- package/templates/yoga-studio/dev/index.ts +15 -1
- package/templates/yoga-studio-owner/dev/index.ts +22 -27
- package/templates/yoga-studio-owner/tier5-src/_shared/aria-chat.ts +23 -3
|
@@ -55260,7 +55260,7 @@ const SCREENS = runtimeSetting({
|
|
|
55260
55260
|
"spacing": 3,
|
|
55261
55261
|
"children": [
|
|
55262
55262
|
{
|
|
55263
|
-
"id": "himi_owner_lite_aria.msg_$item.id.
|
|
55263
|
+
"id": "himi_owner_lite_aria.msg_$item.id.content",
|
|
55264
55264
|
"body": {
|
|
55265
55265
|
"package": "himalaya",
|
|
55266
55266
|
"type": "HStack",
|
|
@@ -55279,43 +55279,34 @@ const SCREENS = runtimeSetting({
|
|
|
55279
55279
|
}
|
|
55280
55280
|
},
|
|
55281
55281
|
{
|
|
55282
|
-
"id": "",
|
|
55282
|
+
"id": "himi_owner_lite_aria.msg_$item.id.bubble",
|
|
55283
55283
|
"body": {
|
|
55284
55284
|
"package": "himalaya",
|
|
55285
55285
|
"type": "Text",
|
|
55286
55286
|
"props": {
|
|
55287
|
-
"text": "$item.
|
|
55288
|
-
"style": "
|
|
55289
|
-
"
|
|
55290
|
-
"maxLines": 1
|
|
55287
|
+
"text": "$item.content",
|
|
55288
|
+
"style": "body",
|
|
55289
|
+
"maxLines": 50
|
|
55291
55290
|
}
|
|
55292
|
-
}
|
|
55293
|
-
}
|
|
55294
|
-
]
|
|
55295
|
-
}
|
|
55296
|
-
}
|
|
55297
|
-
},
|
|
55298
|
-
{
|
|
55299
|
-
"id": "himi_owner_lite_aria.msg_$item.id.content",
|
|
55300
|
-
"body": {
|
|
55301
|
-
"package": "himalaya",
|
|
55302
|
-
"type": "HStack",
|
|
55303
|
-
"props": {
|
|
55304
|
-
"spacing": 0,
|
|
55305
|
-
"children": [
|
|
55306
|
-
{
|
|
55307
|
-
"id": "",
|
|
55308
|
-
"body": {
|
|
55309
|
-
"package": "himalaya",
|
|
55310
|
-
"type": "Spacer",
|
|
55311
|
-
"props": {}
|
|
55312
55291
|
},
|
|
55313
55292
|
"modifiers": {
|
|
55293
|
+
"accessibilityLabel": "$item.spoken",
|
|
55294
|
+
"padding": {
|
|
55295
|
+
"leading": 16,
|
|
55296
|
+
"trailing": 16,
|
|
55297
|
+
"top": 8,
|
|
55298
|
+
"bottom": 8
|
|
55299
|
+
},
|
|
55300
|
+
"background": {
|
|
55301
|
+
"token": "surfaceSecondary"
|
|
55302
|
+
},
|
|
55303
|
+
"cornerRadius": 20,
|
|
55304
|
+
"maxWidth": 300,
|
|
55314
55305
|
"hiddenPath": "$item.notUser"
|
|
55315
55306
|
}
|
|
55316
55307
|
},
|
|
55317
55308
|
{
|
|
55318
|
-
"id": "",
|
|
55309
|
+
"id": "himi_owner_lite_aria.msg_$item.id.text",
|
|
55319
55310
|
"body": {
|
|
55320
55311
|
"package": "himalaya",
|
|
55321
55312
|
"type": "Text",
|
|
@@ -55324,6 +55315,10 @@ const SCREENS = runtimeSetting({
|
|
|
55324
55315
|
"style": "body",
|
|
55325
55316
|
"maxLines": 50
|
|
55326
55317
|
}
|
|
55318
|
+
},
|
|
55319
|
+
"modifiers": {
|
|
55320
|
+
"accessibilityLabel": "$item.spoken",
|
|
55321
|
+
"hiddenPath": "$item.notAria"
|
|
55327
55322
|
}
|
|
55328
55323
|
}
|
|
55329
55324
|
]
|
|
@@ -83,6 +83,11 @@ export interface AriaBubble {
|
|
|
83
83
|
* that right-aligns the owner renders two templates and collapses one. */
|
|
84
84
|
notUser: boolean;
|
|
85
85
|
notAria: boolean;
|
|
86
|
+
/** What a screen reader says for the row: the author, then the words. A
|
|
87
|
+
* screen that draws the speaker only as a bubble and a side of the screen
|
|
88
|
+
* (`messageStyle: 'userBubble'`) has no visible author line to read, and
|
|
89
|
+
* without this the owner's question and Aria's reply sound the same. */
|
|
90
|
+
spoken: string;
|
|
86
91
|
link1Label: string; link1Url: string; link1Hidden: boolean;
|
|
87
92
|
link2Label: string; link2Url: string; link2Hidden: boolean;
|
|
88
93
|
link3Label: string; link3Url: string; link3Hidden: boolean;
|
|
@@ -561,9 +566,23 @@ export function disclosedLabel(link: { label: string; url: string }): string {
|
|
|
561
566
|
* machinery dies. (Measured: 20 tests, every one of them about polling.) */
|
|
562
567
|
export { stripMarkdown };
|
|
563
568
|
|
|
569
|
+
/** The screen-reader line for a bubble — see `AriaBubble.spoken`. */
|
|
570
|
+
export function spokenOf(who: string, content: string): string {
|
|
571
|
+
return who ? `${who}: ${content}` : content;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/** A persisted transcript from before `spoken` existed, made whole. A `$item.`
|
|
575
|
+
* path missing on a row does not substitute, so a row without the field would
|
|
576
|
+
* announce the literal binding until the next rebuild replaced it. */
|
|
577
|
+
export function withSpoken(bubbles: AriaBubble[]): AriaBubble[] {
|
|
578
|
+
return bubbles.every((b) => typeof b.spoken === "string")
|
|
579
|
+
? bubbles
|
|
580
|
+
: bubbles.map((b) => (typeof b.spoken === "string" ? b : { ...b, spoken: spokenOf(b.who, b.content) }));
|
|
581
|
+
}
|
|
582
|
+
|
|
564
583
|
/** A greeting or optimistic bubble: no links, all slots defaulted. */
|
|
565
584
|
export function plainBubble(id: string, role: string, who: string, content: string): AriaBubble {
|
|
566
|
-
return { id, role, who, content, notUser: role !== "USER", notAria: role === "USER", ...linkFieldsOf("", role) };
|
|
585
|
+
return { id, role, who, content, notUser: role !== "USER", notAria: role === "USER", spoken: spokenOf(who, content), ...linkFieldsOf("", role) };
|
|
567
586
|
}
|
|
568
587
|
|
|
569
588
|
/** Server transcript → bubbles. USER text is literal; ASSISTANT replies are
|
|
@@ -644,6 +663,7 @@ function bubbleOf(id: string, role: string, who: string, raw: string, writing: b
|
|
|
644
663
|
content,
|
|
645
664
|
notUser: role !== "USER",
|
|
646
665
|
notAria: role === "USER",
|
|
666
|
+
spoken: spokenOf(who, content),
|
|
647
667
|
...linkFieldsOf(prose, role),
|
|
648
668
|
};
|
|
649
669
|
}
|
|
@@ -2004,7 +2024,7 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
|
|
|
2004
2024
|
// a rehydrated turn there was no ladder at all, leaving "Aria is
|
|
2005
2025
|
// typing…" on screen with nothing ever fetching the answer.
|
|
2006
2026
|
if (s._pending || s.status === "sending") {
|
|
2007
|
-
const held: AriaChatState = { ...s, status: "sending", prompts: [] };
|
|
2027
|
+
const held: AriaChatState = { ...s, status: "sending", prompts: [], messages: withSpoken(s.messages) };
|
|
2008
2028
|
return cadence(held, o.poll ? o.poll.fastMs : null, null);
|
|
2009
2029
|
}
|
|
2010
2030
|
// …but the self-kick pass runs BEFORE the pack is stashed, so the
|
|
@@ -2013,7 +2033,7 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
|
|
|
2013
2033
|
// still the only thing on screen — `prompts` is already recomputed
|
|
2014
2034
|
// here, and a chip pack that localizes beside a greeting that does not
|
|
2015
2035
|
// is the visible half of the same bug.
|
|
2016
|
-
const messages = isGreetingOnly(s.messages) ? greetingOnly() : s.messages;
|
|
2036
|
+
const messages = isGreetingOnly(s.messages) ? greetingOnly() : withSpoken(s.messages);
|
|
2017
2037
|
return { ...s, status: "ready", messages, prompts: promptsFor(messages, promptList()) };
|
|
2018
2038
|
}
|
|
2019
2039
|
try {
|
|
@@ -55191,7 +55191,7 @@ const SCREENS = runtimeSetting({
|
|
|
55191
55191
|
"spacing": 3,
|
|
55192
55192
|
"children": [
|
|
55193
55193
|
{
|
|
55194
|
-
"id": "himi_owner_lite_aria.msg_$item.id.
|
|
55194
|
+
"id": "himi_owner_lite_aria.msg_$item.id.content",
|
|
55195
55195
|
"body": {
|
|
55196
55196
|
"package": "himalaya",
|
|
55197
55197
|
"type": "HStack",
|
|
@@ -55210,43 +55210,34 @@ const SCREENS = runtimeSetting({
|
|
|
55210
55210
|
}
|
|
55211
55211
|
},
|
|
55212
55212
|
{
|
|
55213
|
-
"id": "",
|
|
55213
|
+
"id": "himi_owner_lite_aria.msg_$item.id.bubble",
|
|
55214
55214
|
"body": {
|
|
55215
55215
|
"package": "himalaya",
|
|
55216
55216
|
"type": "Text",
|
|
55217
55217
|
"props": {
|
|
55218
|
-
"text": "$item.
|
|
55219
|
-
"style": "
|
|
55220
|
-
"
|
|
55221
|
-
"maxLines": 1
|
|
55218
|
+
"text": "$item.content",
|
|
55219
|
+
"style": "body",
|
|
55220
|
+
"maxLines": 50
|
|
55222
55221
|
}
|
|
55223
|
-
}
|
|
55224
|
-
}
|
|
55225
|
-
]
|
|
55226
|
-
}
|
|
55227
|
-
}
|
|
55228
|
-
},
|
|
55229
|
-
{
|
|
55230
|
-
"id": "himi_owner_lite_aria.msg_$item.id.content",
|
|
55231
|
-
"body": {
|
|
55232
|
-
"package": "himalaya",
|
|
55233
|
-
"type": "HStack",
|
|
55234
|
-
"props": {
|
|
55235
|
-
"spacing": 0,
|
|
55236
|
-
"children": [
|
|
55237
|
-
{
|
|
55238
|
-
"id": "",
|
|
55239
|
-
"body": {
|
|
55240
|
-
"package": "himalaya",
|
|
55241
|
-
"type": "Spacer",
|
|
55242
|
-
"props": {}
|
|
55243
55222
|
},
|
|
55244
55223
|
"modifiers": {
|
|
55224
|
+
"accessibilityLabel": "$item.spoken",
|
|
55225
|
+
"padding": {
|
|
55226
|
+
"leading": 16,
|
|
55227
|
+
"trailing": 16,
|
|
55228
|
+
"top": 8,
|
|
55229
|
+
"bottom": 8
|
|
55230
|
+
},
|
|
55231
|
+
"background": {
|
|
55232
|
+
"token": "surfaceSecondary"
|
|
55233
|
+
},
|
|
55234
|
+
"cornerRadius": 20,
|
|
55235
|
+
"maxWidth": 300,
|
|
55245
55236
|
"hiddenPath": "$item.notUser"
|
|
55246
55237
|
}
|
|
55247
55238
|
},
|
|
55248
55239
|
{
|
|
55249
|
-
"id": "",
|
|
55240
|
+
"id": "himi_owner_lite_aria.msg_$item.id.text",
|
|
55250
55241
|
"body": {
|
|
55251
55242
|
"package": "himalaya",
|
|
55252
55243
|
"type": "Text",
|
|
@@ -55255,6 +55246,10 @@ const SCREENS = runtimeSetting({
|
|
|
55255
55246
|
"style": "body",
|
|
55256
55247
|
"maxLines": 50
|
|
55257
55248
|
}
|
|
55249
|
+
},
|
|
55250
|
+
"modifiers": {
|
|
55251
|
+
"accessibilityLabel": "$item.spoken",
|
|
55252
|
+
"hiddenPath": "$item.notAria"
|
|
55258
55253
|
}
|
|
55259
55254
|
}
|
|
55260
55255
|
]
|
|
@@ -83,6 +83,11 @@ export interface AriaBubble {
|
|
|
83
83
|
* that right-aligns the owner renders two templates and collapses one. */
|
|
84
84
|
notUser: boolean;
|
|
85
85
|
notAria: boolean;
|
|
86
|
+
/** What a screen reader says for the row: the author, then the words. A
|
|
87
|
+
* screen that draws the speaker only as a bubble and a side of the screen
|
|
88
|
+
* (`messageStyle: 'userBubble'`) has no visible author line to read, and
|
|
89
|
+
* without this the owner's question and Aria's reply sound the same. */
|
|
90
|
+
spoken: string;
|
|
86
91
|
link1Label: string; link1Url: string; link1Hidden: boolean;
|
|
87
92
|
link2Label: string; link2Url: string; link2Hidden: boolean;
|
|
88
93
|
link3Label: string; link3Url: string; link3Hidden: boolean;
|
|
@@ -561,9 +566,23 @@ export function disclosedLabel(link: { label: string; url: string }): string {
|
|
|
561
566
|
* machinery dies. (Measured: 20 tests, every one of them about polling.) */
|
|
562
567
|
export { stripMarkdown };
|
|
563
568
|
|
|
569
|
+
/** The screen-reader line for a bubble — see `AriaBubble.spoken`. */
|
|
570
|
+
export function spokenOf(who: string, content: string): string {
|
|
571
|
+
return who ? `${who}: ${content}` : content;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/** A persisted transcript from before `spoken` existed, made whole. A `$item.`
|
|
575
|
+
* path missing on a row does not substitute, so a row without the field would
|
|
576
|
+
* announce the literal binding until the next rebuild replaced it. */
|
|
577
|
+
export function withSpoken(bubbles: AriaBubble[]): AriaBubble[] {
|
|
578
|
+
return bubbles.every((b) => typeof b.spoken === "string")
|
|
579
|
+
? bubbles
|
|
580
|
+
: bubbles.map((b) => (typeof b.spoken === "string" ? b : { ...b, spoken: spokenOf(b.who, b.content) }));
|
|
581
|
+
}
|
|
582
|
+
|
|
564
583
|
/** A greeting or optimistic bubble: no links, all slots defaulted. */
|
|
565
584
|
export function plainBubble(id: string, role: string, who: string, content: string): AriaBubble {
|
|
566
|
-
return { id, role, who, content, notUser: role !== "USER", notAria: role === "USER", ...linkFieldsOf("", role) };
|
|
585
|
+
return { id, role, who, content, notUser: role !== "USER", notAria: role === "USER", spoken: spokenOf(who, content), ...linkFieldsOf("", role) };
|
|
567
586
|
}
|
|
568
587
|
|
|
569
588
|
/** Server transcript → bubbles. USER text is literal; ASSISTANT replies are
|
|
@@ -644,6 +663,7 @@ function bubbleOf(id: string, role: string, who: string, raw: string, writing: b
|
|
|
644
663
|
content,
|
|
645
664
|
notUser: role !== "USER",
|
|
646
665
|
notAria: role === "USER",
|
|
666
|
+
spoken: spokenOf(who, content),
|
|
647
667
|
...linkFieldsOf(prose, role),
|
|
648
668
|
};
|
|
649
669
|
}
|
|
@@ -2004,7 +2024,7 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
|
|
|
2004
2024
|
// a rehydrated turn there was no ladder at all, leaving "Aria is
|
|
2005
2025
|
// typing…" on screen with nothing ever fetching the answer.
|
|
2006
2026
|
if (s._pending || s.status === "sending") {
|
|
2007
|
-
const held: AriaChatState = { ...s, status: "sending", prompts: [] };
|
|
2027
|
+
const held: AriaChatState = { ...s, status: "sending", prompts: [], messages: withSpoken(s.messages) };
|
|
2008
2028
|
return cadence(held, o.poll ? o.poll.fastMs : null, null);
|
|
2009
2029
|
}
|
|
2010
2030
|
// …but the self-kick pass runs BEFORE the pack is stashed, so the
|
|
@@ -2013,7 +2033,7 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
|
|
|
2013
2033
|
// still the only thing on screen — `prompts` is already recomputed
|
|
2014
2034
|
// here, and a chip pack that localizes beside a greeting that does not
|
|
2015
2035
|
// is the visible half of the same bug.
|
|
2016
|
-
const messages = isGreetingOnly(s.messages) ? greetingOnly() : s.messages;
|
|
2036
|
+
const messages = isGreetingOnly(s.messages) ? greetingOnly() : withSpoken(s.messages);
|
|
2017
2037
|
return { ...s, status: "ready", messages, prompts: promptsFor(messages, promptList()) };
|
|
2018
2038
|
}
|
|
2019
2039
|
try {
|
|
@@ -55191,7 +55191,7 @@ const SCREENS = runtimeSetting({
|
|
|
55191
55191
|
"spacing": 3,
|
|
55192
55192
|
"children": [
|
|
55193
55193
|
{
|
|
55194
|
-
"id": "himi_owner_lite_aria.msg_$item.id.
|
|
55194
|
+
"id": "himi_owner_lite_aria.msg_$item.id.content",
|
|
55195
55195
|
"body": {
|
|
55196
55196
|
"package": "himalaya",
|
|
55197
55197
|
"type": "HStack",
|
|
@@ -55210,43 +55210,34 @@ const SCREENS = runtimeSetting({
|
|
|
55210
55210
|
}
|
|
55211
55211
|
},
|
|
55212
55212
|
{
|
|
55213
|
-
"id": "",
|
|
55213
|
+
"id": "himi_owner_lite_aria.msg_$item.id.bubble",
|
|
55214
55214
|
"body": {
|
|
55215
55215
|
"package": "himalaya",
|
|
55216
55216
|
"type": "Text",
|
|
55217
55217
|
"props": {
|
|
55218
|
-
"text": "$item.
|
|
55219
|
-
"style": "
|
|
55220
|
-
"
|
|
55221
|
-
"maxLines": 1
|
|
55218
|
+
"text": "$item.content",
|
|
55219
|
+
"style": "body",
|
|
55220
|
+
"maxLines": 50
|
|
55222
55221
|
}
|
|
55223
|
-
}
|
|
55224
|
-
}
|
|
55225
|
-
]
|
|
55226
|
-
}
|
|
55227
|
-
}
|
|
55228
|
-
},
|
|
55229
|
-
{
|
|
55230
|
-
"id": "himi_owner_lite_aria.msg_$item.id.content",
|
|
55231
|
-
"body": {
|
|
55232
|
-
"package": "himalaya",
|
|
55233
|
-
"type": "HStack",
|
|
55234
|
-
"props": {
|
|
55235
|
-
"spacing": 0,
|
|
55236
|
-
"children": [
|
|
55237
|
-
{
|
|
55238
|
-
"id": "",
|
|
55239
|
-
"body": {
|
|
55240
|
-
"package": "himalaya",
|
|
55241
|
-
"type": "Spacer",
|
|
55242
|
-
"props": {}
|
|
55243
55222
|
},
|
|
55244
55223
|
"modifiers": {
|
|
55224
|
+
"accessibilityLabel": "$item.spoken",
|
|
55225
|
+
"padding": {
|
|
55226
|
+
"leading": 16,
|
|
55227
|
+
"trailing": 16,
|
|
55228
|
+
"top": 8,
|
|
55229
|
+
"bottom": 8
|
|
55230
|
+
},
|
|
55231
|
+
"background": {
|
|
55232
|
+
"token": "surfaceSecondary"
|
|
55233
|
+
},
|
|
55234
|
+
"cornerRadius": 20,
|
|
55235
|
+
"maxWidth": 300,
|
|
55245
55236
|
"hiddenPath": "$item.notUser"
|
|
55246
55237
|
}
|
|
55247
55238
|
},
|
|
55248
55239
|
{
|
|
55249
|
-
"id": "",
|
|
55240
|
+
"id": "himi_owner_lite_aria.msg_$item.id.text",
|
|
55250
55241
|
"body": {
|
|
55251
55242
|
"package": "himalaya",
|
|
55252
55243
|
"type": "Text",
|
|
@@ -55255,6 +55246,10 @@ const SCREENS = runtimeSetting({
|
|
|
55255
55246
|
"style": "body",
|
|
55256
55247
|
"maxLines": 50
|
|
55257
55248
|
}
|
|
55249
|
+
},
|
|
55250
|
+
"modifiers": {
|
|
55251
|
+
"accessibilityLabel": "$item.spoken",
|
|
55252
|
+
"hiddenPath": "$item.notAria"
|
|
55258
55253
|
}
|
|
55259
55254
|
}
|
|
55260
55255
|
]
|
|
@@ -83,6 +83,11 @@ export interface AriaBubble {
|
|
|
83
83
|
* that right-aligns the owner renders two templates and collapses one. */
|
|
84
84
|
notUser: boolean;
|
|
85
85
|
notAria: boolean;
|
|
86
|
+
/** What a screen reader says for the row: the author, then the words. A
|
|
87
|
+
* screen that draws the speaker only as a bubble and a side of the screen
|
|
88
|
+
* (`messageStyle: 'userBubble'`) has no visible author line to read, and
|
|
89
|
+
* without this the owner's question and Aria's reply sound the same. */
|
|
90
|
+
spoken: string;
|
|
86
91
|
link1Label: string; link1Url: string; link1Hidden: boolean;
|
|
87
92
|
link2Label: string; link2Url: string; link2Hidden: boolean;
|
|
88
93
|
link3Label: string; link3Url: string; link3Hidden: boolean;
|
|
@@ -561,9 +566,23 @@ export function disclosedLabel(link: { label: string; url: string }): string {
|
|
|
561
566
|
* machinery dies. (Measured: 20 tests, every one of them about polling.) */
|
|
562
567
|
export { stripMarkdown };
|
|
563
568
|
|
|
569
|
+
/** The screen-reader line for a bubble — see `AriaBubble.spoken`. */
|
|
570
|
+
export function spokenOf(who: string, content: string): string {
|
|
571
|
+
return who ? `${who}: ${content}` : content;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/** A persisted transcript from before `spoken` existed, made whole. A `$item.`
|
|
575
|
+
* path missing on a row does not substitute, so a row without the field would
|
|
576
|
+
* announce the literal binding until the next rebuild replaced it. */
|
|
577
|
+
export function withSpoken(bubbles: AriaBubble[]): AriaBubble[] {
|
|
578
|
+
return bubbles.every((b) => typeof b.spoken === "string")
|
|
579
|
+
? bubbles
|
|
580
|
+
: bubbles.map((b) => (typeof b.spoken === "string" ? b : { ...b, spoken: spokenOf(b.who, b.content) }));
|
|
581
|
+
}
|
|
582
|
+
|
|
564
583
|
/** A greeting or optimistic bubble: no links, all slots defaulted. */
|
|
565
584
|
export function plainBubble(id: string, role: string, who: string, content: string): AriaBubble {
|
|
566
|
-
return { id, role, who, content, notUser: role !== "USER", notAria: role === "USER", ...linkFieldsOf("", role) };
|
|
585
|
+
return { id, role, who, content, notUser: role !== "USER", notAria: role === "USER", spoken: spokenOf(who, content), ...linkFieldsOf("", role) };
|
|
567
586
|
}
|
|
568
587
|
|
|
569
588
|
/** Server transcript → bubbles. USER text is literal; ASSISTANT replies are
|
|
@@ -644,6 +663,7 @@ function bubbleOf(id: string, role: string, who: string, raw: string, writing: b
|
|
|
644
663
|
content,
|
|
645
664
|
notUser: role !== "USER",
|
|
646
665
|
notAria: role === "USER",
|
|
666
|
+
spoken: spokenOf(who, content),
|
|
647
667
|
...linkFieldsOf(prose, role),
|
|
648
668
|
};
|
|
649
669
|
}
|
|
@@ -2004,7 +2024,7 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
|
|
|
2004
2024
|
// a rehydrated turn there was no ladder at all, leaving "Aria is
|
|
2005
2025
|
// typing…" on screen with nothing ever fetching the answer.
|
|
2006
2026
|
if (s._pending || s.status === "sending") {
|
|
2007
|
-
const held: AriaChatState = { ...s, status: "sending", prompts: [] };
|
|
2027
|
+
const held: AriaChatState = { ...s, status: "sending", prompts: [], messages: withSpoken(s.messages) };
|
|
2008
2028
|
return cadence(held, o.poll ? o.poll.fastMs : null, null);
|
|
2009
2029
|
}
|
|
2010
2030
|
// …but the self-kick pass runs BEFORE the pack is stashed, so the
|
|
@@ -2013,7 +2033,7 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
|
|
|
2013
2033
|
// still the only thing on screen — `prompts` is already recomputed
|
|
2014
2034
|
// here, and a chip pack that localizes beside a greeting that does not
|
|
2015
2035
|
// is the visible half of the same bug.
|
|
2016
|
-
const messages = isGreetingOnly(s.messages) ? greetingOnly() : s.messages;
|
|
2036
|
+
const messages = isGreetingOnly(s.messages) ? greetingOnly() : withSpoken(s.messages);
|
|
2017
2037
|
return { ...s, status: "ready", messages, prompts: promptsFor(messages, promptList()) };
|
|
2018
2038
|
}
|
|
2019
2039
|
try {
|
|
@@ -55262,7 +55262,7 @@ const SCREENS = runtimeSetting({
|
|
|
55262
55262
|
"spacing": 3,
|
|
55263
55263
|
"children": [
|
|
55264
55264
|
{
|
|
55265
|
-
"id": "himi_owner_lite_aria.msg_$item.id.
|
|
55265
|
+
"id": "himi_owner_lite_aria.msg_$item.id.content",
|
|
55266
55266
|
"body": {
|
|
55267
55267
|
"package": "himalaya",
|
|
55268
55268
|
"type": "HStack",
|
|
@@ -55281,43 +55281,34 @@ const SCREENS = runtimeSetting({
|
|
|
55281
55281
|
}
|
|
55282
55282
|
},
|
|
55283
55283
|
{
|
|
55284
|
-
"id": "",
|
|
55284
|
+
"id": "himi_owner_lite_aria.msg_$item.id.bubble",
|
|
55285
55285
|
"body": {
|
|
55286
55286
|
"package": "himalaya",
|
|
55287
55287
|
"type": "Text",
|
|
55288
55288
|
"props": {
|
|
55289
|
-
"text": "$item.
|
|
55290
|
-
"style": "
|
|
55291
|
-
"
|
|
55292
|
-
"maxLines": 1
|
|
55289
|
+
"text": "$item.content",
|
|
55290
|
+
"style": "body",
|
|
55291
|
+
"maxLines": 50
|
|
55293
55292
|
}
|
|
55294
|
-
}
|
|
55295
|
-
}
|
|
55296
|
-
]
|
|
55297
|
-
}
|
|
55298
|
-
}
|
|
55299
|
-
},
|
|
55300
|
-
{
|
|
55301
|
-
"id": "himi_owner_lite_aria.msg_$item.id.content",
|
|
55302
|
-
"body": {
|
|
55303
|
-
"package": "himalaya",
|
|
55304
|
-
"type": "HStack",
|
|
55305
|
-
"props": {
|
|
55306
|
-
"spacing": 0,
|
|
55307
|
-
"children": [
|
|
55308
|
-
{
|
|
55309
|
-
"id": "",
|
|
55310
|
-
"body": {
|
|
55311
|
-
"package": "himalaya",
|
|
55312
|
-
"type": "Spacer",
|
|
55313
|
-
"props": {}
|
|
55314
55293
|
},
|
|
55315
55294
|
"modifiers": {
|
|
55295
|
+
"accessibilityLabel": "$item.spoken",
|
|
55296
|
+
"padding": {
|
|
55297
|
+
"leading": 16,
|
|
55298
|
+
"trailing": 16,
|
|
55299
|
+
"top": 8,
|
|
55300
|
+
"bottom": 8
|
|
55301
|
+
},
|
|
55302
|
+
"background": {
|
|
55303
|
+
"token": "surfaceSecondary"
|
|
55304
|
+
},
|
|
55305
|
+
"cornerRadius": 20,
|
|
55306
|
+
"maxWidth": 300,
|
|
55316
55307
|
"hiddenPath": "$item.notUser"
|
|
55317
55308
|
}
|
|
55318
55309
|
},
|
|
55319
55310
|
{
|
|
55320
|
-
"id": "",
|
|
55311
|
+
"id": "himi_owner_lite_aria.msg_$item.id.text",
|
|
55321
55312
|
"body": {
|
|
55322
55313
|
"package": "himalaya",
|
|
55323
55314
|
"type": "Text",
|
|
@@ -55326,6 +55317,10 @@ const SCREENS = runtimeSetting({
|
|
|
55326
55317
|
"style": "body",
|
|
55327
55318
|
"maxLines": 50
|
|
55328
55319
|
}
|
|
55320
|
+
},
|
|
55321
|
+
"modifiers": {
|
|
55322
|
+
"accessibilityLabel": "$item.spoken",
|
|
55323
|
+
"hiddenPath": "$item.notAria"
|
|
55329
55324
|
}
|
|
55330
55325
|
}
|
|
55331
55326
|
]
|
|
@@ -83,6 +83,11 @@ export interface AriaBubble {
|
|
|
83
83
|
* that right-aligns the owner renders two templates and collapses one. */
|
|
84
84
|
notUser: boolean;
|
|
85
85
|
notAria: boolean;
|
|
86
|
+
/** What a screen reader says for the row: the author, then the words. A
|
|
87
|
+
* screen that draws the speaker only as a bubble and a side of the screen
|
|
88
|
+
* (`messageStyle: 'userBubble'`) has no visible author line to read, and
|
|
89
|
+
* without this the owner's question and Aria's reply sound the same. */
|
|
90
|
+
spoken: string;
|
|
86
91
|
link1Label: string; link1Url: string; link1Hidden: boolean;
|
|
87
92
|
link2Label: string; link2Url: string; link2Hidden: boolean;
|
|
88
93
|
link3Label: string; link3Url: string; link3Hidden: boolean;
|
|
@@ -561,9 +566,23 @@ export function disclosedLabel(link: { label: string; url: string }): string {
|
|
|
561
566
|
* machinery dies. (Measured: 20 tests, every one of them about polling.) */
|
|
562
567
|
export { stripMarkdown };
|
|
563
568
|
|
|
569
|
+
/** The screen-reader line for a bubble — see `AriaBubble.spoken`. */
|
|
570
|
+
export function spokenOf(who: string, content: string): string {
|
|
571
|
+
return who ? `${who}: ${content}` : content;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/** A persisted transcript from before `spoken` existed, made whole. A `$item.`
|
|
575
|
+
* path missing on a row does not substitute, so a row without the field would
|
|
576
|
+
* announce the literal binding until the next rebuild replaced it. */
|
|
577
|
+
export function withSpoken(bubbles: AriaBubble[]): AriaBubble[] {
|
|
578
|
+
return bubbles.every((b) => typeof b.spoken === "string")
|
|
579
|
+
? bubbles
|
|
580
|
+
: bubbles.map((b) => (typeof b.spoken === "string" ? b : { ...b, spoken: spokenOf(b.who, b.content) }));
|
|
581
|
+
}
|
|
582
|
+
|
|
564
583
|
/** A greeting or optimistic bubble: no links, all slots defaulted. */
|
|
565
584
|
export function plainBubble(id: string, role: string, who: string, content: string): AriaBubble {
|
|
566
|
-
return { id, role, who, content, notUser: role !== "USER", notAria: role === "USER", ...linkFieldsOf("", role) };
|
|
585
|
+
return { id, role, who, content, notUser: role !== "USER", notAria: role === "USER", spoken: spokenOf(who, content), ...linkFieldsOf("", role) };
|
|
567
586
|
}
|
|
568
587
|
|
|
569
588
|
/** Server transcript → bubbles. USER text is literal; ASSISTANT replies are
|
|
@@ -644,6 +663,7 @@ function bubbleOf(id: string, role: string, who: string, raw: string, writing: b
|
|
|
644
663
|
content,
|
|
645
664
|
notUser: role !== "USER",
|
|
646
665
|
notAria: role === "USER",
|
|
666
|
+
spoken: spokenOf(who, content),
|
|
647
667
|
...linkFieldsOf(prose, role),
|
|
648
668
|
};
|
|
649
669
|
}
|
|
@@ -2004,7 +2024,7 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
|
|
|
2004
2024
|
// a rehydrated turn there was no ladder at all, leaving "Aria is
|
|
2005
2025
|
// typing…" on screen with nothing ever fetching the answer.
|
|
2006
2026
|
if (s._pending || s.status === "sending") {
|
|
2007
|
-
const held: AriaChatState = { ...s, status: "sending", prompts: [] };
|
|
2027
|
+
const held: AriaChatState = { ...s, status: "sending", prompts: [], messages: withSpoken(s.messages) };
|
|
2008
2028
|
return cadence(held, o.poll ? o.poll.fastMs : null, null);
|
|
2009
2029
|
}
|
|
2010
2030
|
// …but the self-kick pass runs BEFORE the pack is stashed, so the
|
|
@@ -2013,7 +2033,7 @@ export function createAriaChat(o: AriaChatOptions): AriaChatCore {
|
|
|
2013
2033
|
// still the only thing on screen — `prompts` is already recomputed
|
|
2014
2034
|
// here, and a chip pack that localizes beside a greeting that does not
|
|
2015
2035
|
// is the visible half of the same bug.
|
|
2016
|
-
const messages = isGreetingOnly(s.messages) ? greetingOnly() : s.messages;
|
|
2036
|
+
const messages = isGreetingOnly(s.messages) ? greetingOnly() : withSpoken(s.messages);
|
|
2017
2037
|
return { ...s, status: "ready", messages, prompts: promptsFor(messages, promptList()) };
|
|
2018
2038
|
}
|
|
2019
2039
|
try {
|