viveworker 0.7.0-beta.3 → 0.7.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/package.json +1 -1
- package/scripts/viveworker-bridge.mjs +363 -111
- package/web/app.css +97 -4
- package/web/app.js +80 -46
- package/web/i18n.js +20 -8
- package/web/index.html +84 -0
- package/web/sw.js +2 -2
package/web/app.css
CHANGED
|
@@ -33,10 +33,16 @@
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
html {
|
|
36
|
+
width: 100%;
|
|
37
|
+
max-width: 100%;
|
|
38
|
+
overflow-x: hidden;
|
|
36
39
|
background: var(--bg);
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
body {
|
|
43
|
+
width: 100%;
|
|
44
|
+
max-width: 100%;
|
|
45
|
+
min-width: 0;
|
|
40
46
|
margin: 0;
|
|
41
47
|
min-height: 100vh;
|
|
42
48
|
overflow-x: hidden;
|
|
@@ -63,8 +69,17 @@ code {
|
|
|
63
69
|
background: rgba(156, 181, 197, 0.12);
|
|
64
70
|
}
|
|
65
71
|
|
|
72
|
+
#app {
|
|
73
|
+
width: 100%;
|
|
74
|
+
max-width: 100%;
|
|
75
|
+
min-width: 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
66
78
|
.app-shell {
|
|
79
|
+
width: 100%;
|
|
80
|
+
max-width: 100%;
|
|
67
81
|
min-height: 100vh;
|
|
82
|
+
overflow-x: clip;
|
|
68
83
|
padding:
|
|
69
84
|
max(1rem, env(safe-area-inset-top))
|
|
70
85
|
1rem
|
|
@@ -389,6 +404,8 @@ code {
|
|
|
389
404
|
}
|
|
390
405
|
|
|
391
406
|
.app-main {
|
|
407
|
+
width: 100%;
|
|
408
|
+
max-width: 100%;
|
|
392
409
|
display: grid;
|
|
393
410
|
gap: 1rem;
|
|
394
411
|
min-width: 0;
|
|
@@ -403,6 +420,16 @@ code {
|
|
|
403
420
|
.choice-stack {
|
|
404
421
|
display: grid;
|
|
405
422
|
gap: 1rem;
|
|
423
|
+
min-width: 0;
|
|
424
|
+
max-width: 100%;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
.timeline-shell,
|
|
428
|
+
.timeline-list,
|
|
429
|
+
.timeline-thread-filter,
|
|
430
|
+
.timeline-thread-filter__row {
|
|
431
|
+
min-width: 0;
|
|
432
|
+
max-width: 100%;
|
|
406
433
|
}
|
|
407
434
|
|
|
408
435
|
.detail-shell,
|
|
@@ -892,12 +919,37 @@ code {
|
|
|
892
919
|
gap: 0.18rem;
|
|
893
920
|
}
|
|
894
921
|
|
|
922
|
+
.settings-row__title-line {
|
|
923
|
+
min-width: 0;
|
|
924
|
+
display: inline-flex;
|
|
925
|
+
align-items: center;
|
|
926
|
+
gap: 0.42rem;
|
|
927
|
+
}
|
|
928
|
+
|
|
895
929
|
.settings-row__title,
|
|
896
930
|
.settings-info-row__label {
|
|
931
|
+
min-width: 0;
|
|
897
932
|
font-size: 1rem;
|
|
898
933
|
line-height: 1.3;
|
|
899
934
|
}
|
|
900
935
|
|
|
936
|
+
.settings-row__badge {
|
|
937
|
+
flex: 0 0 auto;
|
|
938
|
+
display: inline-flex;
|
|
939
|
+
align-items: center;
|
|
940
|
+
min-height: 1.18rem;
|
|
941
|
+
padding: 0.08rem 0.42rem 0.1rem;
|
|
942
|
+
border-radius: 999px;
|
|
943
|
+
border: 1px solid rgba(240, 180, 40, 0.26);
|
|
944
|
+
background: rgba(240, 180, 40, 0.11);
|
|
945
|
+
color: rgba(255, 220, 140, 0.96);
|
|
946
|
+
font-size: 0.66rem;
|
|
947
|
+
font-weight: 800;
|
|
948
|
+
letter-spacing: 0.04em;
|
|
949
|
+
line-height: 1;
|
|
950
|
+
text-transform: uppercase;
|
|
951
|
+
}
|
|
952
|
+
|
|
901
953
|
.settings-row__subtitle {
|
|
902
954
|
color: var(--muted);
|
|
903
955
|
font-size: 0.84rem;
|
|
@@ -1237,6 +1289,18 @@ code {
|
|
|
1237
1289
|
background: rgba(53, 26, 29, 0.96);
|
|
1238
1290
|
}
|
|
1239
1291
|
|
|
1292
|
+
.wallet-beta-notice {
|
|
1293
|
+
border-color: rgba(240, 180, 40, 0.18);
|
|
1294
|
+
background: rgba(42, 34, 22, 0.78);
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
.wallet-beta-notice p {
|
|
1298
|
+
margin: 0;
|
|
1299
|
+
color: rgba(255, 220, 140, 0.9);
|
|
1300
|
+
font-size: 0.84rem;
|
|
1301
|
+
line-height: 1.5;
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1240
1304
|
.settings-update-notice {
|
|
1241
1305
|
margin-top: 0.85rem;
|
|
1242
1306
|
border-color: rgba(121, 196, 255, 0.22);
|
|
@@ -1321,7 +1385,8 @@ code {
|
|
|
1321
1385
|
border-color: rgba(112, 202, 157, 0.16);
|
|
1322
1386
|
}
|
|
1323
1387
|
|
|
1324
|
-
.wallet-step-card--locked
|
|
1388
|
+
.wallet-step-card--locked,
|
|
1389
|
+
.wallet-step-card--comingSoon {
|
|
1325
1390
|
opacity: 0.78;
|
|
1326
1391
|
}
|
|
1327
1392
|
|
|
@@ -1408,7 +1473,8 @@ code {
|
|
|
1408
1473
|
color: rgba(205, 220, 231, 0.6);
|
|
1409
1474
|
}
|
|
1410
1475
|
|
|
1411
|
-
.wallet-step-card__status--optional
|
|
1476
|
+
.wallet-step-card__status--optional,
|
|
1477
|
+
.wallet-step-card__status--comingSoon {
|
|
1412
1478
|
border-color: rgba(240, 180, 40, 0.22);
|
|
1413
1479
|
background: rgba(240, 180, 40, 0.12);
|
|
1414
1480
|
color: rgba(255, 220, 140, 0.96);
|
|
@@ -1735,12 +1801,17 @@ code {
|
|
|
1735
1801
|
}
|
|
1736
1802
|
|
|
1737
1803
|
.card-list {
|
|
1804
|
+
width: 100%;
|
|
1805
|
+
max-width: 100%;
|
|
1806
|
+
min-width: 0;
|
|
1738
1807
|
display: grid;
|
|
1739
1808
|
gap: 0.85rem;
|
|
1740
1809
|
}
|
|
1741
1810
|
|
|
1742
1811
|
.item-card {
|
|
1743
1812
|
width: 100%;
|
|
1813
|
+
min-width: 0;
|
|
1814
|
+
overflow: hidden;
|
|
1744
1815
|
display: grid;
|
|
1745
1816
|
gap: 0.8rem;
|
|
1746
1817
|
padding: 0.95rem;
|
|
@@ -1754,6 +1825,7 @@ code {
|
|
|
1754
1825
|
}
|
|
1755
1826
|
|
|
1756
1827
|
.item-card__header {
|
|
1828
|
+
min-width: 0;
|
|
1757
1829
|
display: flex;
|
|
1758
1830
|
justify-content: space-between;
|
|
1759
1831
|
gap: 0.8rem;
|
|
@@ -1761,11 +1833,12 @@ code {
|
|
|
1761
1833
|
}
|
|
1762
1834
|
|
|
1763
1835
|
.item-card__header-right {
|
|
1836
|
+
flex: 0 0 auto;
|
|
1764
1837
|
display: inline-flex;
|
|
1765
1838
|
align-items: center;
|
|
1766
1839
|
justify-content: flex-end;
|
|
1767
1840
|
gap: 0.55rem;
|
|
1768
|
-
min-width:
|
|
1841
|
+
min-width: 0;
|
|
1769
1842
|
}
|
|
1770
1843
|
|
|
1771
1844
|
.item-card__header--completion-readonly {
|
|
@@ -1775,18 +1848,21 @@ code {
|
|
|
1775
1848
|
|
|
1776
1849
|
.item-card__meta,
|
|
1777
1850
|
.detail-pills {
|
|
1851
|
+
min-width: 0;
|
|
1778
1852
|
display: flex;
|
|
1779
1853
|
flex-wrap: wrap;
|
|
1780
1854
|
gap: 0.55rem;
|
|
1781
1855
|
}
|
|
1782
1856
|
|
|
1783
1857
|
.item-card__content {
|
|
1858
|
+
min-width: 0;
|
|
1784
1859
|
display: grid;
|
|
1785
1860
|
gap: 0.38rem;
|
|
1786
1861
|
}
|
|
1787
1862
|
|
|
1788
1863
|
.item-card__intent,
|
|
1789
1864
|
.detail-intent {
|
|
1865
|
+
min-width: 0;
|
|
1790
1866
|
margin: 0;
|
|
1791
1867
|
display: inline-flex;
|
|
1792
1868
|
align-items: center;
|
|
@@ -1794,6 +1870,7 @@ code {
|
|
|
1794
1870
|
color: rgba(236, 248, 255, 0.86);
|
|
1795
1871
|
font-size: 0.84rem;
|
|
1796
1872
|
line-height: 1.35;
|
|
1873
|
+
overflow-wrap: anywhere;
|
|
1797
1874
|
}
|
|
1798
1875
|
|
|
1799
1876
|
.item-card__intent {
|
|
@@ -1810,6 +1887,7 @@ code {
|
|
|
1810
1887
|
}
|
|
1811
1888
|
|
|
1812
1889
|
.item-card__title {
|
|
1890
|
+
min-width: 0;
|
|
1813
1891
|
margin: 0;
|
|
1814
1892
|
font-size: 1.08rem;
|
|
1815
1893
|
line-height: 1.35;
|
|
@@ -1817,6 +1895,7 @@ code {
|
|
|
1817
1895
|
}
|
|
1818
1896
|
|
|
1819
1897
|
.item-card__summary {
|
|
1898
|
+
min-width: 0;
|
|
1820
1899
|
margin: 0;
|
|
1821
1900
|
color: var(--muted);
|
|
1822
1901
|
line-height: 1.45;
|
|
@@ -1828,6 +1907,7 @@ code {
|
|
|
1828
1907
|
}
|
|
1829
1908
|
|
|
1830
1909
|
.item-card__thread {
|
|
1910
|
+
min-width: 0;
|
|
1831
1911
|
margin: 0;
|
|
1832
1912
|
color: var(--muted);
|
|
1833
1913
|
font-size: 0.82rem;
|
|
@@ -2101,6 +2181,8 @@ code {
|
|
|
2101
2181
|
|
|
2102
2182
|
.timeline-entry {
|
|
2103
2183
|
width: 100%;
|
|
2184
|
+
min-width: 0;
|
|
2185
|
+
overflow: hidden;
|
|
2104
2186
|
display: grid;
|
|
2105
2187
|
gap: 0.55rem;
|
|
2106
2188
|
padding: 0.92rem;
|
|
@@ -2288,6 +2370,7 @@ code {
|
|
|
2288
2370
|
}
|
|
2289
2371
|
|
|
2290
2372
|
.timeline-entry__meta {
|
|
2373
|
+
min-width: 0;
|
|
2291
2374
|
display: grid;
|
|
2292
2375
|
grid-template-columns: minmax(0, 1fr) auto;
|
|
2293
2376
|
gap: 0.75rem;
|
|
@@ -2305,6 +2388,7 @@ code {
|
|
|
2305
2388
|
min-width: 0;
|
|
2306
2389
|
display: inline-flex;
|
|
2307
2390
|
align-items: center;
|
|
2391
|
+
flex-wrap: wrap;
|
|
2308
2392
|
gap: 0.42rem;
|
|
2309
2393
|
color: #edf8ff;
|
|
2310
2394
|
font-size: 0.8rem;
|
|
@@ -2338,6 +2422,7 @@ code {
|
|
|
2338
2422
|
}
|
|
2339
2423
|
|
|
2340
2424
|
.timeline-entry__body {
|
|
2425
|
+
min-width: 0;
|
|
2341
2426
|
display: grid;
|
|
2342
2427
|
gap: 0.34rem;
|
|
2343
2428
|
}
|
|
@@ -2408,6 +2493,7 @@ code {
|
|
|
2408
2493
|
|
|
2409
2494
|
.timeline-entry__title,
|
|
2410
2495
|
.timeline-entry__summary {
|
|
2496
|
+
min-width: 0;
|
|
2411
2497
|
margin: 0;
|
|
2412
2498
|
overflow-wrap: anywhere;
|
|
2413
2499
|
}
|
|
@@ -4721,7 +4807,9 @@ button[aria-busy="true"]:not(.is-loading) {
|
|
|
4721
4807
|
}
|
|
4722
4808
|
|
|
4723
4809
|
.provider-filter {
|
|
4724
|
-
|
|
4810
|
+
width: 100%;
|
|
4811
|
+
min-width: 0;
|
|
4812
|
+
display: flex;
|
|
4725
4813
|
align-items: center;
|
|
4726
4814
|
gap: 0.25rem;
|
|
4727
4815
|
padding: 0.2rem;
|
|
@@ -4732,8 +4820,13 @@ button[aria-busy="true"]:not(.is-loading) {
|
|
|
4732
4820
|
max-width: 100%;
|
|
4733
4821
|
overflow-x: auto;
|
|
4734
4822
|
-webkit-overflow-scrolling: touch;
|
|
4823
|
+
scrollbar-width: none;
|
|
4824
|
+
}
|
|
4825
|
+
.provider-filter::-webkit-scrollbar {
|
|
4826
|
+
display: none;
|
|
4735
4827
|
}
|
|
4736
4828
|
.provider-filter__button {
|
|
4829
|
+
min-width: 0;
|
|
4737
4830
|
appearance: none;
|
|
4738
4831
|
background: transparent;
|
|
4739
4832
|
color: var(--text-muted, #9aa6b2);
|
package/web/app.js
CHANGED
|
@@ -132,6 +132,23 @@ function hazbasePasskeyHostSupport() {
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
const app = document.querySelector("#app");
|
|
135
|
+
let bootSplashDismissed = false;
|
|
136
|
+
|
|
137
|
+
function dismissBootSplash() {
|
|
138
|
+
if (bootSplashDismissed || typeof document === "undefined") {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
bootSplashDismissed = true;
|
|
142
|
+
const splash = document.querySelector("#boot-splash");
|
|
143
|
+
document.body?.classList.add("viveworker-ready");
|
|
144
|
+
if (!splash) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
splash.setAttribute("aria-hidden", "true");
|
|
148
|
+
window.setTimeout(() => {
|
|
149
|
+
splash.remove();
|
|
150
|
+
}, 280);
|
|
151
|
+
}
|
|
135
152
|
const params = new URLSearchParams(window.location.search);
|
|
136
153
|
const initialItem = params.get("item") || "";
|
|
137
154
|
const initialTargetTab = params.get("tab") || "";
|
|
@@ -146,6 +163,7 @@ boot().catch((error) => {
|
|
|
146
163
|
const hint = /Load failed|Failed to fetch|NetworkError|fetch/i.test(message)
|
|
147
164
|
? `<p class="muted">${escapeHtml(L("error.networkHint"))}</p>`
|
|
148
165
|
: "";
|
|
166
|
+
dismissBootSplash();
|
|
149
167
|
app.innerHTML = `
|
|
150
168
|
<main class="onboarding-shell">
|
|
151
169
|
<section class="onboarding-card">
|
|
@@ -1171,6 +1189,7 @@ function renderPair() {
|
|
|
1171
1189
|
});
|
|
1172
1190
|
|
|
1173
1191
|
bindSharedUi(renderPair);
|
|
1192
|
+
requestAnimationFrame(dismissBootSplash);
|
|
1174
1193
|
}
|
|
1175
1194
|
|
|
1176
1195
|
async function pair(payload) {
|
|
@@ -1279,6 +1298,7 @@ async function renderShell() {
|
|
|
1279
1298
|
applyPendingListScrollRestore();
|
|
1280
1299
|
applyPendingSettingsSubpageScrollReset();
|
|
1281
1300
|
applyPendingSettingsScrollRestore();
|
|
1301
|
+
requestAnimationFrame(dismissBootSplash);
|
|
1282
1302
|
}
|
|
1283
1303
|
|
|
1284
1304
|
function applyPendingDetailScrollReset() {
|
|
@@ -1899,7 +1919,11 @@ function buildActionOutcomeDetail({ kind, title, message }) {
|
|
|
1899
1919
|
|
|
1900
1920
|
function approvalOutcomeMessage(actionUrl, provider) {
|
|
1901
1921
|
const vars = { provider: providerDisplayName(provider) };
|
|
1902
|
-
|
|
1922
|
+
const normalizedUrl = String(actionUrl || "");
|
|
1923
|
+
if (/\/api\/payments\/x402\/hazbase-wallet\/[^/]+\/pay$/u.test(normalizedUrl)) {
|
|
1924
|
+
return L("server.message.paymentSubmitted");
|
|
1925
|
+
}
|
|
1926
|
+
return /\/accept$/u.test(normalizedUrl)
|
|
1903
1927
|
? L("server.message.approvalAccepted", vars)
|
|
1904
1928
|
: L("server.message.approvalRejected", vars);
|
|
1905
1929
|
}
|
|
@@ -2617,6 +2641,8 @@ function timelineEntryStatusLabel(item, isMessageLike) {
|
|
|
2617
2641
|
return L("timeline.status.approved");
|
|
2618
2642
|
case "rejected":
|
|
2619
2643
|
return L("timeline.status.rejected");
|
|
2644
|
+
case "failed":
|
|
2645
|
+
return L("timeline.status.failed");
|
|
2620
2646
|
case "implemented":
|
|
2621
2647
|
return L("timeline.status.implemented");
|
|
2622
2648
|
case "dismissed":
|
|
@@ -3518,6 +3544,7 @@ function renderSettingsRoot(context, { mobile }) {
|
|
|
3518
3544
|
page: "wallet",
|
|
3519
3545
|
icon: "coin",
|
|
3520
3546
|
title: L("settings.wallet.title"),
|
|
3547
|
+
badge: "beta",
|
|
3521
3548
|
subtitle: L("settings.wallet.subtitle"),
|
|
3522
3549
|
value: context.hazbase?.sessionInvalid
|
|
3523
3550
|
? L("settings.hazbase.status.sessionExpired")
|
|
@@ -3780,12 +3807,15 @@ function renderSettingsGroup(title, rows, options = {}) {
|
|
|
3780
3807
|
`;
|
|
3781
3808
|
}
|
|
3782
3809
|
|
|
3783
|
-
function renderSettingsNavRow({ page, icon, title, subtitle, value }) {
|
|
3810
|
+
function renderSettingsNavRow({ page, icon, title, badge, subtitle, value }) {
|
|
3784
3811
|
return `
|
|
3785
3812
|
<button class="settings-nav-row" type="button" data-settings-subpage="${escapeHtml(page)}">
|
|
3786
3813
|
<span class="settings-row__icon" aria-hidden="true">${renderIcon(icon)}</span>
|
|
3787
3814
|
<span class="settings-row__body">
|
|
3788
|
-
<span class="settings-row__title"
|
|
3815
|
+
<span class="settings-row__title-line">
|
|
3816
|
+
<span class="settings-row__title">${escapeHtml(title)}</span>
|
|
3817
|
+
${badge ? `<span class="settings-row__badge">${escapeHtml(badge)}</span>` : ""}
|
|
3818
|
+
</span>
|
|
3789
3819
|
${subtitle ? `<span class="settings-row__subtitle">${escapeHtml(subtitle)}</span>` : ""}
|
|
3790
3820
|
</span>
|
|
3791
3821
|
<span class="settings-row__value">${escapeHtml(value || "")}</span>
|
|
@@ -4565,6 +4595,7 @@ function renderSettingsWalletPage(context) {
|
|
|
4565
4595
|
// longer duplicated.
|
|
4566
4596
|
const guideRows = [
|
|
4567
4597
|
renderHazbaseWalletBanner(flow),
|
|
4598
|
+
renderHazbaseWalletBetaNotice(),
|
|
4568
4599
|
state.hazbaseNotice
|
|
4569
4600
|
? `<div class="settings-copy-block settings-copy-block--compact wallet-flow-message wallet-flow-message--notice"><p>${escapeHtml(state.hazbaseNotice)}</p></div>`
|
|
4570
4601
|
: "",
|
|
@@ -4616,15 +4647,10 @@ function renderSettingsWalletPage(context) {
|
|
|
4616
4647
|
function renderHazbaseWalletStepList(flow) {
|
|
4617
4648
|
const rendered = [];
|
|
4618
4649
|
for (const step of flow.steps) {
|
|
4619
|
-
//
|
|
4620
|
-
//
|
|
4621
|
-
//
|
|
4622
|
-
|
|
4623
|
-
// true completion boundary; the ready banner already keys off
|
|
4624
|
-
// `coreReady = signedIn && hasPasskey && hasBaseSepolia`. Drop this
|
|
4625
|
-
// guard (and restore the opt-in reveal) once mainnet is enabled
|
|
4626
|
-
// server-side.
|
|
4627
|
-
if (step.number === 4) {
|
|
4650
|
+
// Keep the Base mainnet roadmap visible only after the usable Base Sepolia
|
|
4651
|
+
// wallet is ready. Showing Step 4 during email/passkey setup makes the
|
|
4652
|
+
// sequential flow feel like there is another action competing for focus.
|
|
4653
|
+
if (step.number === 4 && step.status === "comingSoon" && !flow.coreReady) {
|
|
4628
4654
|
continue;
|
|
4629
4655
|
}
|
|
4630
4656
|
|
|
@@ -4764,16 +4790,10 @@ function deriveHazbaseWalletFlow(hazbase) {
|
|
|
4764
4790
|
icon: "coin",
|
|
4765
4791
|
title: L("settings.wallet.step.base.title"),
|
|
4766
4792
|
copy: L("settings.wallet.step.base.copy"),
|
|
4767
|
-
detail: baseMainnet?.smartAccountAddress || L("settings.
|
|
4793
|
+
detail: baseMainnet?.smartAccountAddress || L("settings.wallet.step.base.comingSoonDetail"),
|
|
4768
4794
|
monoDetail: Boolean(baseMainnet?.smartAccountAddress),
|
|
4769
|
-
status: hasBaseMainnet ? "complete" :
|
|
4770
|
-
actions:
|
|
4771
|
-
? []
|
|
4772
|
-
: [
|
|
4773
|
-
actionButton("settings.hazbase.action.bootstrapBase", "bootstrap-base", {
|
|
4774
|
-
disabled: !coreReady,
|
|
4775
|
-
}),
|
|
4776
|
-
],
|
|
4795
|
+
status: hasBaseMainnet ? "complete" : "comingSoon",
|
|
4796
|
+
actions: [],
|
|
4777
4797
|
},
|
|
4778
4798
|
],
|
|
4779
4799
|
};
|
|
@@ -4825,14 +4845,29 @@ function renderHazbaseWalletBanner(flow) {
|
|
|
4825
4845
|
`;
|
|
4826
4846
|
}
|
|
4827
4847
|
|
|
4848
|
+
function renderHazbaseWalletBetaNotice() {
|
|
4849
|
+
return `
|
|
4850
|
+
<div class="settings-copy-block settings-copy-block--compact wallet-beta-notice">
|
|
4851
|
+
<p>${escapeHtml(L("settings.wallet.betaNotice"))}</p>
|
|
4852
|
+
</div>
|
|
4853
|
+
`;
|
|
4854
|
+
}
|
|
4855
|
+
|
|
4828
4856
|
function renderHazbaseWalletStepCard(step, { mode = "full" } = {}) {
|
|
4829
4857
|
const statusMeta = {
|
|
4830
4858
|
complete: { label: L("settings.wallet.status.complete"), icon: "completed" },
|
|
4831
4859
|
current: { label: L("settings.wallet.status.current"), icon: "pending" },
|
|
4832
4860
|
locked: { label: L("settings.wallet.status.locked"), icon: "lock" },
|
|
4833
4861
|
optional: { label: L("settings.wallet.status.optional"), icon: "coin" },
|
|
4862
|
+
comingSoon: { label: L("settings.wallet.status.comingSoon"), icon: "coin" },
|
|
4834
4863
|
pending: { label: L("settings.wallet.status.pending"), icon: "pending" },
|
|
4835
4864
|
}[step.status] || { label: L("settings.wallet.status.pending"), icon: "pending" };
|
|
4865
|
+
const statusChipHtml = step.status === "current"
|
|
4866
|
+
? ""
|
|
4867
|
+
: `<span class="wallet-step-card__status wallet-step-card__status--${escapeHtml(step.status)}">
|
|
4868
|
+
<span class="wallet-step-card__status-icon" aria-hidden="true">${renderIcon(statusMeta.icon)}</span>
|
|
4869
|
+
<span>${escapeHtml(statusMeta.label)}</span>
|
|
4870
|
+
</span>`;
|
|
4836
4871
|
|
|
4837
4872
|
if (mode === "compact") {
|
|
4838
4873
|
// Compact row for finished steps. Keeps the check icon + title + one-line
|
|
@@ -4863,10 +4898,7 @@ function renderHazbaseWalletStepCard(step, { mode = "full" } = {}) {
|
|
|
4863
4898
|
<h3 class="wallet-step-card__title">${escapeHtml(step.title)}</h3>
|
|
4864
4899
|
</div>
|
|
4865
4900
|
</div>
|
|
4866
|
-
|
|
4867
|
-
<span class="wallet-step-card__status-icon" aria-hidden="true">${renderIcon(statusMeta.icon)}</span>
|
|
4868
|
-
<span>${escapeHtml(statusMeta.label)}</span>
|
|
4869
|
-
</span>
|
|
4901
|
+
${statusChipHtml}
|
|
4870
4902
|
</div>
|
|
4871
4903
|
<p class="wallet-step-card__copy">${escapeHtml(step.copy)}</p>
|
|
4872
4904
|
<p class="wallet-step-card__detail ${step.monoDetail ? "wallet-step-card__detail--mono" : ""}">${escapeHtml(step.detail)}</p>
|
|
@@ -6496,20 +6528,7 @@ function renderLogoutConfirmModal() {
|
|
|
6496
6528
|
<strong id="logout-confirm-title">${escapeHtml(L("logout.confirm.title"))}</strong>
|
|
6497
6529
|
<p class="muted">${escapeHtml(L("logout.confirm.copy"))}</p>
|
|
6498
6530
|
</div>
|
|
6499
|
-
<
|
|
6500
|
-
<div class="logout-option__copy">
|
|
6501
|
-
<strong>${escapeHtml(L("logout.confirm.keepTrustedTitle"))}</strong>
|
|
6502
|
-
<p class="muted">${escapeHtml(L("logout.confirm.keepTrustedCopy"))}</p>
|
|
6503
|
-
</div>
|
|
6504
|
-
<button class="primary primary--wide" type="button" data-logout-mode="session">${escapeHtml(L("logout.action.keepTrusted"))}</button>
|
|
6505
|
-
</div>
|
|
6506
|
-
<div class="logout-option logout-option--danger">
|
|
6507
|
-
<div class="logout-option__copy">
|
|
6508
|
-
<strong>${escapeHtml(L("logout.confirm.removeTitle"))}</strong>
|
|
6509
|
-
<p class="muted">${escapeHtml(L("logout.confirm.removeCopy"))}</p>
|
|
6510
|
-
</div>
|
|
6511
|
-
<button class="secondary secondary--wide" type="button" data-logout-mode="revoke">${escapeHtml(L("logout.action.removeDevice"))}</button>
|
|
6512
|
-
</div>
|
|
6531
|
+
<button class="secondary secondary--wide" type="button" data-logout-mode="session">${escapeHtml(L("logout.action.keepTrusted"))}</button>
|
|
6513
6532
|
<button class="ghost ghost--wide" type="button" data-close-logout-confirm>${escapeHtml(L("common.cancel"))}</button>
|
|
6514
6533
|
</section>
|
|
6515
6534
|
</div>
|
|
@@ -6870,18 +6889,33 @@ function bindShellInteractions() {
|
|
|
6870
6889
|
state.pendingActionUrls.delete(actionUrl);
|
|
6871
6890
|
} catch (error) {
|
|
6872
6891
|
state.pendingActionUrls.delete(actionUrl);
|
|
6892
|
+
const approvalFinalized = Boolean(error?.payload?.approvalFinalized);
|
|
6873
6893
|
if (error?.errorKey === "hazbase-session-expired") {
|
|
6874
6894
|
await fetchHazbaseStatus();
|
|
6875
6895
|
}
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
if (
|
|
6879
|
-
|
|
6896
|
+
if (approvalFinalized) {
|
|
6897
|
+
await refreshAuthenticatedState();
|
|
6898
|
+
if (keepDetailOpen && activeItem?.kind === "approval") {
|
|
6899
|
+
pinActionOutcomeDetail(
|
|
6900
|
+
activeItem,
|
|
6901
|
+
buildActionOutcomeDetail({
|
|
6902
|
+
kind: "approval",
|
|
6903
|
+
title: state.currentDetail?.title,
|
|
6904
|
+
message: L("server.message.paymentFailed", { reason: error.message || String(error) }),
|
|
6905
|
+
})
|
|
6906
|
+
);
|
|
6880
6907
|
}
|
|
6881
|
-
|
|
6882
|
-
|
|
6908
|
+
} else {
|
|
6909
|
+
// Restore buttons on recoverable failure so the user can retry the same action.
|
|
6910
|
+
for (const sibling of siblingButtons) {
|
|
6911
|
+
if (originalLabels.has(sibling)) {
|
|
6912
|
+
sibling.innerHTML = originalLabels.get(sibling);
|
|
6913
|
+
}
|
|
6914
|
+
sibling.disabled = false;
|
|
6915
|
+
sibling.removeAttribute("aria-busy");
|
|
6916
|
+
}
|
|
6917
|
+
button.classList.remove("is-loading");
|
|
6883
6918
|
}
|
|
6884
|
-
button.classList.remove("is-loading");
|
|
6885
6919
|
state.pushError = error.message || String(error);
|
|
6886
6920
|
await renderShell();
|
|
6887
6921
|
}
|
package/web/i18n.js
CHANGED
|
@@ -250,6 +250,7 @@ const translations = {
|
|
|
250
250
|
"timeline.filterLabel": "Thread filter",
|
|
251
251
|
"timeline.status.approved": "Approved",
|
|
252
252
|
"timeline.status.rejected": "Rejected",
|
|
253
|
+
"timeline.status.failed": "Failed",
|
|
253
254
|
"timeline.status.implemented": "Started",
|
|
254
255
|
"timeline.status.dismissed": "Dismissed",
|
|
255
256
|
"timeline.status.submitted": "Sent",
|
|
@@ -520,6 +521,7 @@ const translations = {
|
|
|
520
521
|
"settings.wallet.flow.title": "Recommended order",
|
|
521
522
|
"settings.wallet.flow.banner.title": "Let's set up your wallet",
|
|
522
523
|
"settings.wallet.flow.copy": "You need to activate your wallet to exchange task rewards over A2A.",
|
|
524
|
+
"settings.wallet.betaNotice": "Wallet is in beta. During this test period, wallet payments and payouts are available on testnets only.",
|
|
523
525
|
"settings.wallet.sessionExpired.title": "Refresh your wallet session",
|
|
524
526
|
"settings.wallet.sessionExpired.copy": "Your wallet session expired. Sign in again with a one-time password; your passkey and Base Sepolia address stay linked.",
|
|
525
527
|
"settings.wallet.ready.title": "Ready to use",
|
|
@@ -533,6 +535,7 @@ const translations = {
|
|
|
533
535
|
"settings.wallet.status.pending": "Pending",
|
|
534
536
|
"settings.wallet.status.locked": "Waiting",
|
|
535
537
|
"settings.wallet.status.optional": "Optional",
|
|
538
|
+
"settings.wallet.status.comingSoon": "Coming soon",
|
|
536
539
|
"settings.wallet.step.signIn.title": "Sign in with email",
|
|
537
540
|
"settings.wallet.step.signIn.copy": "Send a one-time password to your email, then enter it here to sign in to your wallet.",
|
|
538
541
|
"settings.wallet.step.refreshSession.title": "Refresh session",
|
|
@@ -542,7 +545,8 @@ const translations = {
|
|
|
542
545
|
"settings.wallet.step.baseSepolia.title": "Issue a Base Sepolia wallet",
|
|
543
546
|
"settings.wallet.step.baseSepolia.copy": "Create a testing wallet for the current beta flow. This is the main wallet we recommend issuing first.",
|
|
544
547
|
"settings.wallet.step.base.title": "Issue a Base wallet",
|
|
545
|
-
"settings.wallet.step.base.copy": "
|
|
548
|
+
"settings.wallet.step.base.copy": "Base mainnet wallet issuance is planned for production payouts. It is not active yet.",
|
|
549
|
+
"settings.wallet.step.base.comingSoonDetail": "Coming soon",
|
|
546
550
|
"settings.wallet.mainnet.optIn": "Also set up Base mainnet",
|
|
547
551
|
"settings.wallet.mainnet.optInHint": "Optional — required only for production payouts.",
|
|
548
552
|
"settings.hazbase.title": "Wallet",
|
|
@@ -707,6 +711,8 @@ const translations = {
|
|
|
707
711
|
"claudeAway.notifyOnly.notice": "Sync mode is OFF — please respond on the desktop. {provider} is waiting for input there.",
|
|
708
712
|
"server.message.approvalAccepted": "Approved. {provider} will continue.",
|
|
709
713
|
"server.message.approvalRejected": "Rejected. {provider} was told not to continue this action.",
|
|
714
|
+
"server.message.paymentSubmitted": "Payment submitted. Waiting for settlement to complete.",
|
|
715
|
+
"server.message.paymentFailed": "Payment failed: {reason}",
|
|
710
716
|
"server.message.planImplemented": "{provider} was asked to start implementing from this plan.",
|
|
711
717
|
"server.message.planDismissed": "This plan prompt was closed and future reminders were suppressed.",
|
|
712
718
|
"server.confirm.planImplement": "Implementation will start from this plan.",
|
|
@@ -828,8 +834,8 @@ const translations = {
|
|
|
828
834
|
"Open the HTTP URL in a mobile browser only if you intentionally allowed insecure LAN access. This mode is not recommended on shared Wi-Fi.",
|
|
829
835
|
"cli.setup.instructions.localOnlyHttp":
|
|
830
836
|
"This setup is loopback-only HTTP for local development. Use the default HTTPS setup or --allow-insecure-http-lan if you explicitly need LAN access.",
|
|
831
|
-
"logout.confirm.title": "
|
|
832
|
-
"logout.confirm.copy": "
|
|
837
|
+
"logout.confirm.title": "Log out of viveworker?",
|
|
838
|
+
"logout.confirm.copy": "This ends the current session. This device stays trusted, so you can come back without pairing again.",
|
|
833
839
|
"logout.confirm.keepTrustedTitle": "Log out only",
|
|
834
840
|
"logout.confirm.keepTrustedCopy": "End this session now, but keep this device trusted for the next time you open viveworker.",
|
|
835
841
|
"logout.confirm.removeTitle": "Log out and remove this device",
|
|
@@ -1167,6 +1173,7 @@ const translations = {
|
|
|
1167
1173
|
"timeline.filterLabel": "スレッドフィルター",
|
|
1168
1174
|
"timeline.status.approved": "承認済み",
|
|
1169
1175
|
"timeline.status.rejected": "拒否済み",
|
|
1176
|
+
"timeline.status.failed": "失敗",
|
|
1170
1177
|
"timeline.status.implemented": "実装開始",
|
|
1171
1178
|
"timeline.status.dismissed": "見送り",
|
|
1172
1179
|
"timeline.status.submitted": "送信済み",
|
|
@@ -1293,14 +1300,14 @@ const translations = {
|
|
|
1293
1300
|
"settings.install.title": "ホーム画面に追加",
|
|
1294
1301
|
"settings.install.copy":
|
|
1295
1302
|
"いちばん使いやすい体験にするには、viveworker をホーム画面に追加して、インストール版を開いてください。",
|
|
1296
|
-
"settings.device.title": "
|
|
1303
|
+
"settings.device.title": "信頼済み端末",
|
|
1297
1304
|
"settings.device.copy": "この LAN 上で viveworker を開ける信頼済み端末を管理します。",
|
|
1298
1305
|
"settings.device.count": ({ count }) => `${count} 台の端末`,
|
|
1299
1306
|
"settings.device.section.current": "この端末",
|
|
1300
1307
|
"settings.device.section.other": "他の信頼済み端末",
|
|
1301
1308
|
"settings.device.thisDevice": "この端末",
|
|
1302
1309
|
"settings.device.emptyCurrent": "この端末は現在の有効な信頼済み端末一覧には入っていません。以前の信頼期限が切れたか、削除された可能性があります。必要なら Mac で `npx viveworker pair` を実行して再ペアリングしてください。",
|
|
1303
|
-
"settings.device.emptyOther": "
|
|
1310
|
+
"settings.device.emptyOther": "他に有効な信頼済み端末はありません。",
|
|
1304
1311
|
"settings.device.addAnother.title": "端末を追加する",
|
|
1305
1312
|
"settings.device.addAnother.heading": "新しい端末 / ブラウザを追加",
|
|
1306
1313
|
"settings.device.addAnother.copy":
|
|
@@ -1437,6 +1444,7 @@ const translations = {
|
|
|
1437
1444
|
"settings.wallet.flow.title": "おすすめの順番",
|
|
1438
1445
|
"settings.wallet.flow.banner.title": "まずは、セットアップしましょう",
|
|
1439
1446
|
"settings.wallet.flow.copy": "A2A でタスクの報酬をやりとりするには、ウォレットを有効化する必要があります。",
|
|
1447
|
+
"settings.wallet.betaNotice": "ウォレット機能はベータテスト中です。この期間はテストネットでのみ支払い・受け取りを利用できます。",
|
|
1440
1448
|
"settings.wallet.sessionExpired.title": "ウォレットセッションを更新しましょう",
|
|
1441
1449
|
"settings.wallet.sessionExpired.copy": "ウォレットのセッションが切れています。ワンタイムパスワードで再サインインすれば、Passkey と Base Sepolia アドレスはそのまま使えます。",
|
|
1442
1450
|
"settings.wallet.ready.title": "利用準備ができました",
|
|
@@ -1450,6 +1458,7 @@ const translations = {
|
|
|
1450
1458
|
"settings.wallet.status.pending": "保留",
|
|
1451
1459
|
"settings.wallet.status.locked": "前の step 待ち",
|
|
1452
1460
|
"settings.wallet.status.optional": "任意",
|
|
1461
|
+
"settings.wallet.status.comingSoon": "Coming soon",
|
|
1453
1462
|
"settings.wallet.step.signIn.title": "メールでサインイン",
|
|
1454
1463
|
"settings.wallet.step.signIn.copy": "メールにワンタイムパスワードを送り、届いた値を入力してウォレットにサインインします。",
|
|
1455
1464
|
"settings.wallet.step.refreshSession.title": "セッションを更新",
|
|
@@ -1459,7 +1468,8 @@ const translations = {
|
|
|
1459
1468
|
"settings.wallet.step.baseSepolia.title": "Base Sepolia ウォレットを発行",
|
|
1460
1469
|
"settings.wallet.step.baseSepolia.copy": "現在の beta フローで使うテスト用ウォレットを発行します。まずはこれを用意するのがおすすめです。",
|
|
1461
1470
|
"settings.wallet.step.base.title": "Base ウォレットを発行",
|
|
1462
|
-
"settings.wallet.step.base.copy": "
|
|
1471
|
+
"settings.wallet.step.base.copy": "本番 payout 向けの Base mainnet ウォレット発行は準備中です。まだ有効化されていません。",
|
|
1472
|
+
"settings.wallet.step.base.comingSoonDetail": "Coming soon",
|
|
1463
1473
|
"settings.wallet.mainnet.optIn": "Base mainnet も設定する",
|
|
1464
1474
|
"settings.wallet.mainnet.optInHint": "任意 — 本番 payout が必要な場合だけ。",
|
|
1465
1475
|
"settings.hazbase.title": "ウォレット",
|
|
@@ -1624,6 +1634,8 @@ const translations = {
|
|
|
1624
1634
|
"claudeAway.notifyOnly.notice": "同期モードは OFF です。PC で操作してください。{provider} は PC からの入力を待っています。",
|
|
1625
1635
|
"server.message.approvalAccepted": "承認しました。{provider} を続行します。",
|
|
1626
1636
|
"server.message.approvalRejected": "拒否しました。{provider} にこの操作を続けないよう伝えました。",
|
|
1637
|
+
"server.message.paymentSubmitted": "支払いを送信しました。決済完了を待っています。",
|
|
1638
|
+
"server.message.paymentFailed": "支払いに失敗しました: {reason}",
|
|
1627
1639
|
"server.message.planImplemented": "この plan から実装を開始するよう {provider} に伝えました。",
|
|
1628
1640
|
"server.message.planDismissed": "この Plan 確認を閉じ、再通知を抑止しました。",
|
|
1629
1641
|
"server.confirm.planImplement": "この plan から実装を開始します。",
|
|
@@ -1745,8 +1757,8 @@ const translations = {
|
|
|
1745
1757
|
"HTTP URL は、LAN 上の平文アクセスを明示的に許可した場合だけブラウザで開いてください。共有 Wi-Fi では非推奨です。",
|
|
1746
1758
|
"cli.setup.instructions.localOnlyHttp":
|
|
1747
1759
|
"この setup はローカル開発用の loopback-only HTTP です。別の端末から使うなら既定の HTTPS setup か --allow-insecure-http-lan を使ってください。",
|
|
1748
|
-
"logout.confirm.title": "
|
|
1749
|
-
"logout.confirm.copy": "session
|
|
1760
|
+
"logout.confirm.title": "viveworker からログアウトしますか?",
|
|
1761
|
+
"logout.confirm.copy": "現在の session を終了します。この端末の信頼は維持されるので、次回は再 pairing なしで戻れます。",
|
|
1750
1762
|
"logout.confirm.keepTrustedTitle": "ログアウトのみ",
|
|
1751
1763
|
"logout.confirm.keepTrustedCopy": "今の session だけ終了し、この端末の信頼は残します。",
|
|
1752
1764
|
"logout.confirm.removeTitle": "ログアウトしてこの端末を削除",
|