replicas-computer 0.2.10 → 0.2.12

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/README.md CHANGED
@@ -8,7 +8,7 @@ The versioned computer-use runtime for Replicas workspace images.
8
8
  - `src/stream-viewer.ts` owns browser decoding, audio playback, reconnects, and interactive input.
9
9
  - `src/viewer.ts` owns the optional noVNC fallback.
10
10
  - `assets/desktop/start-services.sh` owns the X11 and stream process lifecycle.
11
- - `assets/desktop/` owns the desktop theme: `brand-wallpaper.svg` (regenerate with `bun scripts/render-wallpaper.ts`), `tint2rc` dock, `openbox-theme/`, `gtk-settings.ini`, the `replicas-terminal` wrapper, and the bundled fonts (static TTF instances of General Sans and Geist Mono; variable and WOFF2 builds render with wrong metrics in Pango and VTE).
11
+ - `assets/desktop/` owns the desktop theme: `brand-wallpaper.svg` (regenerate with `bun scripts/render-wallpaper.ts`), `tint2rc` dock, `openbox-theme/`, `gtk-settings.ini`, the `replicas-terminal` wrapper, `themes/` palettes that `start-services.sh` renders into those templates (`--theme light|dark` switches a running desktop), and the bundled fonts (static TTF instances of General Sans and Geist Mono; variable and WOFF2 builds render with wrong metrics in Pango and VTE).
12
12
 
13
13
  The viewer and agent command paths are independent. One on-demand encoder is shared by all viewers, stops when the last viewer disconnects, and restarts without reloading the page. The default 1920×1080 stream uses low-latency H.264 and Opus; noVNC remains available as an opt-in fallback.
14
14
 
