clay-server 2.17.0-beta.5 → 2.17.0-beta.7

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/lib/pages.js CHANGED
@@ -48,56 +48,58 @@ function setupPageHtml(httpsUrl, httpUrl, hasCert, lanMode) {
48
48
  <link rel="apple-touch-icon" href="/apple-touch-icon.png">
49
49
  <title>Setup - Clay</title>
50
50
  <style>
51
+ :root{--s-bg:#282a36;--s-text:#f8f8f2;--s-accent:#ffb86c;--s-muted:#6272a4;--s-border:#44475a;--s-dimmer:#6272a4;--s-success:#50fa7b;--s-accent-15:rgba(255,184,108,0.15);--s-success-10:rgba(80,250,123,0.1);--s-success-15:rgba(80,250,123,0.15);--s-accent-06:rgba(255,184,108,0.06);--s-muted-06:rgba(98,114,164,0.06);--s-muted-15:rgba(98,114,164,0.15)}
52
+ @media(prefers-color-scheme:light){:root{--s-bg:#FAFAFA;--s-text:#5C6166;--s-accent:#FA8D3E;--s-muted:#A0A6AC;--s-border:#D2D4D8;--s-dimmer:#8A9199;--s-success:#6CBF49;--s-accent-15:rgba(250,141,62,0.15);--s-success-10:rgba(108,191,73,0.1);--s-success-15:rgba(108,191,73,0.15);--s-accent-06:rgba(250,141,62,0.06);--s-muted-06:rgba(160,166,172,0.06);--s-muted-15:rgba(160,166,172,0.15)}}
51
53
  *{margin:0;padding:0;box-sizing:border-box}
52
- body{background:#2F2E2B;color:#E8E5DE;font-family:system-ui,-apple-system,sans-serif;min-height:100dvh;display:flex;justify-content:center;padding:env(safe-area-inset-top,0) 20px 40px}
54
+ body{background:var(--s-bg);color:var(--s-text);font-family:system-ui,-apple-system,sans-serif;min-height:100dvh;display:flex;justify-content:center;padding:env(safe-area-inset-top,0) 20px 40px}
53
55
  .c{max-width:480px;width:100%;padding-top:40px}
54
- h1{color:#DA7756;font-size:22px;margin:0 0 4px;text-align:center}
55
- .subtitle{text-align:center;color:#908B81;font-size:13px;margin-bottom:28px}
56
+ h1{color:var(--s-accent);font-size:22px;margin:0 0 4px;text-align:center}
57
+ .subtitle{text-align:center;color:var(--s-muted);font-size:13px;margin-bottom:28px}
56
58
 
57
59
  /* Steps indicator */
58
60
  .steps-bar{display:flex;gap:6px;margin-bottom:32px}
59
- .steps-bar .pip{flex:1;height:3px;border-radius:2px;background:#3E3C37;transition:background 0.3s}
60
- .steps-bar .pip.done{background:#57AB5A}
61
- .steps-bar .pip.active{background:#DA7756}
61
+ .steps-bar .pip{flex:1;height:3px;border-radius:2px;background:var(--s-border);transition:background 0.3s}
62
+ .steps-bar .pip.done{background:var(--s-success)}
63
+ .steps-bar .pip.active{background:var(--s-accent)}
62
64
 
63
65
  /* Step card */
64
66
  .step-card{display:none;animation:fadeIn 0.25s ease}
65
67
  .step-card.active{display:block}
66
68
  @keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
67
69
 
68
- .step-label{font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#DA7756;font-weight:600;margin-bottom:8px}
70
+ .step-label{font-size:11px;text-transform:uppercase;letter-spacing:1px;color:var(--s-accent);font-weight:600;margin-bottom:8px}
69
71
  .step-title{font-size:18px;font-weight:600;margin-bottom:6px}
70
- .step-desc{font-size:14px;line-height:1.6;color:#908B81;margin-bottom:20px}
72
+ .step-desc{font-size:14px;line-height:1.6;color:var(--s-muted);margin-bottom:20px}
71
73
 
72
74
  .instruction{display:flex;gap:12px;margin-bottom:16px}
73
- .inst-num{width:24px;height:24px;border-radius:50%;background:rgba(218,119,86,0.15);color:#DA7756;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:12px;flex-shrink:0;margin-top:1px}
75
+ .inst-num{width:24px;height:24px;border-radius:50%;background:var(--s-accent-15);color:var(--s-accent);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:12px;flex-shrink:0;margin-top:1px}
74
76
  .inst-text{font-size:14px;line-height:1.6}
75
- .inst-text .note{font-size:12px;color:#6D6860;margin-top:4px}
77
+ .inst-text .note{font-size:12px;color:var(--s-dimmer);margin-top:4px}
76
78
 
77
- .btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;background:#DA7756;color:#fff;text-decoration:none;padding:12px 24px;border-radius:12px;font-weight:600;font-size:14px;margin:4px 0;border:none;cursor:pointer;font-family:inherit;transition:opacity 0.15s}
79
+ .btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;background:var(--s-accent);color:#fff;text-decoration:none;padding:12px 24px;border-radius:12px;font-weight:600;font-size:14px;margin:4px 0;border:none;cursor:pointer;font-family:inherit;transition:opacity 0.15s}
78
80
  .btn:hover{opacity:0.9}
79
- .btn.outline{background:transparent;border:1.5px solid #3E3C37;color:#E8E5DE}
80
- .btn.outline:hover{border-color:#6D6860}
81
- .btn.success{background:#57AB5A}
81
+ .btn.outline{background:transparent;border:1.5px solid var(--s-border);color:var(--s-text)}
82
+ .btn.outline:hover{border-color:var(--s-dimmer)}
83
+ .btn.success{background:var(--s-success)}
82
84
  .btn:disabled{opacity:0.4;cursor:default}
83
85
 
84
86
  .btn-row{display:flex;gap:8px;margin-top:20px}
85
87
  .btn-row .btn{flex:1}
86
88
 
87
89
  .check-status{display:flex;align-items:center;gap:8px;padding:12px 16px;border-radius:10px;font-size:13px;margin:16px 0}
88
- .check-status.ok{background:rgba(87,171,90,0.1);color:#57AB5A;border:1px solid rgba(87,171,90,0.15)}
89
- .check-status.warn{background:rgba(218,119,86,0.06);border:1px solid rgba(218,119,86,0.15);color:#DA7756}
90
- .check-status.pending{background:rgba(144,139,129,0.06);border:1px solid rgba(144,139,129,0.15);color:#908B81}
90
+ .check-status.ok{background:var(--s-success-10);color:var(--s-success);border:1px solid var(--s-success-15)}
91
+ .check-status.warn{background:var(--s-accent-06);border:1px solid var(--s-accent-15);color:var(--s-accent)}
92
+ .check-status.pending{background:var(--s-muted-06);border:1px solid var(--s-muted-15);color:var(--s-muted)}
91
93
 
92
94
  .platform-ios,.platform-android,.platform-desktop{display:none}
93
95
 
94
96
  .done-card{text-align:center;padding:40px 0}
95
97
  .done-icon{font-size:48px;margin-bottom:16px}
96
98
  .done-title{font-size:20px;font-weight:600;margin-bottom:8px}
97
- .done-desc{font-size:14px;color:#908B81;margin-bottom:24px}
99
+ .done-desc{font-size:14px;color:var(--s-muted);margin-bottom:24px}
98
100
 
99
- .skip-link{display:block;text-align:center;color:#6D6860;font-size:13px;text-decoration:none;margin-top:12px;cursor:pointer;border:none;background:none;font-family:inherit}
100
- .skip-link:hover{color:#908B81}
101
+ .skip-link{display:block;text-align:center;color:var(--s-dimmer);font-size:13px;text-decoration:none;margin-top:12px;cursor:pointer;border:none;background:none;font-family:inherit}
102
+ .skip-link:hover{color:var(--s-muted)}
101
103
  </style></head><body>
102
104
  <div class="c">
103
105
  <h1>Clay</h1>
package/lib/project.js CHANGED
@@ -1646,11 +1646,11 @@ function createProjectContext(opts) {
1646
1646
  var switchTarget = sm.sessions.get(msg.id);
1647
1647
  if (!usersModule.canAccessSession(ws._clayUser.id, switchTarget, { visibility: "public" })) return;
1648
1648
  ws._clayActiveSession = msg.id;
1649
- sm.switchSession(msg.id, ws);
1649
+ sm.switchSession(msg.id, ws, hydrateImageRefs);
1650
1650
  broadcastPresence();
1651
1651
  } else {
1652
1652
  ws._clayActiveSession = msg.id;
1653
- sm.switchSession(msg.id, ws);
1653
+ sm.switchSession(msg.id, ws, hydrateImageRefs);
1654
1654
  }
1655
1655
  }
1656
1656
  return;
@@ -2005,7 +2005,7 @@ function createProjectContext(opts) {
2005
2005
  onProcessingChanged();
2006
2006
 
2007
2007
  sm.saveSessionFile(session);
2008
- sm.switchSession(session.localId, ws);
2008
+ sm.switchSession(session.localId, ws, hydrateImageRefs);
2009
2009
  sm.sendAndRecord(session, { type: "rewind_complete", mode: mode });
2010
2010
  sm.broadcastSessionList();
2011
2011
  } catch (err) {
@@ -3162,7 +3162,7 @@ function createProjectContext(opts) {
3162
3162
  judgeCraftSession.ralphCraftingMode = true;
3163
3163
  judgeCraftSession.loop = { active: true, iteration: 0, role: "crafting", loopId: newLoopId, name: craftName, source: recordSource, startedAt: loopState.startedAt };
3164
3164
  sm.saveSessionFile(judgeCraftSession);
3165
- sm.switchSession(judgeCraftSession.localId);
3165
+ sm.switchSession(judgeCraftSession.localId, null, hydrateImageRefs);
3166
3166
  loopState.craftingSessionId = judgeCraftSession.localId;
3167
3167
 
3168
3168
  loopRegistry.updateRecord(newLoopId, { craftingSessionId: judgeCraftSession.localId });
@@ -3206,7 +3206,7 @@ function createProjectContext(opts) {
3206
3206
  craftingSession.ralphCraftingMode = true;
3207
3207
  craftingSession.loop = { active: true, iteration: 0, role: "crafting", loopId: newLoopId, name: craftName, source: recordSource, startedAt: loopState.startedAt };
3208
3208
  sm.saveSessionFile(craftingSession);
3209
- sm.switchSession(craftingSession.localId);
3209
+ sm.switchSession(craftingSession.localId, null, hydrateImageRefs);
3210
3210
  loopState.craftingSessionId = craftingSession.localId;
3211
3211
 
3212
3212
  // Store crafting session ID in the registry record
@@ -320,7 +320,7 @@
320
320
  right: 0;
321
321
  transform: none;
322
322
  width: 100%;
323
- max-height: 85vh;
323
+ max-height: 85dvh;
324
324
  border-radius: 16px 16px 0 0;
325
325
  border: none;
326
326
  border-top: 1px solid var(--border-subtle);
@@ -1329,6 +1329,22 @@ function renderSheetSettings(listEl) {
1329
1329
  });
1330
1330
 
1331
1331
  listEl.appendChild(themeBtn);
1332
+
1333
+ // "Open as app" — only show if not already in PWA standalone mode
1334
+ if (!document.documentElement.classList.contains("pwa-standalone")) {
1335
+ var pwaBtn = document.createElement("button");
1336
+ pwaBtn.className = "mobile-more-item";
1337
+ pwaBtn.innerHTML = '<i data-lucide="smartphone"></i><span class="mobile-more-item-label">Open as app</span>';
1338
+ pwaBtn.addEventListener("click", function () {
1339
+ closeMobileSheet();
1340
+ // Trigger the existing PWA install modal
1341
+ var installPill = document.getElementById("pwa-install-pill");
1342
+ if (installPill) {
1343
+ setTimeout(function () { installPill.click(); }, 250);
1344
+ }
1345
+ });
1346
+ listEl.appendChild(pwaBtn);
1347
+ }
1332
1348
  }
1333
1349
 
1334
1350
  export function initSidebar(_ctx) {
package/lib/sessions.js CHANGED
@@ -315,7 +315,7 @@ function createSessionManager(opts) {
315
315
  return 0;
316
316
  }
317
317
 
318
- function replayHistory(session, fromIndex, targetWs) {
318
+ function replayHistory(session, fromIndex, targetWs, transform) {
319
319
  var _send = (targetWs && sendTo) ? function (obj) { sendTo(targetWs, obj); } : send;
320
320
  var total = session.history.length;
321
321
  if (typeof fromIndex !== "number") {
@@ -329,7 +329,7 @@ function createSessionManager(opts) {
329
329
  _send({ type: "history_meta", total: total, from: fromIndex });
330
330
 
331
331
  for (var i = fromIndex; i < total; i++) {
332
- _send(session.history[i]);
332
+ _send(transform ? transform(session.history[i]) : session.history[i]);
333
333
  }
334
334
 
335
335
  // Find the last result message in the full history for accurate context data
@@ -351,7 +351,7 @@ function createSessionManager(opts) {
351
351
  _send({ type: "history_done", lastUsage: lastUsage, lastModelUsage: lastModelUsage, lastCost: lastCost, lastStreamInputTokens: lastStreamInputTokens });
352
352
  }
353
353
 
354
- function switchSession(localId, targetWs) {
354
+ function switchSession(localId, targetWs, transform) {
355
355
  var session = sessions.get(localId);
356
356
  if (!session) return;
357
357
 
@@ -374,7 +374,7 @@ function createSessionManager(opts) {
374
374
 
375
375
  _send({ type: "session_switched", id: localId, cliSessionId: session.cliSessionId || null, loop: session.loop || null });
376
376
  broadcastSessionList();
377
- replayHistory(session, undefined, targetWs);
377
+ replayHistory(session, undefined, targetWs, transform);
378
378
 
379
379
  if (session.isProcessing) {
380
380
  _send({ type: "status", status: "processing" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clay-server",
3
- "version": "2.17.0-beta.5",
3
+ "version": "2.17.0-beta.7",
4
4
  "description": "Web UI for Claude Code. Any device. Push notifications.",
5
5
  "bin": {
6
6
  "clay-server": "./bin/cli.js",
@@ -1,10 +0,0 @@
1
- {
2
- "name": "Clay Light",
3
- "author": "Clay",
4
- "variant": "light",
5
- "base00": "F3EBE7", "base01": "EBE1DC", "base02": "D8CCC6", "base03": "A09590",
6
- "base04": "786D67", "base05": "504541", "base06": "332925", "base07": "1A1412",
7
- "base08": "C83520", "base09": "F74728", "base0A": "C08520", "base0B": "008F6B",
8
- "base0C": "1C8575", "base0D": "3560B0", "base0E": "8C4E8E", "base0F": "A57C45",
9
- "accent2": "2A26E5"
10
- }
@@ -1,10 +0,0 @@
1
- {
2
- "name": "Clay Dark",
3
- "author": "Clay",
4
- "variant": "dark",
5
- "base00": "1F1B1B", "base01": "2A2525", "base02": "352F2F", "base03": "7D7370",
6
- "base04": "A09590", "base05": "C2BAB4", "base06": "E5DED8", "base07": "FFFFFF",
7
- "base08": "F74728", "base09": "FE7150", "base0A": "E5A040", "base0B": "09E5A3",
8
- "base0C": "4EC9B0", "base0D": "6BA0E5", "base0E": "D085CC", "base0F": "D09558",
9
- "accent2": "5857FC"
10
- }