shepherd-onboard 0.1.13 → 0.1.15

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.
@@ -1333,18 +1333,18 @@ function renderMessagesSelectorPage(chats, token, error = "") {
1333
1333
  .join(" ")
1334
1334
  .toLowerCase();
1335
1335
 
1336
+ const kindKey = chat.kind === "group" ? "group" : chat.kind === "dm" ? "dm" : "other";
1337
+ const kindLabel = kindKey === "group" ? "Group" : kindKey === "dm" ? "Contact" : "Chat";
1336
1338
  return `
1337
1339
  <label class="chat-row" data-index="${index}" data-search="${htmlAttr(searchText)}">
1338
1340
  <input type="checkbox" name="chatId" value="${htmlAttr(chat.chatId)}">
1339
1341
  <span class="box" aria-hidden="true"></span>
1340
- <span class="chat-main">
1341
- <span class="chat-top">
1342
- <span class="chat-name">${html(chat.label)}</span>
1343
- <span class="chat-kind">${html(chat.kind === "group" ? "Group" : chat.kind === "dm" ? "Contact" : "Chat")}</span>
1344
- </span>
1342
+ <span class="chat-name-block">
1343
+ <span class="chat-name">${html(chat.label)}</span>
1345
1344
  ${people ? `<span class="chat-people">${html(people)}</span>` : ""}
1346
- ${when ? `<span class="chat-meta">${html(when)}</span>` : ""}
1347
1345
  </span>
1346
+ <span class="chat-kind chat-kind--${kindKey}">${html(kindLabel)}</span>
1347
+ <span class="chat-meta">${when ? html(when) : "—"}</span>
1348
1348
  </label>`;
1349
1349
  }).join("");
1350
1350
 