@@ -0,0 +1,14 @@
1
+ <svg width="1920" height="1080" viewBox="0 0 1920 1080" xmlns="http://www.w3.org/2000/svg">
2
+ <defs>
3
+ <linearGradient id="cell" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#2fc487" stop-opacity="0.3"/><stop offset="1" stop-color="#2fc487" stop-opacity="0.14"/></linearGradient>
4
+ <pattern id="grid" width="64" height="64" y="28" patternUnits="userSpaceOnUse"><path d="M0.5 0V64M0 0.5H64" stroke="#162118" stroke-opacity="0.1"/></pattern>
5
+ <filter id="cell-glow" x="-25%" y="-25%" width="150%" height="150%"><feDropShadow dx="0" dy="0" stdDeviation="10" flood-color="#2fc487" flood-opacity="0.18"/></filter>
6
+ </defs>
7
+ <rect width="1920" height="1080" fill="#f4f5f1"/>
8
+ <rect width="1920" height="1080" fill="url(#grid)"/>
9
+ <g fill="url(#cell)" stroke="#2fc487" filter="url(#cell-glow)"><rect x="768.5" y="220.5" width="64" height="64"/><rect x="768.5" y="284.5" width="64" height="64"/><rect x="832.5" y="220.5" width="64" height="64"/><rect x="832.5" y="284.5" width="64" height="64"/><rect x="896.5" y="220.5" width="64" height="64"/><rect x="896.5" y="284.5" width="64" height="64"/><rect x="960.5" y="220.5" width="64" height="64"/><rect x="960.5" y="284.5" width="64" height="64"/><rect x="1024.5" y="348.5" width="64" height="64"/><rect x="1024.5" y="412.5" width="64" height="64"/><rect x="1088.5" y="348.5" width="64" height="64"/><rect x="1088.5" y="412.5" width="64" height="64"/><rect x="768.5" y="476.5" width="64" height="64"/><rect x="768.5" y="540.5" width="64" height="64"/><rect x="832.5" y="476.5" width="64" height="64"/><rect x="832.5" y="540.5" width="64" height="64"/><rect x="896.5" y="476.5" width="64" height="64"/><rect x="896.5" y="540.5" width="64" height="64"/><rect x="960.5" y="476.5" width="64" height="64"/><rect x="960.5" y="540.5" width="64" height="64"/><rect x="768.5" y="604.5" width="64" height="64"/><rect x="768.5" y="668.5" width="64" height="64"/><rect x="832.5" y="604.5" width="64" height="64"/><rect x="832.5" y="668.5" width="64" height="64"/><rect x="1024.5" y="604.5" width="64" height="64"/><rect x="1024.5" y="668.5" width="64" height="64"/><rect x="1088.5" y="604.5" width="64" height="64"/><rect x="1088.5" y="668.5" width="64" height="64"/><rect x="320.5" y="156.5" width="64" height="64"/><rect x="384.5" y="220.5" width="64" height="64"/><rect x="256.5" y="284.5" width="64" height="64"/><rect x="320.5" y="284.5" width="64" height="64"/><rect x="384.5" y="284.5" width="64" height="64"/><rect x="1536.5" y="220.5" width="64" height="64"/><rect x="1472.5" y="284.5" width="64" height="64"/><rect x="1600.5" y="348.5" width="64" height="64"/><rect x="1536.5" y="348.5" width="64" height="64"/><rect x="1472.5" y="348.5" width="64" height="64"/><rect x="448.5" y="860.5" width="64" height="64"/><rect x="512.5" y="796.5" width="64" height="64"/><rect x="384.5" y="732.5" width="64" height="64"/><rect x="448.5" y="732.5" width="64" height="64"/><rect x="512.5" y="732.5" width="64" height="64"/><rect x="1344.5" y="796.5" width="64" height="64"/><rect x="1408.5" y="796.5" width="64" height="64"/><rect x="1472.5" y="796.5" width="64" height="64"/><rect x="1664.5" y="540.5" width="64" height="64"/><rect x="1728.5" y="540.5" width="64" height="64"/><rect x="1664.5" y="604.5" width="64" height="64"/><rect x="1728.5" y="604.5" width="64" height="64"/></g>
10
+ <g font-family="Geist Mono, monospace" font-size="5" font-weight="600" fill="#2f9d57"><text x="774" y="233">AGENT-73</text><text x="774" y="276">CODING</text><text x="774" y="297">AGENT-45</text><text x="774" y="340">DEPLOYING</text><text x="838" y="233">AGENT-10</text><text x="838" y="276">LINTING</text><text x="838" y="297">AGENT-82</text><text x="838" y="340">MERGING</text><text x="902" y="233">AGENT-47</text><text x="902" y="276">REFACTORING</text><text x="902" y="297">AGENT-19</text><text x="902" y="340">CODING</text><text x="966" y="233">AGENT-84</text><text x="966" y="276">RUNNING TESTS</text><text x="966" y="297">AGENT-56</text><text x="966" y="340">LINTING</text><text x="1030" y="361">AGENT-65</text><text x="1030" y="404">CODING</text><text x="1030" y="425">AGENT-37</text><text x="1030" y="468">DEPLOYING</text><text x="1094" y="361">AGENT-02</text><text x="1094" y="404">LINTING</text><text x="1094" y="425">AGENT-74</text><text x="1094" y="468">MERGING</text><text x="774" y="489">AGENT-61</text><text x="774" y="532">DEPLOYING</text><text x="774" y="553">AGENT-33</text><text x="774" y="596">REFACTORING</text><text x="838" y="489">AGENT-98</text><text x="838" y="532">MERGING</text><text x="838" y="553">AGENT-70</text><text x="838" y="596">RUNNING TESTS</text><text x="902" y="489">AGENT-35</text><text x="902" y="532">CODING</text><text x="902" y="553">AGENT-07</text><text x="902" y="596">DEPLOYING</text><text x="966" y="489">AGENT-72</text><text x="966" y="532">LINTING</text><text x="966" y="553">AGENT-44</text><text x="966" y="596">MERGING</text><text x="774" y="617">AGENT-05</text><text x="774" y="660">CODING</text><text x="774" y="681">AGENT-77</text><text x="774" y="724">DEPLOYING</text><text x="838" y="617">AGENT-42</text><text x="838" y="660">LINTING</text><text x="838" y="681">AGENT-14</text><text x="838" y="724">MERGING</text><text x="1030" y="617">AGENT-53</text><text x="1030" y="660">DEPLOYING</text><text x="1030" y="681">AGENT-25</text><text x="1030" y="724">REFACTORING</text><text x="1094" y="617">AGENT-90</text><text x="1094" y="660">MERGING</text><text x="1094" y="681">AGENT-62</text><text x="1094" y="724">RUNNING TESTS</text><text x="326" y="169">AGENT-42</text><text x="326" y="212">LINTING</text><text x="390" y="233">AGENT-51</text><text x="390" y="276">CODING</text><text x="262" y="297">AGENT-49</text><text x="262" y="340">REFACTORING</text><text x="326" y="297">AGENT-86</text><text x="326" y="340">RUNNING TESTS</text><text x="390" y="297">AGENT-23</text><text x="390" y="340">DEPLOYING</text><text x="1542" y="233">AGENT-17</text><text x="1542" y="276">CODING</text><text x="1478" y="297">AGENT-52</text><text x="1478" y="340">RUNNING TESTS</text><text x="1606" y="361">AGENT-98</text><text x="1606" y="404">RUNNING TESTS</text><text x="1542" y="361">AGENT-61</text><text x="1542" y="404">REFACTORING</text><text x="1478" y="361">AGENT-24</text><text x="1478" y="404">LINTING</text><text x="454" y="873">AGENT-08</text><text x="454" y="916">MERGING</text><text x="518" y="809">AGENT-73</text><text x="518" y="852">REFACTORING</text><text x="390" y="745">AGENT-27</text><text x="390" y="788">REFACTORING</text><text x="454" y="745">AGENT-64</text><text x="454" y="788">RUNNING TESTS</text><text x="518" y="745">AGENT-01</text><text x="518" y="788">DEPLOYING</text><text x="1350" y="809">AGENT-54</text><text x="1350" y="852">RUNNING TESTS</text><text x="1414" y="809">AGENT-91</text><text x="1414" y="852">DEPLOYING</text><text x="1478" y="809">AGENT-28</text><text x="1478" y="852">MERGING</text><text x="1670" y="553">AGENT-51</text><text x="1670" y="596">DEPLOYING</text><text x="1734" y="553">AGENT-88</text><text x="1734" y="596">MERGING</text><text x="1670" y="617">AGENT-23</text><text x="1670" y="660">REFACTORING</text><text x="1734" y="617">AGENT-60</text><text x="1734" y="660">RUNNING TESTS</text></g>
11
+ <path transform="translate(893.05 842)" fill="#162118" fill-opacity="0.9" d="M5.3 0H3.3V-28.7H13.2Q17.5 -28.7 20 -26.5Q22.6 -24.3 22.6 -20.2Q22.6 -16.9 20.5 -14.6Q18.4 -12.4 14.9 -12L23.3 0H20.9L12.8 -11.8H5.3ZM5.3 -27.1V-13.4H13Q16.5 -13.4 18.5 -15.2Q20.6 -17 20.6 -20.2Q20.6 -23.5 18.5 -25.3Q16.5 -27.1 13 -27.1Z M33.8 0.4Q31 0.4 28.8 -0.9Q26.6 -2.3 25.4 -4.9Q24.2 -7.4 24.2 -10.7Q24.2 -13.7 25.5 -16.2Q26.7 -18.6 28.8 -20Q30.9 -21.4 33.6 -21.4Q35.8 -21.4 37.5 -20.6Q39.2 -19.7 40.5 -18.2Q41.7 -16.7 42.3 -14.7Q42.9 -12.6 42.8 -10.1H25.2V-11.5H40.9Q40.7 -15.4 38.8 -17.7Q36.8 -19.9 33.6 -19.9Q31.4 -19.9 29.7 -18.7Q28 -17.6 27 -15.5Q26.1 -13.5 26.1 -10.7Q26.1 -7.8 27 -5.6Q27.9 -3.4 29.7 -2.3Q31.4 -1.1 33.8 -1.1Q36.7 -1.1 38.6 -2.7Q40.6 -4.3 41.1 -7.1H42.9Q42.3 -3.6 39.8 -1.6Q37.4 0.4 33.8 0.4Z M64.2 -10.5Q64.2 -7.2 63.1 -4.8Q61.9 -2.3 59.9 -1Q57.8 0.4 55 0.4Q52.5 0.4 50.5 -1Q48.5 -2.4 47.4 -4.8V7.7H45.5V-21H47.3V-15.9Q48.3 -18.5 50.4 -19.9Q52.5 -21.4 55 -21.4Q57.8 -21.4 59.9 -20Q61.9 -18.7 63.1 -16.2Q64.2 -13.8 64.2 -10.5ZM62.3 -10.5Q62.3 -14.8 60.3 -17.3Q58.3 -19.8 54.8 -19.8Q52.7 -19.8 51 -18.7Q49.3 -17.6 48.3 -15.5Q47.3 -13.5 47.3 -10.5Q47.3 -7.7 48.3 -5.6Q49.2 -3.5 50.9 -2.3Q52.6 -1.2 54.8 -1.2Q58.3 -1.2 60.3 -3.6Q62.3 -6.1 62.3 -10.5Z M68.7 0H66.8V-28.7H68.7Z M74.8 0H72.9V-21H74.8ZM75.6 -25.8Q75.6 -25.1 75.2 -24.6Q74.7 -24.1 73.9 -24.1Q73.1 -24.1 72.6 -24.6Q72.1 -25.1 72.1 -25.8Q72.1 -26.6 72.6 -27Q73.1 -27.5 73.9 -27.5Q74.7 -27.5 75.2 -27Q75.6 -26.6 75.6 -25.8Z M86.5 0.4Q83.8 0.4 81.8 -0.9Q79.7 -2.3 78.6 -4.8Q77.4 -7.3 77.4 -10.5Q77.4 -13.7 78.6 -16.2Q79.7 -18.6 81.8 -20Q83.9 -21.4 86.5 -21.4Q88.9 -21.4 90.7 -20.4Q92.6 -19.4 93.8 -17.6Q95 -15.7 95.5 -13.2H93.6Q93 -16.3 91.2 -18.1Q89.3 -19.8 86.5 -19.8Q84.4 -19.8 82.8 -18.6Q81.1 -17.4 80.2 -15.4Q79.3 -13.3 79.3 -10.5Q79.3 -7.7 80.2 -5.6Q81.1 -3.5 82.8 -2.3Q84.4 -1.1 86.5 -1.1Q89.3 -1.1 91.2 -2.9Q93.1 -4.7 93.6 -7.8H95.5Q95.1 -5.2 93.8 -3.4Q92.6 -1.6 90.8 -0.6Q88.9 0.4 86.5 0.4Z M111.1 0V-4.2Q110.3 -2.1 108.3 -0.9Q106.4 0.4 103.9 0.4Q100.6 0.4 98.7 -1.3Q96.7 -2.9 96.7 -5.7Q96.7 -8.8 99.2 -10.4Q101.6 -11.9 106.4 -11.9Q107.4 -11.9 108.3 -11.9Q109.3 -11.8 111 -11.7V-13.6Q111 -16.6 109.5 -18.2Q108.1 -19.9 105.4 -19.9Q102.6 -19.9 100.9 -18.2Q99.3 -16.5 99.2 -13.7H97.5Q97.5 -16 98.5 -17.7Q99.5 -19.4 101.3 -20.4Q103.1 -21.4 105.4 -21.4Q108.9 -21.4 110.9 -19.4Q112.8 -17.4 112.8 -13.8V0ZM98.6 -5.8Q98.6 -3.7 100.1 -2.4Q101.6 -1 104 -1Q107.2 -1 109.1 -3.1Q111 -5.1 111 -8.4V-10.4Q109.5 -10.5 108.5 -10.5Q107.4 -10.6 106.5 -10.6Q102.5 -10.6 100.5 -9.4Q98.6 -8.2 98.6 -5.8Z M131.9 -5.5Q131.9 -2.8 129.8 -1.2Q127.7 0.4 123.9 0.4Q120.3 0.4 118 -1.4Q115.8 -3.2 115.5 -6.4H117.3Q117.4 -3.9 119.2 -2.5Q121 -1.1 124 -1.1Q126.9 -1.1 128.5 -2.2Q130 -3.3 130 -5.3Q130 -7.1 128.9 -8Q127.8 -8.9 125.2 -9.4L122.4 -10Q119.3 -10.6 117.8 -12Q116.3 -13.4 116.3 -15.6Q116.3 -17.3 117.2 -18.6Q118.2 -19.9 119.8 -20.6Q121.5 -21.4 123.7 -21.4Q126 -21.4 127.7 -20.6Q129.5 -19.8 130.5 -18.3Q131.5 -16.8 131.7 -14.8H129.9Q129.7 -17.2 128 -18.6Q126.4 -19.9 123.7 -19.9Q121.2 -19.9 119.6 -18.8Q118.1 -17.7 118.1 -15.8Q118.1 -14 119.2 -13.1Q120.4 -12.1 123 -11.6L125.9 -11Q129 -10.4 130.5 -9.1Q131.9 -7.8 131.9 -5.5Z"/>
12
+ <g font-family="Geist Mono, monospace" font-size="14" fill="#162118" fill-opacity="0.4" text-anchor="middle"><text x="14" y="22">+</text><text x="1906" y="22">+</text><text x="14" y="1070">+</text><text x="1906" y="1070">+</text></g>
13
+ <text x="34" y="22" font-family="Geist Mono, monospace" font-size="10" letter-spacing="1.4" fill="#162118" fill-opacity="0.45">REPLICAS / DESKTOP</text>
14
+ </svg>
@@ -1,12 +1,10 @@
1
1
  <svg width="1920" height="1080" viewBox="0 0 1920 1080" xmlns="http://www.w3.org/2000/svg">
2
2
  <defs>
3
3
  <linearGradient id="cell" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#082b24" stop-opacity="0.95"/><stop offset="1" stop-color="#005b45" stop-opacity="0.82"/></linearGradient>
4
- <radialGradient id="glow" gradientUnits="userSpaceOnUse" cx="960" cy="476" r="620"><stop stop-color="#3eeba3" stop-opacity="0.07"/><stop offset="1" stop-color="#3eeba3" stop-opacity="0"/></radialGradient>
5
4
  <pattern id="grid" width="64" height="64" y="28" patternUnits="userSpaceOnUse"><path d="M0.5 0V64M0 0.5H64" stroke="#ffffff" stroke-opacity="0.12"/></pattern>
6
5
  <filter id="cell-glow" x="-25%" y="-25%" width="150%" height="150%"><feDropShadow dx="0" dy="0" stdDeviation="10" flood-color="#3eeba3" flood-opacity="0.16"/></filter>
7
6
  </defs>
8
7
  <rect width="1920" height="1080" fill="#121212"/>
9
- <rect width="1920" height="1080" fill="url(#glow)"/>
10
8
  <rect width="1920" height="1080" fill="url(#grid)"/>
11
9
  <g fill="url(#cell)" stroke="#3eeba3" filter="url(#cell-glow)"><rect x="768.5" y="220.5" width="64" height="64"/><rect x="768.5" y="284.5" width="64" height="64"/><rect x="832.5" y="220.5" width="64" height="64"/><rect x="832.5" y="284.5" width="64" height="64"/><rect x="896.5" y="220.5" width="64" height="64"/><rect x="896.5" y="284.5" width="64" height="64"/><rect x="960.5" y="220.5" width="64" height="64"/><rect x="960.5" y="284.5" width="64" height="64"/><rect x="1024.5" y="348.5" width="64" height="64"/><rect x="1024.5" y="412.5" width="64" height="64"/><rect x="1088.5" y="348.5" width="64" height="64"/><rect x="1088.5" y="412.5" width="64" height="64"/><rect x="768.5" y="476.5" width="64" height="64"/><rect x="768.5" y="540.5" width="64" height="64"/><rect x="832.5" y="476.5" width="64" height="64"/><rect x="832.5" y="540.5" width="64" height="64"/><rect x="896.5" y="476.5" width="64" height="64"/><rect x="896.5" y="540.5" width="64" height="64"/><rect x="960.5" y="476.5" width="64" height="64"/><rect x="960.5" y="540.5" width="64" height="64"/><rect x="768.5" y="604.5" width="64" height="64"/><rect x="768.5" y="668.5" width="64" height="64"/><rect x="832.5" y="604.5" width="64" height="64"/><rect x="832.5" y="668.5" width="64" height="64"/><rect x="1024.5" y="604.5" width="64" height="64"/><rect x="1024.5" y="668.5" width="64" height="64"/><rect x="1088.5" y="604.5" width="64" height="64"/><rect x="1088.5" y="668.5" width="64" height="64"/><rect x="320.5" y="156.5" width="64" height="64"/><rect x="384.5" y="220.5" width="64" height="64"/><rect x="256.5" y="284.5" width="64" height="64"/><rect x="320.5" y="284.5" width="64" height="64"/><rect x="384.5" y="284.5" width="64" height="64"/><rect x="1536.5" y="220.5" width="64" height="64"/><rect x="1472.5" y="284.5" width="64" height="64"/><rect x="1600.5" y="348.5" width="64" height="64"/><rect x="1536.5" y="348.5" width="64" height="64"/><rect x="1472.5" y="348.5" width="64" height="64"/><rect x="448.5" y="860.5" width="64" height="64"/><rect x="512.5" y="796.5" width="64" height="64"/><rect x="384.5" y="732.5" width="64" height="64"/><rect x="448.5" y="732.5" width="64" height="64"/><rect x="512.5" y="732.5" width="64" height="64"/><rect x="1344.5" y="796.5" width="64" height="64"/><rect x="1408.5" y="796.5" width="64" height="64"/><rect x="1472.5" y="796.5" width="64" height="64"/><rect x="1664.5" y="540.5" width="64" height="64"/><rect x="1728.5" y="540.5" width="64" height="64"/><rect x="1664.5" y="604.5" width="64" height="64"/><rect x="1728.5" y="604.5" width="64" height="64"/></g>