@@ -1356,125 +1356,134 @@ function renderMessagesSelectorPage(chats, token, error = "") {
1356
1356
  <title>Select Messages Chats</title>
1357
1357
  <style>
1358
1358
  :root {
1359
- color-scheme: light dark;
1360
- --bg: #FCFCFC;
1361
- --fg: #111111;
1362
- --muted: #6D726D;
1363
- --line: #E8ECE8;
1364
- --panel: #FFFFFF;
1365
- --button: #136033;
1366
- --button-text: #FFFFFF;
1367
- --link: #136033;
1368
- --radius: 10px;
1369
- }
1370
- @media (prefers-color-scheme: dark) {
1371
- :root {
1372
- --bg: #000000;
1373
- --fg: #F8F8F8;
1374
- --muted: #A2A8A2;
1375
- --line: #202520;
1376
- --panel: #070907;
1377
- --button: #FFFFFF;
1378
- --button-text: #000000;
1379
- --link: #136033;
1380
- }
1359
+ --bg: #fbfbfa;
1360
+ --panel: #ffffff;
1361
+ --fg: #141614;
1362
+ --muted: #767d78;
1363
+ --faint: #9aa09b;
1364
+ --line: #dedfdd;
1365
+ --green: #1f5c2e;
1366
+ --green-hover: #246836;
1367
+ --radius: 8px;
1368
+ --grid: 20px minmax(0, 1fr) 84px 112px;
1381
1369
  }
1382
1370
  * { box-sizing: border-box; }
1383
1371
  body {
1384
1372
  margin: 0;
1373
+ min-height: 100vh;
1385
1374
  background: var(--bg);
1386
1375
  color: var(--fg);
1387
1376
  font-family: Geist, "Geist Sans", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
1388
1377
  letter-spacing: 0;
1378
+ -webkit-font-smoothing: antialiased;
1389
1379
  }
1390
1380
  main {
1391
- width: min(700px, calc(100vw - 32px));
1392
- margin: 36px auto;
1381
+ width: min(720px, calc(100vw - 32px));
1382
+ margin: 0 auto;
1383
+ padding: 30px 0 28px;
1393
1384
  }
1394
- header {
1385
+ .header {
1395
1386
  display: flex;
1396
1387
  justify-content: space-between;
1397
- gap: 16px;
1398
1388
  align-items: center;
1399
- padding-bottom: 18px;
1400
- border-bottom: 1px solid var(--line);
1389
+ gap: 16px;
1390
+ padding: 0 0 18px;
1401
1391
  }
1402
1392
  .brand {
1403
1393
  display: flex;
1404
- gap: 10px;
1405
1394
  align-items: center;
1395
+ gap: 10px;
1406
1396
  min-width: 0;
1407
1397
  }
1408
1398
  .logo {
1409
- width: 30px;
1410
- height: 30px;
1411
- border-radius: 8px;
1399
+ width: 28px;
1400
+ height: 28px;
1412
1401
  object-fit: contain;
1413
1402
  flex: none;
1414
1403
  }
1415
1404
  .logo-fallback {
1416
- width: 30px;
1417
- height: 30px;
1418
- border-radius: 8px;
1405
+ width: 28px;
1406
+ height: 28px;
1407
+ border-radius: 6px;
1419
1408
  display: grid;
1420
1409
  place-items: center;
1421
1410
  color: #FFFFFF;
1422
- background: #136033;
1411
+ background: var(--green);
1412
+ font-size: 13px;
1423
1413
  font-weight: 700;
1424
1414
  flex: none;
1425
1415
  }
1426
1416
  h1 {
1427
1417
  margin: 0;
1428
- font-size: 22px;
1418
+ font-size: 19px;
1429
1419
  line-height: 1.1;
1430
- font-weight: 650;
1420
+ font-weight: 700;
1421
+ letter-spacing: 0;
1431
1422
  }
1432
- form {
1433
- margin-top: 18px;
1423
+ .subtitle {
1424
+ margin: 4px 0 0;
1425
+ font-size: 13px;
1426
+ line-height: 1.4;
1427
+ color: var(--muted);
1434
1428
  }
1435
- .search {
1436
- width: 100%;
1437
- margin: 0 0 12px;
1429
+ .panel {
1430
+ background: var(--panel);
1438
1431
  border: 1px solid var(--line);
1439
1432
  border-radius: var(--radius);
1440
- background: var(--panel);
1433
+ overflow: hidden;
1434
+ }
1435
+ .panel-head {
1436
+ padding: 12px;
1437
+ border-bottom: 1px solid var(--line);
1438
+ }
1439
+ .search {
1440
+ width: 100%;
1441
+ border: 1px solid #d7d9d6;
1442
+ border-radius: 6px;
1443
+ background: #ffffff;
1441
1444
  color: var(--fg);
1442
- padding: 11px 12px;
1445
+ padding: 9px 10px;
1443
1446
  font: inherit;
1444
- font-size: 14px;
1447
+ font-size: 13px;
1445
1448
  outline: none;
1446
1449
  }
1447
1450
  .search:focus {
1448
- border-color: #136033;
1449
- box-shadow: 0 0 0 3px color-mix(in srgb, #136033 16%, transparent);
1450
- }
1451
- .search::placeholder {
1452
- color: var(--muted);
1451
+ border-color: var(--green);
1452
+ outline: 2px solid color-mix(in srgb, var(--green) 22%, transparent);
1453
+ outline-offset: 1px;
1453
1454
  }
1455
+ .search::placeholder { color: var(--faint); }
1454
1456
  .error {
1455
- margin: 0 0 12px;
1457
+ margin: 10px 12px 0;
1456
1458
  color: #9B1C1C;
1457
- font-size: 14px;
1459
+ font-size: 13px;
1458
1460
  }
1459
- .chat-list {
1461
+ .list-head {
1460
1462
  display: grid;
1461
- gap: 8px;
1462
- margin: 0 0 18px;
1463
+ grid-template-columns: var(--grid);
1464
+ gap: 12px;
1465
+ align-items: center;
1466
+ padding: 9px 12px;
1467
+ border-bottom: 1px solid var(--line);
1468
+ color: var(--faint);
1469
+ font-size: 11px;
1470
+ font-weight: 600;
1471
+ text-transform: uppercase;
1463
1472
  }
1473
+ .list-head .right { text-align: left; }
1474
+ .chat-list { display: block; }
1464
1475
  .chat-row {
1465
1476
  display: grid;
1466
- grid-template-columns: 24px 1fr;
1477
+ grid-template-columns: var(--grid);
1467
1478
  gap: 12px;
1468
- align-items: start;
1469
- padding: 13px 14px;
1470
- background: var(--panel);
1471
- border: 1px solid var(--line);
1472
- border-radius: var(--radius);
1479
+ align-items: center;
1480
+ padding: 11px 12px;
1481
+ border-bottom: 1px solid var(--line);
1473
1482
  cursor: pointer;
1483
+ transition: background 120ms ease;
1474
1484
  }
1475
- .chat-row:hover {
1476
- border-color: color-mix(in srgb, var(--link) 45%, var(--line));
1477
- }
1485
+ .chat-row:last-child { border-bottom: 0; }
1486
+ .chat-row:hover { background: #f6f7f5; }
1478
1487
  input[type="checkbox"] {
1479
1488
  position: absolute;
1480
1489
  opacity: 0;
@@ -1483,61 +1492,63 @@ function renderMessagesSelectorPage(chats, token, error = "") {
1483
1492
  .box {
1484
1493
  width: 18px;
1485
1494
  height: 18px;
1486
- margin-top: 2px;
1487
- border: 1.5px solid var(--muted);
1488
- border-radius: 5px;
1495
+ border: 1.5px solid #C7CDC8;
1496
+ border-radius: 4px;
1489
1497
  display: inline-grid;
1490
1498
  place-items: center;
1499
+ transition: background 120ms ease, border-color 120ms ease;
1491
1500
  }
1501
+ .chat-row:hover .box { border-color: var(--green); }
1492
1502
  input[type="checkbox"]:checked + .box {
1493
- background: var(--button);
1494
- border-color: var(--button);
1503
+ background: var(--green);
1504
+ border-color: var(--green);
1495
1505
  }
1496
1506
  input[type="checkbox"]:checked + .box::after {
1497
1507
  content: "";
1498
1508
  width: 7px;
1499
1509
  height: 4px;
1500
- border-left: 2px solid var(--button-text);
1501
- border-bottom: 2px solid var(--button-text);
1510
+ border-left: 2px solid #FFFFFF;
1511
+ border-bottom: 2px solid #FFFFFF;
1502
1512
  transform: rotate(-45deg) translateY(-1px);
1503
1513
  }
1504
- .chat-main {
1514
+ .chat-name-block {
1505
1515
  min-width: 0;
1506
1516
  display: grid;
1507
- gap: 4px;
1508
- }
1509
- .chat-top {
1510
- display: flex;
1511
- gap: 10px;
1512
- align-items: center;
1513
- min-width: 0;
1517
+ gap: 2px;
1514
1518
  }
1515
1519
  .chat-name {
1516
1520
  overflow: hidden;
1517
1521
  text-overflow: ellipsis;
1518
1522
  white-space: nowrap;
1519
1523
  font-size: 15px;
1520
- font-weight: 600;
1524
+ font-weight: 550;
1525
+ }
1526
+ .chat-people {
1527
+ color: var(--muted);
1528
+ font-size: 12.5px;
1529
+ line-height: 1.3;
1530
+ overflow: hidden;
1531
+ text-overflow: ellipsis;
1532
+ white-space: nowrap;
1521
1533
  }
1522
1534
  .chat-kind {
1523
- color: var(--link);
1524
- font-size: 12px;
1525
- flex: none;
1535
+ justify-self: start;
1536
+ color: var(--muted);
1537
+ font-size: 12.5px;
1538
+ font-weight: 500;
1526
1539
  }
1527
- .chat-people,
1540
+ .chat-kind--group { color: var(--green); }
1528
1541
  .chat-meta {
1529
1542
  color: var(--muted);
1530
- font-size: 13px;
1531
- line-height: 1.35;
1543
+ font-size: 12.5px;
1532
1544
  overflow-wrap: anywhere;
1533
1545
  }
1534
- [hidden] {
1535
- display: none !important;
1536
- }
1546
+ [hidden] { display: none !important; }
1537
1547
  .empty {
1538
- margin: 18px 0 28px;
1548
+ margin: 0;
1549
+ padding: 26px 12px;
1539
1550
  color: var(--muted);
1540
- font-size: 14px;
1551
+ font-size: 13px;
1541
1552
  text-align: center;
1542
1553
  }
1543
1554
  .actions {
@@ -1547,44 +1558,67 @@ function renderMessagesSelectorPage(chats, token, error = "") {
1547
1558
  gap: 12px;
1548
1559
  position: sticky;
1549
1560
  bottom: 0;
1550
- padding: 14px 0 0;
1551
- background: linear-gradient(to top, var(--bg) 70%, transparent);
1561
+ margin-top: 12px;
1562
+ padding: 10px 0 0;
1563
+ background: var(--bg);
1552
1564
  }
1553
1565
  .selection-count {
1554
1566
  color: var(--muted);
1555
1567
  font-size: 13px;
1568
+ font-weight: 500;
1556
1569
  }
1557
1570
  button {
1558
1571
  appearance: none;
1559
1572
  border: 0;
1560
- border-radius: var(--radius);
1561
- background: var(--button);
1562
- color: var(--button-text);
1563
- padding: 10px 14px;
1573
+ border-radius: 6px;
1574
+ background: var(--green);
1575
+ color: #FFFFFF;
1576
+ padding: 9px 13px;
1564
1577
  font: inherit;
1565
- font-weight: 620;
1578
+ font-size: 13px;
1579
+ font-weight: 600;
1566
1580
  cursor: pointer;
1581
+ transition: background 120ms ease;
1582
+ }
1583
+ button:hover { background: var(--green-hover); }
1584
+ @media (max-width: 560px) {
1585
+ :root { --grid: 18px minmax(0, 1fr) auto; }
1586
+ .list-head span:last-child,
1587
+ .chat-meta { display: none; }
1567
1588
  }
1568
- a { color: var(--link); }
1569
1589
  </style>
1570
1590
  </head>
1571
1591
  <body>
1572
1592
  <main>
1573
- <header>
1593
+ <header class="header">
1574
1594
  <div class="brand">
1575
- ${logo ? `<img class="logo" src="${htmlAttr(logo)}" alt="">` : `<span class="logo-fallback" aria-hidden="true">G</span>`}
1576
- <h1>Select chats</h1>
1595
+ ${logo ? `<img class="logo" src="${htmlAttr(logo)}" alt="">` : `<span class="logo-fallback" aria-hidden="true">S</span>`}
1596
+ <div>
1597
+ <h1>Select chats</h1>
1598
+ <p class="subtitle">Choose the local Messages chats Shepherd should sync.</p>
1599
+ </div>
1577
1600
  </div>
1578
1601
  </header>
1579
1602
  <form method="post" action="/select">
1580
1603
  <input type="hidden" name="token" value="${htmlAttr(token)}">
1581
- <input class="search" id="search" type="search" placeholder="Search contacts or groups" autocomplete="off">
1582
- ${error ? `<p class="error">${html(error)}</p>` : ""}
1583
- <div class="chat-list">${rows}</div>
1584
- <p class="empty" id="empty" hidden>No chats found.</p>
1604
+ <div class="panel">
1605
+ <div class="panel-head">
1606
+ <input class="search" id="search" type="search" placeholder="Search contacts or groups" autocomplete="off">
1607
+ </div>
1608
+ ${error ? `<p class="error">${html(error)}</p>` : ""}
1609
+ <div class="list-head">
1610
+ <span></span>
1611
+ <span></span>
1612
+ <span>Name</span>
1613
+ <span>Type</span>
1614
+ <span class="right">Last message</span>
1615
+ </div>
1616
+ <div class="chat-list">${rows}</div>
1617
+ <p class="empty" id="empty" hidden>No chats found.</p>
1618
+ </div>
1585
1619
  <div class="actions">
1586
- <span class="selection-count" id="selection-count">Select one or more</span>
1587
- <button type="submit">return</button>
1620
+ <span class="selection-count" id="selection-count">0 selected</span>
1621
+ <button type="submit">Return</button>
1588
1622
  </div>
1589
1623
  </form>
1590
1624
  </main>
@@ -1611,7 +1645,7 @@ function renderMessagesSelectorPage(chats, token, error = "") {
1611
1645
 
1612
1646
  function updateSelected() {
1613
1647
  const count = checks.filter((check) => check.checked).length;
1614
- selected.textContent = count ? count + " selected" : "Select one or more";
1648
+ selected.textContent = count + " selected";
1615
1649
  }
1616
1650
 
1617
1651
  search.addEventListener("input", updateRows);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shepherd-onboard",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Customer-facing Shepherd raw sync onboarding CLI",
5
5
  "type": "module",
6
6
  "bin": {