12
10
  <g font-family="Geist Mono, monospace" font-size="5" font-weight="600" fill="#3eeba3"><text x="774" y="233">AGENT-73</text><text x="774" y="276">CODING</text><text x="774" y="297">AGENT-45</text><text x="774" y="340">DEPLOYING</text><text x="838" y="233">AGENT-10</text><text x="838" y="276">LINTING</text><text x="838" y="297">AGENT-82</text><text x="838" y="340">MERGING</text><text x="902" y="233">AGENT-47</text><text x="902" y="276">REFACTORING</text><text x="902" y="297">AGENT-19</text><text x="902" y="340">CODING</text><text x="966" y="233">AGENT-84</text><text x="966" y="276">RUNNING TESTS</text><text x="966" y="297">AGENT-56</text><text x="966" y="340">LINTING</text><text x="1030" y="361">AGENT-65</text><text x="1030" y="404">CODING</text><text x="1030" y="425">AGENT-37</text><text x="1030" y="468">DEPLOYING</text><text x="1094" y="361">AGENT-02</text><text x="1094" y="404">LINTING</text><text x="1094" y="425">AGENT-74</text><text x="1094" y="468">MERGING</text><text x="774" y="489">AGENT-61</text><text x="774" y="532">DEPLOYING</text><text x="774" y="553">AGENT-33</text><text x="774" y="596">REFACTORING</text><text x="838" y="489">AGENT-98</text><text x="838" y="532">MERGING</text><text x="838" y="553">AGENT-70</text><text x="838" y="596">RUNNING TESTS</text><text x="902" y="489">AGENT-35</text><text x="902" y="532">CODING</text><text x="902" y="553">AGENT-07</text><text x="902" y="596">DEPLOYING</text><text x="966" y="489">AGENT-72</text><text x="966" y="532">LINTING</text><text x="966" y="553">AGENT-44</text><text x="966" y="596">MERGING</text><text x="774" y="617">AGENT-05</text><text x="774" y="660">CODING</text><text x="774" y="681">AGENT-77</text><text x="774" y="724">DEPLOYING</text><text x="838" y="617">AGENT-42</text><text x="838" y="660">LINTING</text><text x="838" y="681">AGENT-14</text><text x="838" y="724">MERGING</text><text x="1030" y="617">AGENT-53</text><text x="1030" y="660">DEPLOYING</text><text x="1030" y="681">AGENT-25</text><text x="1030" y="724">REFACTORING</text><text x="1094" y="617">AGENT-90</text><text x="1094" y="660">MERGING</text><text x="1094" y="681">AGENT-62</text><text x="1094" y="724">RUNNING TESTS</text><text x="326" y="169">AGENT-42</text><text x="326" y="212">LINTING</text><text x="390" y="233">AGENT-51</text><text x="390" y="276">CODING</text><text x="262" y="297">AGENT-49</text><text x="262" y="340">REFACTORING</text><text x="326" y="297">AGENT-86</text><text x="326" y="340">RUNNING TESTS</text><text x="390" y="297">AGENT-23</text><text x="390" y="340">DEPLOYING</text><text x="1542" y="233">AGENT-17</text><text x="1542" y="276">CODING</text><text x="1478" y="297">AGENT-52</text><text x="1478" y="340">RUNNING TESTS</text><text x="1606" y="361">AGENT-98</text><text x="1606" y="404">RUNNING TESTS</text><text x="1542" y="361">AGENT-61</text><text x="1542" y="404">REFACTORING</text><text x="1478" y="361">AGENT-24</text><text x="1478" y="404">LINTING</text><text x="454" y="873">AGENT-08</text><text x="454" y="916">MERGING</text><text x="518" y="809">AGENT-73</text><text x="518" y="852">REFACTORING</text><text x="390" y="745">AGENT-27</text><text x="390" y="788">REFACTORING</text><text x="454" y="745">AGENT-64</text><text x="454" y="788">RUNNING TESTS</text><text x="518" y="745">AGENT-01</text><text x="518" y="788">DEPLOYING</text><text x="1350" y="809">AGENT-54</text><text x="1350" y="852">RUNNING TESTS</text><text x="1414" y="809">AGENT-91</text><text x="1414" y="852">DEPLOYING</text><text x="1478" y="809">AGENT-28</text><text x="1478" y="852">MERGING</text><text x="1670" y="553">AGENT-51</text><text x="1670" y="596">DEPLOYING</text><text x="1734" y="553">AGENT-88</text><text x="1734" y="596">MERGING</text><text x="1670" y="617">AGENT-23</text><text x="1670" y="660">REFACTORING</text><text x="1734" y="617">AGENT-60</text><text x="1734" y="660">RUNNING TESTS</text></g>
@@ -1,10 +1,10 @@
1
1
  [Settings]
2
- gtk-theme-name=Yaru-viridian-dark
2
+ gtk-theme-name=@GTK_THEME_NAME@
3
3
  gtk-icon-theme-name=Yaru-viridian
4
4
  gtk-cursor-theme-name=Bibata-Modern-Ice
5
5
  gtk-cursor-theme-size=22
6
6
  gtk-font-name=General Sans 10
7
- gtk-application-prefer-dark-theme=1
7
+ gtk-application-prefer-dark-theme=@GTK_PREFER_DARK@
8
8
  gtk-xft-antialias=1
9
9
  gtk-xft-hinting=1
10
10
  gtk-xft-hintstyle=hintslight
@@ -4,6 +4,7 @@
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
6
6
  <title>Replicas Desktop</title>
7
+ <script src="./viewer-theme.js"></script>
7
8
  <link rel="stylesheet" href="./viewer-theme.css">
8
9
  <link rel="stylesheet" href="./viewer.css">
9
10
  <link rel="icon" href="./viewer-icon.svg" type="image/svg+xml">
@@ -6,32 +6,32 @@ window.client.padding.height: 0
6
6
  window.handle.width: 0
7
7
  window.label.text.justify: center
8
8
 
9
- window.active.border.color: #2b2d2c
10
- window.inactive.border.color: #242424
11
- window.*.client.color: #121212
9
+ window.active.border.color: @BORDER@
10
+ window.inactive.border.color: @BORDER_MUTED@
11
+ window.*.client.color: @SURFACE_ALT@
12
12
  window.*.title.bg: flat
13
- window.active.title.bg.color: #171717
14
- window.inactive.title.bg.color: #121212
13
+ window.active.title.bg.color: @SURFACE@
14
+ window.inactive.title.bg.color: @SURFACE_ALT@
15
15
  window.active.label.bg: parentrelative
16
16
  window.inactive.label.bg: parentrelative
17
17
  window.active.button.*.bg: flat
18
- window.active.button.*.bg.color: #171717
18
+ window.active.button.*.bg.color: @SURFACE@
19
19
  window.inactive.button.*.bg: flat
20
- window.inactive.button.*.bg.color: #121212
21
- window.active.button.*.image.color: #ededed
22
- window.inactive.button.*.image.color: #6f6f6f
20
+ window.inactive.button.*.bg.color: @SURFACE_ALT@
21
+ window.active.button.*.image.color: @INK@
22
+ window.inactive.button.*.image.color: @INK_FAINT@
23
23
  window.active.button.*.hover.bg: flat
24
- window.active.button.*.hover.bg.color: #2b2b2b
24
+ window.active.button.*.hover.bg.color: @SURFACE_RAISED@
25
25
  window.inactive.button.*.hover.bg: flat
26
- window.inactive.button.*.hover.bg.color: #2b2b2b
27
- window.active.button.*.hover.image.color: #ffffff
28
- window.inactive.button.*.hover.image.color: #ffffff
29
- window.active.button.*.pressed.image.color: #3eeba3
30
- window.inactive.button.*.pressed.image.color: #3eeba3
31
- window.active.label.text.color: #ededed
32
- window.inactive.label.text.color: #8a8a8a
33
- window.active.title.separator.color: #171717
34
- window.inactive.title.separator.color: #121212
26
+ window.inactive.button.*.hover.bg.color: @SURFACE_RAISED@
27
+ window.active.button.*.hover.image.color: @INK_STRONG@
28
+ window.inactive.button.*.hover.image.color: @INK_STRONG@
29
+ window.active.button.*.pressed.image.color: @ACCENT_INK@
30
+ window.inactive.button.*.pressed.image.color: @ACCENT_INK@
31
+ window.active.label.text.color: @INK@
32
+ window.inactive.label.text.color: @INK_MUTED@
33
+ window.active.title.separator.color: @SURFACE@
34
+ window.inactive.title.separator.color: @SURFACE_ALT@
35
35
 
36
36
  menu.border.width: 1
37
37
  menu.separator.width: 1
@@ -39,28 +39,28 @@ menu.separator.padding.width: 6
39
39
  menu.separator.padding.height: 4
40
40
  menu.overlap.x: 0
41
41
  menu.overlap.y: 0
42
- menu.border.color: #2b2d2c
43
- menu.separator.color: #2b2d2c
44
- menu.items.text.color: #ededed
45
- menu.items.disabled.text.color: #5c5c5c
42
+ menu.border.color: @BORDER@
43
+ menu.separator.color: @BORDER@
44
+ menu.items.text.color: @INK@
45
+ menu.items.disabled.text.color: @INK_DISABLED@
46
46
  menu.items.active.text.color: #121212
47
47
  menu.items.active.disabled.text.color: #1c6a49
48
48
  menu.items.bg: flat
49
- menu.items.bg.color: #171717
49
+ menu.items.bg.color: @SURFACE@
50
50
  menu.items.active.bg: flat
51
- menu.items.active.bg.color: #3eeba3
52
- menu.title.text.color: #a3a3a3
51
+ menu.items.active.bg.color: @ACCENT@
52
+ menu.title.text.color: @INK_MUTED@
53
53
  menu.title.bg: flat
54
- menu.title.bg.color: #121212
54
+ menu.title.bg.color: @SURFACE_ALT@
55
55
 
56
56
  osd.border.width: 1
57
- osd.border.color: #2b2d2c
57
+ osd.border.color: @BORDER@
58
58
  osd.bg: flat
59
- osd.bg.color: #171717
59
+ osd.bg.color: @SURFACE@
60
60
  osd.hilight.bg: flat
61
- osd.hilight.bg.color: #3eeba3
61
+ osd.hilight.bg.color: @ACCENT@
62
62
  osd.unhilight.bg: flat
63
- osd.unhilight.bg.color: #2b2b2b
63
+ osd.unhilight.bg.color: @SURFACE_RAISED@
64
64
  osd.label.bg: flat
65
- osd.label.bg.color: #171717
66
- osd.label.text.color: #ededed
65
+ osd.label.bg.color: @SURFACE@
66
+ osd.label.text.color: @INK@
@@ -1,10 +1,15 @@
1
1
  #!/bin/bash
2
2
  # xfce4-terminal 1.1 keeps its settings in xfconf, which needs a session bus this
3
3
  # desktop does not run, so the theme is applied per launch instead of via terminalrc.
4
+ STATE_DIR="${REPLICAS_DESKTOP_STATE_DIR:-/tmp/replicas-computer}"
5
+ TEMPLATES="${REPLICAS_DESKTOP_TEMPLATES:-/usr/local/share/replicas/desktop}"
6
+ THEME="$(cat "$STATE_DIR/theme" 2>/dev/null)"
7
+ [ -f "$TEMPLATES/themes/$THEME.env" ] || THEME=dark
8
+ . "$TEMPLATES/themes/$THEME.env"
4
9
  exec xfce4-terminal \
5
10
  --font='Geist Mono 11' \
6
- --color-bg='#121212' \
7
- --color-text='#ededed' \
11
+ --color-bg="$SURFACE_ALT" \
12
+ --color-text="$INK" \
8
13
  --hide-menubar \
9
14
  --hide-toolbar \
10
15
  --hide-scrollbar \
@@ -43,6 +43,8 @@ LOCK_BUSY_EXIT_CODE="${REPLICAS_DESKTOP_LOCK_BUSY_EXIT_CODE:-75}"
43
43
  LOCK_FILE="${REPLICAS_DESKTOP_LOCK_FILE:-$STATE_DIR/services-start.lock}"
44
44
 
45
45
  mkdir -p "$STATE_DIR"
46
+ REQUESTED_THEME=""
47
+ [ "$1" = "--theme" ] && REQUESTED_THEME="$2"
46
48
 
47
49
  acquire_start_lock() {
48
50
  if command -v flock >/dev/null 2>&1; then
@@ -264,8 +266,8 @@ clear_bridge_pid_if_unhealthy() {
264
266
  }
265
267
 
266
268
  paint_wallpaper() {
267
- local wallpaper="${REPLICAS_DESKTOP_WALLPAPER:-$REPLICAS_DESKTOP_TEMPLATES/brand-wallpaper.svg}"
268
- local rendered_wallpaper="$STATE_DIR/wallpaper-${WIDTH}x${HEIGHT}.png"
269
+ local wallpaper="${REPLICAS_DESKTOP_WALLPAPER:-$REPLICAS_DESKTOP_TEMPLATES/$WALLPAPER}"
270
+ local rendered_wallpaper="$STATE_DIR/wallpaper-$THEME-${WIDTH}x${HEIGHT}.png"
269
271
  if command -v ffmpeg >/dev/null 2>&1 && [ -f "$wallpaper" ] && [ ! -f "$rendered_wallpaper" ]; then
270
272
  ffmpeg -y -loglevel error \
271
273
  -i "$wallpaper" \
@@ -278,21 +280,35 @@ paint_wallpaper() {
278
280
  elif command -v hsetroot >/dev/null 2>&1 && [ -f "$wallpaper" ]; then
279
281
  DISPLAY=":$DISPLAY_NUM" hsetroot -cover "$wallpaper" >/dev/null 2>&1 || true
280
282
  elif command -v hsetroot >/dev/null 2>&1; then
281
- DISPLAY=":$DISPLAY_NUM" hsetroot -solid '#121212' >/dev/null 2>&1 || true
283
+ DISPLAY=":$DISPLAY_NUM" hsetroot -solid "$SURFACE_ALT" >/dev/null 2>&1 || true
282
284
  else
283
- DISPLAY=":$DISPLAY_NUM" xsetroot -solid '#121212' >/dev/null 2>&1 || true
285
+ DISPLAY=":$DISPLAY_NUM" xsetroot -solid "$SURFACE_ALT" >/dev/null 2>&1 || true
284
286
  fi
285
287
  DISPLAY=":$DISPLAY_NUM" xsetroot -cursor_name left_ptr >/dev/null 2>&1 || true
286
288
  }
287
289
 
288
290
  acquire_start_lock
289
291
 
292
+ REPLICAS_DESKTOP_TEMPLATES="${REPLICAS_DESKTOP_TEMPLATES:-/usr/local/share/replicas/desktop}"
293
+ PREVIOUS_THEME="$(cat "$STATE_DIR/theme" 2>/dev/null)"
294
+ THEME="${REQUESTED_THEME:-${PREVIOUS_THEME:-${REPLICAS_DESKTOP_THEME:-dark}}}"
295
+ [ -f "$REPLICAS_DESKTOP_TEMPLATES/themes/$THEME.env" ] || THEME=dark
296
+ . "$REPLICAS_DESKTOP_TEMPLATES/themes/$THEME.env"
297
+ echo "$THEME" > "$STATE_DIR/theme"
298
+
299
+ render_template() {
300
+ local expr="s|/usr/local/share/replicas/desktop|$REPLICAS_DESKTOP_TEMPLATES|g" key
301
+ for key in $(grep -o '^[A-Z_]*' "$REPLICAS_DESKTOP_TEMPLATES/themes/$THEME.env"); do
302
+ expr="$expr;s|@$key@|${!key}|g"
303
+ done
304
+ sed "$expr" "$1" > "$2"
305
+ }
306
+
290
307
  export XCURSOR_THEME="${XCURSOR_THEME:-Bibata-Modern-Ice}"
291
308
  export XCURSOR_SIZE="${XCURSOR_SIZE:-22}"
292
- export GTK_THEME="${GTK_THEME:-Yaru-viridian-dark}"
309
+ export GTK_THEME="$GTK_THEME_NAME"
293
310
  export GTK_ICON_THEME="${GTK_ICON_THEME:-Yaru-viridian}"
294
311
 
295
- REPLICAS_DESKTOP_TEMPLATES="${REPLICAS_DESKTOP_TEMPLATES:-/usr/local/share/replicas/desktop}"
296
312
  mkdir -p \
297
313
  "$HOME/.config/tint2" \
298
314
  "$HOME/.config/openbox" \
@@ -301,12 +317,13 @@ mkdir -p \
301
317
  "$HOME/.themes/Replicas-modern/openbox-3" \
302
318
  "$HOME/.icons/default"
303
319
 
304
- [ -f "$REPLICAS_DESKTOP_TEMPLATES/tint2rc" ] && sed "s|/usr/local/share/replicas/desktop|$REPLICAS_DESKTOP_TEMPLATES|g" "$REPLICAS_DESKTOP_TEMPLATES/tint2rc" > "$HOME/.config/tint2/tint2rc"
320
+ [ -f "$REPLICAS_DESKTOP_TEMPLATES/tint2rc" ] && render_template "$REPLICAS_DESKTOP_TEMPLATES/tint2rc" "$HOME/.config/tint2/tint2rc"
305
321
  [ -f "$REPLICAS_DESKTOP_TEMPLATES/openbox-rc.xml" ] && cp "$REPLICAS_DESKTOP_TEMPLATES/openbox-rc.xml" "$HOME/.config/openbox/rc.xml"
306
322
  [ -f "$REPLICAS_DESKTOP_TEMPLATES/picom.conf" ] && cp "$REPLICAS_DESKTOP_TEMPLATES/picom.conf" "$HOME/.config/picom/picom.conf"
307
- [ -f "$REPLICAS_DESKTOP_TEMPLATES/gtk-settings.ini" ] && cp "$REPLICAS_DESKTOP_TEMPLATES/gtk-settings.ini" "$HOME/.config/gtk-3.0/settings.ini"
323
+ [ -f "$REPLICAS_DESKTOP_TEMPLATES/gtk-settings.ini" ] && render_template "$REPLICAS_DESKTOP_TEMPLATES/gtk-settings.ini" "$HOME/.config/gtk-3.0/settings.ini"
308
324
  if [ -d "$REPLICAS_DESKTOP_TEMPLATES/openbox-theme" ]; then
309
- cp "$REPLICAS_DESKTOP_TEMPLATES/openbox-theme/"* "$HOME/.themes/Replicas-modern/openbox-3/" 2>/dev/null || true
325
+ cp "$REPLICAS_DESKTOP_TEMPLATES/openbox-theme/"*.xbm "$HOME/.themes/Replicas-modern/openbox-3/" 2>/dev/null || true
326
+ render_template "$REPLICAS_DESKTOP_TEMPLATES/openbox-theme/themerc" "$HOME/.themes/Replicas-modern/openbox-3/themerc"
310
327
  fi
311
328
  if [ -f "$REPLICAS_DESKTOP_TEMPLATES/replicas-chrome" ]; then
312
329
  sudo install -m 0755 "$REPLICAS_DESKTOP_TEMPLATES/replicas-chrome" /usr/local/bin/replicas-chrome 2>/dev/null || true
@@ -347,6 +364,12 @@ start_bg openbox \
347
364
  sleep 0.2
348
365
  paint_wallpaper
349
366
 
367
+ if [ -n "$REQUESTED_THEME" ] && [ "$THEME" != "$PREVIOUS_THEME" ]; then
368
+ DISPLAY=":$DISPLAY_NUM" openbox --reconfigure >/dev/null 2>&1 || true
369
+ kill_pids "$(cat "$STATE_DIR/tint2.pid" 2>/dev/null)"
370
+ rm -f "$STATE_DIR/tint2.pid"
371
+ fi
372
+
350
373
  # tint2 panel anchors window stacking on bare openbox.
351
374
  start_bg tint2 \
352
375
  "false" \
@@ -4,6 +4,7 @@
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
6
6
  <title>Replicas Desktop</title>
7
+ <script src="./viewer-theme.js"></script>
7
8
  <link rel="stylesheet" href="./viewer-theme.css">
8
9
  <link rel="stylesheet" href="./stream-viewer.css">
9
10
  <link rel="icon" href="./viewer-icon.svg" type="image/svg+xml">
@@ -1,10 +1,10 @@
1
- html, body { background: var(--replicas-black); }
1
+ html, body { background: var(--replicas-surface); }
2
2
  body { display: grid; place-items: center; }
3
3
 
4
4
  #screen {
5
5
  display: block;
6
6
  outline: none;
7
- background: var(--replicas-black);
7
+ background: var(--replicas-surface);
8
8
  cursor: default;
9
9
  touch-action: none;
10
10
  }
@@ -17,10 +17,10 @@ body { display: grid; place-items: center; }
17
17
  bottom: 16px;
18
18
  height: 32px;
19
19
  padding: 0 12px;
20
- border: 1px solid rgb(255 255 255 / 50%);
20
+ border: 1px solid var(--replicas-hairline-strong);
21
21
  border-radius: 0;
22
- color: rgb(255 255 255 / 75%);
23
- background: var(--replicas-black);
22
+ color: var(--replicas-ink);
23
+ background: var(--replicas-surface);
24
24
  font: 700 11px/1 "Geist Mono", ui-monospace, monospace;
25
25
  letter-spacing: 0.06em;
26
26
  text-transform: uppercase;
@@ -36,9 +36,9 @@ body { display: grid; place-items: center; }
36
36
  right: 12px;
37
37
  display: none;
38
38
  padding: 6px 10px;
39
- border: 1px solid rgb(255 255 255 / 16%);
40
- color: rgb(255 255 255 / 78%);
41
- background: rgb(18 18 18 / 88%);
39
+ border: 1px solid var(--replicas-hairline);
40
+ color: var(--replicas-ink);
41
+ background: var(--replicas-panel);
42
42
  font-size: 11px;
43
43
  pointer-events: none;
44
44
  }
@@ -0,0 +1,17 @@
1
+ WALLPAPER='brand-wallpaper.svg'
2
+ GTK_THEME_NAME='Yaru-viridian-dark'
3
+ GTK_PREFER_DARK='1'
4
+ SURFACE='#171717'
5
+ SURFACE_ALT='#121212'
6
+ SURFACE_RAISED='#2b2b2b'
7
+ BORDER='#2b2d2c'
8
+ BORDER_MUTED='#242424'
9
+ INK='#ededed'
10
+ INK_STRONG='#ffffff'
11
+ INK_MUTED='#8a8a8a'
12
+ INK_FAINT='#6f6f6f'
13
+ INK_DISABLED='#5c5c5c'
14
+ LINE='#ffffff'
15
+ ACCENT='#3eeba3'
16
+ ACCENT_INK='#3eeba3'
17
+ MARK_ICON='viewer-icon.svg'
@@ -0,0 +1,17 @@
1
+ WALLPAPER='brand-wallpaper-light.svg'
2
+ GTK_THEME_NAME='Yaru-viridian'
3
+ GTK_PREFER_DARK='0'
4
+ SURFACE='#ffffff'
5
+ SURFACE_ALT='#f2f3f1'
6
+ SURFACE_RAISED='#e8ece7'
7
+ BORDER='#d9ded8'
8
+ BORDER_MUTED='#e2e6e0'
9
+ INK='#162118'
10
+ INK_STRONG='#000000'
11
+ INK_MUTED='#67706a'
12
+ INK_FAINT='#8a938d'
13
+ INK_DISABLED='#b9c1b8'
14
+ LINE='#162118'
15
+ ACCENT='#2fc487'
16
+ ACCENT_INK='#2f9d57'
17
+ MARK_ICON='viewer-icon-light.svg'
@@ -4,48 +4,48 @@
4
4
  rounded = 18
5
5
  border_width = 1
6
6
  border_sides = TBLR
7
- background_color = #171717 100
8
- border_color = #ffffff 14
9
- background_color_hover = #171717 100
10
- border_color_hover = #ffffff 14
11
- background_color_pressed = #171717 100
12
- border_color_pressed = #ffffff 14
7
+ background_color = @SURFACE@ 100
8
+ border_color = @LINE@ 14
9
+ background_color_hover = @SURFACE@ 100
10
+ border_color_hover = @LINE@ 14
11
+ background_color_pressed = @SURFACE@ 100
12
+ border_color_pressed = @LINE@ 14
13
13
 
14
14
  # id 2 -> launcher_icon_background_id
15
15
  rounded = 12
16
16
  border_width = 0
17
- background_color = #ffffff 0
17
+ background_color = @LINE@ 0
18
18
  border_color = #000000 0
19
- background_color_hover = #ffffff 10
19
+ background_color_hover = @LINE@ 10
20
20
  border_color_hover = #000000 0
21
- background_color_pressed = #ffffff 6
21
+ background_color_pressed = @LINE@ 6
22
22
  border_color_pressed = #000000 0
23
23
 
24
24
  # id 3 -> task_background_id, task_iconified_background_id
25
25
  rounded = 12
26
26
  border_width = 0
27
- background_color = #ffffff 8
27
+ background_color = @LINE@ 8
28
28
  border_color = #000000 0
29
- background_color_hover = #ffffff 13
29
+ background_color_hover = @LINE@ 13
30
30
  border_color_hover = #000000 0
31
- background_color_pressed = #ffffff 6
31
+ background_color_pressed = @LINE@ 6
32
32
  border_color_pressed = #000000 0
33
33
 
34
34
  # id 4 -> task_active_background_id, task_urgent_background_id
35
35
  rounded = 12
36
36
  border_width = 1
37
- background_color = #3eeba3 12
38
- border_color = #3eeba3 40
39
- background_color_hover = #3eeba3 16
40
- border_color_hover = #3eeba3 40
41
- background_color_pressed = #3eeba3 10
42
- border_color_pressed = #3eeba3 40
37
+ background_color = @ACCENT@ 12
38
+ border_color = @ACCENT@ 40
39
+ background_color_hover = @ACCENT@ 16
40
+ border_color_hover = @ACCENT@ 40
41
+ background_color_pressed = @ACCENT@ 10
42
+ border_color_pressed = @ACCENT@ 40
43
43
 
44
44
  # id 5 -> tooltip_background_id
45
45
  rounded = 6
46
46
  border_width = 1
47
- background_color = #121212 96
48
- border_color = #ffffff 16
47
+ background_color = @SURFACE_ALT@ 96
48
+ border_color = @LINE@ 16
49
49
 
50
50
  panel_items = PLT:C
51
51
  panel_size = 100% 72
@@ -66,7 +66,7 @@ mouse_hover_icon_asb = 100 0 12
66
66
  mouse_pressed_icon_asb = 100 0 -14
67
67
 
68
68
  button = new
69
- button_icon = /usr/local/share/replicas/desktop/viewer-icon.svg
69
+ button_icon = /usr/local/share/replicas/desktop/@MARK_ICON@
70
70
  button_tooltip = Replicas Desktop
71
71
  button_background_id = 0
72
72
  button_centered = 1
@@ -113,7 +113,7 @@ urgent_nb_of_blink = 8
113
113
 
114
114
  separator = new
115
115
  separator_background_id = 0
116
- separator_color = #ffffff 18
116
+ separator_color = @LINE@ 18
117
117
  separator_style = line
118
118
  separator_size = 1
119
119
  separator_padding = 6 14
@@ -122,7 +122,7 @@ time1_format = %H:%M
122
122
  time2_format = %a %-d %b
123
123
  time1_font = General Sans Semibold 12
124
124
  time2_font = Geist Mono 8
125
- clock_font_color = #ededed 100
125
+ clock_font_color = @INK@ 100
126
126
  clock_padding = 12 0
127
127
  clock_background_id = 0
128
128
  clock_tooltip = %A, %B %-d
@@ -131,7 +131,7 @@ tooltip_padding = 10 6
131
131
  tooltip_show_timeout = 0.4
132
132
  tooltip_hide_timeout = 0.1
133
133
  tooltip_background_id = 5
134
- tooltip_font_color = #ededed 100
134
+ tooltip_font_color = @INK@ 100
135
135
  tooltip_font = General Sans 10
136
136
 
137
137
  mouse_middle = none
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 360" fill="#2fc487">
2
+ <path d="M68 30h75v75H68zm75 0h75v75h-75zm75 75h75v75h-75zM68 180h75v75H68zm75 0h75v75h-75zm-75 75h75v75H68zm150 0h75v75h-75z"/>
3
+ </svg>
@@ -31,13 +31,37 @@
31
31
  }
32
32
 
33
33
  :root {
34
- --replicas-black: #121212;
35
34
  --replicas-green: #3eeba3;
35
+ --replicas-mark-glow: rgb(62 235 163 / 45%);
36
+ --replicas-mark-filter: brightness(1);
37
+ --replicas-surface: #121212;
38
+ --replicas-ink: #ededed;
39
+ --replicas-title: #ffffff;
40
+ --replicas-ink-muted: rgb(255 255 255 / 60%);
41
+ --replicas-ink-faint: rgb(255 255 255 / 40%);
42
+ --replicas-hairline: rgb(255 255 255 / 16%);
43
+ --replicas-hairline-strong: rgb(255 255 255 / 50%);
44
+ --replicas-grid-line: rgb(255 255 255 / 12%);
45
+ --replicas-panel: rgb(18 18 18 / 90%);
36
46
  --replicas-grid:
37
- linear-gradient(to right, rgb(255 255 255 / 12%) 1px, transparent 1px) center / 64px 64px,
38
- linear-gradient(to bottom, rgb(255 255 255 / 12%) 1px, transparent 1px) center / 64px 64px,
39
- radial-gradient(circle at 50% 50%, rgb(62 235 163 / 7%), transparent 36%),
40
- var(--replicas-black);
47
+ linear-gradient(to right, var(--replicas-grid-line) 1px, transparent 1px) center / 64px 64px,
48
+ linear-gradient(to bottom, var(--replicas-grid-line) 1px, transparent 1px) center / 64px 64px,
49
+ var(--replicas-surface);
50
+ }
51
+
52
+ :root[data-theme="light"] {
53
+ --replicas-green: #2fc487;
54
+ --replicas-mark-glow: rgb(47 196 135 / 40%);
55
+ --replicas-mark-filter: brightness(0.84);
56
+ --replicas-surface: #f4f5f1;
57
+ --replicas-ink: #162118;
58
+ --replicas-title: #162118;
59
+ --replicas-ink-muted: rgb(22 33 24 / 60%);
60
+ --replicas-ink-faint: rgb(22 33 24 / 40%);
61
+ --replicas-hairline: rgb(22 33 24 / 14%);
62
+ --replicas-hairline-strong: rgb(22 33 24 / 45%);
63
+ --replicas-grid-line: rgb(22 33 24 / 10%);
64
+ --replicas-panel: rgb(244 245 241 / 92%);
41
65
  }
42
66
 
43
67
  html, body {
@@ -45,7 +69,7 @@ html, body {
45
69
  height: 100%;
46
70
  margin: 0;
47
71
  overflow: hidden;
48
- color: #ededed;
72
+ color: var(--replicas-ink);
49
73
  font-family: "Geist Mono", ui-monospace, monospace;
50
74
  }
51
75
 
@@ -67,7 +91,7 @@ html, body {
67
91
  #status img {
68
92
  width: 56px;
69
93
  height: 56px;
70
- filter: drop-shadow(0 0 18px rgb(62 235 163 / 45%));
94
+ filter: var(--replicas-mark-filter) drop-shadow(0 0 18px var(--replicas-mark-glow));
71
95
  animation: status-pulse 2.4s ease-in-out infinite;
72
96
  }
73
97
 
@@ -81,7 +105,7 @@ html, body {
81
105
  }
82
106
 
83
107
  #status-title {
84
- color: #fff;
108
+ color: var(--replicas-title);
85
109
  font-family: "General Sans", system-ui, sans-serif;
86
110
  font-size: 30px;
87
111
  font-weight: 300;
@@ -92,7 +116,7 @@ html, body {
92
116
  #status-text {
93
117
  max-width: 72ch;
94
118
  padding: 0 24px;
95
- color: rgb(255 255 255 / 60%);
119
+ color: var(--replicas-ink-muted);
96
120
  font-size: 11px;
97
121
  font-weight: 600;
98
122
  letter-spacing: 0.12em;
@@ -103,7 +127,7 @@ html, body {
103
127
 
104
128
  .frame-corner, .frame-label {
105
129
  position: absolute;
106
- color: rgb(255 255 255 / 40%);
130
+ color: var(--replicas-ink-faint);
107
131
  font-size: 14px;
108
132
  line-height: 1;
109
133
  }
@@ -0,0 +1,8 @@
1
+ (() => {
2
+ const requested = new URLSearchParams(location.search).get('theme');
3
+ const theme = requested === 'light' || requested === 'dark'
4
+ ? requested
5
+ : matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
6
+ document.documentElement.dataset.theme = theme;
7
+ document.documentElement.style.colorScheme = theme;
8
+ })();
@@ -10,9 +10,9 @@ html, body { background: var(--replicas-grid); }
10
10
  bottom: 20px;
11
11
  left: 50%;
12
12
  padding: 8px 12px;
13
- border: 1px solid rgb(255 255 255 / 16%);
14
- color: rgb(255 255 255 / 85%);
15
- background: rgb(18 18 18 / 94%);
13
+ border: 1px solid var(--replicas-hairline);
14
+ color: var(--replicas-ink);
15
+ background: var(--replicas-panel);
16
16
  font-size: 11px;
17
17
  font-weight: 500;
18
18
  white-space: nowrap;
package/dist/index.js CHANGED
@@ -2926,7 +2926,7 @@ async function computerStatusCommand() {
2926
2926
  }
2927
2927
 
2928
2928
  // src/version.ts
2929
- var COMPUTER_USE_VERSION = "0.2.10";
2929
+ var COMPUTER_USE_VERSION = "0.2.12";
2930
2930
  var COMPUTER_USE_PROTOCOL_VERSION = 1;
2931
2931
 
2932
2932
  // src/program.ts
@@ -3544,6 +3544,7 @@ function mediaPacket(kind, timestamp, payload) {
3544
3544
  function validInput(value) {
3545
3545
  if (!value || typeof value !== "object" || !("type" in value) || typeof value.type !== "string") return false;
3546
3546
  if (value.type === "release") return true;
3547
+ if (value.type === "theme") return "theme" in value && (value.theme === "light" || value.theme === "dark");
3547
3548
  if (value.type === "stats") return "videoFps" in value && typeof value.videoFps === "number" && Number.isFinite(value.videoFps) && "audioPacketsPerSecond" in value && typeof value.audioPacketsPerSecond === "number" && Number.isFinite(value.audioPacketsPerSecond) && "decodeQueue" in value && typeof value.decodeQueue === "number" && Number.isFinite(value.decodeQueue) && "rttMs" in value && typeof value.rttMs === "number" && Number.isFinite(value.rttMs);
3548
3549
  if (value.type === "ping" || value.type === "pong") return "sentAt" in value && typeof value.sentAt === "number";
3549
3550
  if (value.type === "key") return "code" in value && typeof value.code === "string" && value.code.length < 40 && "down" in value && typeof value.down === "boolean";
@@ -3552,6 +3553,28 @@ function validInput(value) {
3552
3553
  if (value.type === "button") return "button" in value && typeof value.button === "number" && "down" in value && typeof value.down === "boolean";
3553
3554
  return value.type === "wheel" && "deltaX" in value && typeof value.deltaX === "number" && "deltaY" in value && typeof value.deltaY === "number";
3554
3555
  }
3556
+ var appliedTheme;
3557
+ var pendingTheme;
3558
+ var applyingTheme = false;
3559
+ function applyDesktopTheme(theme) {
3560
+ pendingTheme = theme;
3561
+ if (!applyingTheme) drainDesktopTheme();
3562
+ }
3563
+ function drainDesktopTheme() {
3564
+ const theme = pendingTheme;
3565
+ pendingTheme = void 0;
3566
+ if (theme === void 0 || theme === appliedTheme) return;
3567
+ applyingTheme = true;
3568
+ const finish = (applied) => {
3569
+ applyingTheme = false;
3570
+ if (applied) appliedTheme = theme;
3571
+ drainDesktopTheme();
3572
+ };
3573
+ const child = spawn4("bash", [SERVICES_SCRIPT, "--theme", theme], { detached: true, stdio: "ignore" });
3574
+ child.unref();
3575
+ child.once("exit", (code) => finish(code === 0));
3576
+ child.once("error", () => finish(false));
3577
+ }
3555
3578
  async function runMediaServer() {
3556
3579
  if (![width, height, fps, port].every((value) => Number.isInteger(value) && value > 0)) throw new Error("Invalid desktop stream dimensions, frame rate, or port");
3557
3580
  const videoSocket = await bindUdp();
@@ -3926,7 +3949,8 @@ async function runMediaServer() {
3926
3949
  decodeQueue: clamp(message.decodeQueue, 0, 1e3),
3927
3950
  rttMs: clamp(message.rttMs, 0, 6e5)
3928
3951
  };
3929
- } else clients.get(client)?.input.handle(message);
3952
+ } else if (message.type === "theme") applyDesktopTheme(message.theme);
3953
+ else clients.get(client)?.input.handle(message);
3930
3954
  });
3931
3955
  client.once("close", () => {
3932
3956
  clients.get(client)?.input.close();
@@ -4093,13 +4117,13 @@ function setupComputer(options = {}) {
4093
4117
  mkdirSync6(viewerRoot, { recursive: true });
4094
4118
  cpSync(noVncCore, resolve3(viewerRoot, "core"), { recursive: true, force: true });
4095
4119
  cpSync(noVncVendor, resolve3(viewerRoot, "vendor"), { recursive: true, force: true });
4096
- for (const file of ["novnc-index.html", "viewer.css", "viewer-theme.css", "viewer-icon.svg", "geist-mono-400.ttf", "geist-mono-600.ttf", "geist-mono-700.ttf", "general-sans-300.ttf"]) {
4120
+ for (const file of ["novnc-index.html", "viewer.css", "viewer-theme.css", "viewer-theme.js", "viewer-icon.svg", "geist-mono-400.ttf", "geist-mono-600.ttf", "geist-mono-700.ttf", "general-sans-300.ttf"]) {
4097
4121
  cpSync(resolve3(assets, file), resolve3(viewerRoot, file === "novnc-index.html" ? "index.html" : file), { force: true });
4098
4122
  }
4099
4123
  cpSync(resolve3(packageRoot2, "dist", "viewer.js"), resolve3(viewerRoot, "viewer.js"), { force: true });
4100
4124
  const streamRoot = "/usr/local/share/replicas/desktop/stream";
4101
4125
  mkdirSync6(streamRoot, { recursive: true });
4102
- for (const file of ["stream-index.html", "stream-viewer.css", "viewer-theme.css", "viewer-icon.svg", "geist-mono-400.ttf", "geist-mono-600.ttf", "geist-mono-700.ttf", "general-sans-300.ttf"]) {
4126
+ for (const file of ["stream-index.html", "stream-viewer.css", "viewer-theme.css", "viewer-theme.js", "viewer-icon.svg", "geist-mono-400.ttf", "geist-mono-600.ttf", "geist-mono-700.ttf", "general-sans-300.ttf"]) {
4103
4127
  cpSync(resolve3(assets, file), resolve3(streamRoot, file), { force: true });
4104
4128
  }
4105
4129
  cpSync(resolve3(packageRoot2, "dist", "stream-viewer.js"), resolve3(streamRoot, "stream-viewer.js"), { force: true });
@@ -192,6 +192,7 @@ var connect = () => {
192
192
  nextSocket.addEventListener("open", () => {
193
193
  if (socket !== nextSocket) return;
194
194
  reconnectAttempt = 0;
195
+ send({ type: "theme", theme: document.documentElement.dataset.theme === "light" ? "light" : "dark" });
195
196
  });
196
197
  nextSocket.addEventListener("message", (event) => {
197
198
  if (socket !== nextSocket) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-computer",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "Replicas workspace computer-use runtime",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",