@zerwiz/sessrumnir 0.1.14 → 0.1.16
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/LICENSE +9 -7
- package/NOTICE +33 -0
- package/out/main/index.js +6 -4
- package/out/renderer/assets/{index-DaKov4Fl.css → index-DL2o01yM.css} +9 -0
- package/out/renderer/assets/{index-BS9g6EfW.js → index-DbCaU2eq.js} +253 -61
- package/out/renderer/index.html +2 -2
- package/package.json +5 -3
- package/resources/icons/icon-128.png +0 -0
- package/resources/icons/icon-16.png +0 -0
- package/resources/icons/icon-256.png +0 -0
- package/resources/icons/icon-32.png +0 -0
- package/resources/icons/icon-48.png +0 -0
- package/src/renderer/src/app.tsx +3 -0
- package/src/renderer/src/assets/ember.d.ts +13 -0
- package/src/renderer/src/assets/ember.js +183 -0
- package/src/renderer/src/components/EmberBackground.tsx +14 -0
- package/src/renderer/src/components/theme-editor.tsx +1 -1
- package/src/renderer/src/index.css +3 -0
- package/src/renderer/src/store.ts +1 -1
- package/src/renderer/src/themes/fensalir.json +82 -0
- package/src/renderer/src/themes/index.ts +6 -0
- package/src/renderer/src/themes/sessrumnir.json +82 -0
- package/src/shared/default-settings.ts +3 -3
- package/src/shared/theme/builtin-ids.ts +1 -1
package/LICENSE
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
Apache License
|
|
2
3
|
Version 2.0, January 2004
|
|
3
4
|
http://www.apache.org/licenses/
|
|
@@ -48,7 +49,7 @@
|
|
|
48
49
|
"Contribution" shall mean any work of authorship, including
|
|
49
50
|
the original version of the Work and any modifications or additions
|
|
50
51
|
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
-
submitted to
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
53
|
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
54
|
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
55
|
means any form of electronic, verbal, or written communication sent
|
|
@@ -60,7 +61,7 @@
|
|
|
60
61
|
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
62
|
|
|
62
63
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
-
on behalf of whom a Contribution has been received by
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
65
|
subsequently incorporated within the Work.
|
|
65
66
|
|
|
66
67
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
@@ -106,7 +107,7 @@
|
|
|
106
107
|
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
108
|
distribution, then any Derivative Works that You distribute must
|
|
108
109
|
include a readable copy of the attribution notices contained
|
|
109
|
-
within such NOTICE file, excluding
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
111
|
pertain to any part of the Derivative Works, in at least one
|
|
111
112
|
of the following places: within a NOTICE text file distributed
|
|
112
113
|
as part of the Derivative Works; within the Source form or
|
|
@@ -181,11 +182,12 @@
|
|
|
181
182
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
183
|
replaced with your own identifying information. (Don't include
|
|
183
184
|
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
-
comment syntax for the file format.
|
|
185
|
-
|
|
186
|
-
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
187
189
|
|
|
188
|
-
Copyright 2026
|
|
190
|
+
Copyright 2026 zerwiz
|
|
189
191
|
|
|
190
192
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
191
193
|
you may not use this file except in compliance with the License.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Sessrúmnir
|
|
2
|
+
Copyright 2026 zerwiz
|
|
3
|
+
|
|
4
|
+
This project is a vendored, re-themed fork of **pi-desktop**, an Electron
|
|
5
|
+
desktop GUI for the Pi and OMP coding agents, distributed under the Apache
|
|
6
|
+
License, Version 2.0. The vendored source is kept in this directory; the
|
|
7
|
+
upstream repository is https://github.com/FaqFirebase/pi-desktop (v0.1.7-alpha,
|
|
8
|
+
commit 4a5601b).
|
|
9
|
+
|
|
10
|
+
The following copyright notice applies to the portions derived from pi-desktop:
|
|
11
|
+
|
|
12
|
+
Copyright 2026 Pi Desktop GUI Contributors.
|
|
13
|
+
|
|
14
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
15
|
+
use this work except in compliance with the License. You may obtain a copy of
|
|
16
|
+
the License at
|
|
17
|
+
|
|
18
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
19
|
+
|
|
20
|
+
Unless required by applicable law or agreed to in writing, software
|
|
21
|
+
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
22
|
+
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
23
|
+
License for the specific language governing permissions and limitations under
|
|
24
|
+
the License.
|
|
25
|
+
|
|
26
|
+
Changes made by Ymir beyond the upstream source:
|
|
27
|
+
- Rebranded the GUI to Sessrúmnir (window titles, launcher, package identity,
|
|
28
|
+
tray/autostart strings, data-dir name).
|
|
29
|
+
- Added the Sessrúmnir built-in theme (Ymir way-of palette: sky #38bdf8 on
|
|
30
|
+
deep navy) and made it the default.
|
|
31
|
+
- Replaced the Pi logo asset with the Sessrúmnir Sowilo rune mark.
|
|
32
|
+
- Added bin/sessrumnir.sh and bin/sessrumnir-ensure.sh and wired the app into
|
|
33
|
+
bin/ymir-install.sh.
|
package/out/main/index.js
CHANGED
|
@@ -5482,9 +5482,9 @@ const DEFAULT_SETTINGS = {
|
|
|
5482
5482
|
piExecutablePath: "pi",
|
|
5483
5483
|
piEngine: "auto",
|
|
5484
5484
|
defaultArgs: [],
|
|
5485
|
-
theme: "
|
|
5486
|
-
systemLightTheme: "
|
|
5487
|
-
systemDarkTheme: "
|
|
5485
|
+
theme: "fensalir",
|
|
5486
|
+
systemLightTheme: "fensalir",
|
|
5487
|
+
systemDarkTheme: "fensalir",
|
|
5488
5488
|
defaultModel: null,
|
|
5489
5489
|
defaultProvider: null,
|
|
5490
5490
|
defaultCwd: null,
|
|
@@ -7308,7 +7308,9 @@ const BUILTIN_THEME_IDS = [
|
|
|
7308
7308
|
"gruvbox",
|
|
7309
7309
|
"breeze-dark",
|
|
7310
7310
|
"breeze-light",
|
|
7311
|
-
"breeze-claudius"
|
|
7311
|
+
"breeze-claudius",
|
|
7312
|
+
"sessrumnir",
|
|
7313
|
+
"fensalir"
|
|
7312
7314
|
];
|
|
7313
7315
|
const THEME_FILE_EXT = ".json";
|
|
7314
7316
|
const VALID_THEME_ID = /^[a-z0-9-]+$/;
|
|
@@ -4106,6 +4106,15 @@
|
|
|
4106
4106
|
font-display: swap;
|
|
4107
4107
|
}
|
|
4108
4108
|
|
|
4109
|
+
.ember-bg {
|
|
4110
|
+
z-index: 0;
|
|
4111
|
+
pointer-events: none;
|
|
4112
|
+
opacity: .5;
|
|
4113
|
+
mix-blend-mode: screen;
|
|
4114
|
+
position: fixed;
|
|
4115
|
+
inset: 0;
|
|
4116
|
+
}
|
|
4117
|
+
|
|
4109
4118
|
@property --tw-translate-x {
|
|
4110
4119
|
syntax: "*";
|
|
4111
4120
|
inherits: false;
|
|
@@ -16210,9 +16210,9 @@ function resolveSidebarWidth(draft, persisted) {
|
|
|
16210
16210
|
const DEFAULT_SETTINGS = {
|
|
16211
16211
|
piExecutablePath: "pi",
|
|
16212
16212
|
piEngine: "auto",
|
|
16213
|
-
theme: "
|
|
16214
|
-
systemLightTheme: "
|
|
16215
|
-
systemDarkTheme: "
|
|
16213
|
+
theme: "fensalir",
|
|
16214
|
+
systemLightTheme: "fensalir",
|
|
16215
|
+
systemDarkTheme: "fensalir",
|
|
16216
16216
|
fontSize: 16,
|
|
16217
16217
|
terminalFontSize: 12,
|
|
16218
16218
|
codeEditorFontSize: 14,
|
|
@@ -16405,7 +16405,7 @@ const DEFAULT_SYNTAX = {
|
|
|
16405
16405
|
}
|
|
16406
16406
|
};
|
|
16407
16407
|
const TOKEN_FOR_SEED = Object.fromEntries(
|
|
16408
|
-
Object.entries(SEED_TO_TOKEN).map(([
|
|
16408
|
+
Object.entries(SEED_TO_TOKEN).map(([seed2, token]) => [token, seed2])
|
|
16409
16409
|
);
|
|
16410
16410
|
function resolveThemeVars(file) {
|
|
16411
16411
|
const vars = {};
|
|
@@ -16432,39 +16432,69 @@ const BUILTIN_THEME_IDS$1 = [
|
|
|
16432
16432
|
"gruvbox",
|
|
16433
16433
|
"breeze-dark",
|
|
16434
16434
|
"breeze-light",
|
|
16435
|
-
"breeze-claudius"
|
|
16435
|
+
"breeze-claudius",
|
|
16436
|
+
"sessrumnir",
|
|
16437
|
+
"fensalir"
|
|
16436
16438
|
];
|
|
16439
|
+
const $schema$8 = "pi-theme/v1";
|
|
16440
|
+
const name$a = "Dark";
|
|
16441
|
+
const kind$8 = "dark";
|
|
16442
|
+
const seeds$8 = { "app": "#0a0a0a", "surface": "#171717", "text": "#f5f5f5", "accent": "#2563eb", "success": "#34d399", "warning": "#facc15", "error": "#f87171" };
|
|
16443
|
+
const overrides$9 = { "surface-hover": "#262626", "card": "#262626", "elevated": "#404040", "highlight": "#171717", "highlight-strong": "#262626", "secondary": "#d4d4d4", "muted": "#a3a3a3", "dim": "#737373", "faint": "#525252", "ghost": "#404040", "inverse": "#0a0a0a", "border": "#262626", "border-strong": "#404040", "focus": "#3b82f6", "accent-hover": "#1d4ed8", "accent-fg": "#60a5fa", "accent-bg": "rgba(30, 58, 138, 0.3)", "success-bg": "rgba(6, 78, 59, 0.3)", "warning-bg": "rgba(113, 63, 18, 0.3)", "error-bg": "rgba(127, 29, 29, 0.3)", "info": "#60a5fa", "info-bg": "rgba(30, 58, 138, 0.3)", "special": "#c084fc", "special-bg": "rgba(88, 28, 135, 0.3)", "chat-column": "#0a0a0a", "chat-column-border": "#262626", "scrollbar": "#2a2a2a", "scrollbar-hover": "#3a3a3a", "md-code": "#60a5fa", "md-pre-bg": "#0d1117" };
|
|
16444
|
+
const dark = {
|
|
16445
|
+
$schema: $schema$8,
|
|
16446
|
+
name: name$a,
|
|
16447
|
+
kind: kind$8,
|
|
16448
|
+
seeds: seeds$8,
|
|
16449
|
+
overrides: overrides$9
|
|
16450
|
+
};
|
|
16451
|
+
const $schema$7 = "pi-theme/v1";
|
|
16452
|
+
const name$9 = "Light";
|
|
16453
|
+
const kind$7 = "light";
|
|
16454
|
+
const seeds$7 = { "app": "#ffffff", "surface": "#f5f5f5", "text": "#171717", "accent": "#2563eb", "success": "#10b981", "warning": "#f59e0b", "error": "#ef4444" };
|
|
16455
|
+
const overrides$8 = { "surface-hover": "#e5e5e5", "card": "#e5e5e5", "elevated": "#d4d4d4", "highlight": "#f5f5f5", "highlight-strong": "#e5e5e5", "secondary": "#404040", "muted": "#525252", "dim": "#737373", "faint": "#a3a3a3", "ghost": "#d4d4d4", "inverse": "#ffffff", "border": "#e5e5e5", "border-strong": "#d4d4d4", "focus": "#3b82f6", "accent-hover": "#1d4ed8", "accent-fg": "#3b82f6", "accent-bg": "rgba(30, 64, 175, 0.15)", "success-bg": "rgba(6, 95, 70, 0.15)", "warning-bg": "rgba(113, 63, 18, 0.15)", "error-bg": "rgba(153, 27, 27, 0.15)", "info": "#3b82f6", "info-bg": "rgba(30, 64, 175, 0.15)", "special": "#a855f7", "special-bg": "rgba(88, 28, 135, 0.15)", "chat-column": "#ffffff", "chat-column-border": "#e5e5e5", "scrollbar": "#d4d4d4", "scrollbar-hover": "#a3a3a3", "md-code": "#a855f7", "md-pre-bg": "#f8f9fa" };
|
|
16456
|
+
const light = {
|
|
16457
|
+
$schema: $schema$7,
|
|
16458
|
+
name: name$9,
|
|
16459
|
+
kind: kind$7,
|
|
16460
|
+
seeds: seeds$7,
|
|
16461
|
+
overrides: overrides$8
|
|
16462
|
+
};
|
|
16437
16463
|
const $schema$6 = "pi-theme/v1";
|
|
16438
|
-
const name$8 = "
|
|
16464
|
+
const name$8 = "Nord";
|
|
16439
16465
|
const kind$6 = "dark";
|
|
16440
|
-
const seeds$6 = { "app": "#
|
|
16441
|
-
const overrides$7 = { "surface-hover": "#
|
|
16442
|
-
const
|
|
16466
|
+
const seeds$6 = { "app": "#2E3440", "surface": "#3B4252", "text": "#ECEFF4", "accent": "#5E81AC", "success": "#A3BE8C", "warning": "#EBCB8B", "error": "#BF616A" };
|
|
16467
|
+
const overrides$7 = { "surface-hover": "#434C5E", "card": "#434C5E", "elevated": "#4C566A", "highlight": "#3B4252", "highlight-strong": "#434C5E", "secondary": "#D8DEE9", "muted": "#9599A3", "dim": "#616E88", "faint": "#4C566A", "ghost": "#434C5E", "inverse": "#2E3440", "border": "#434C5E", "border-strong": "#4C566A", "focus": "#88C0D0", "accent-hover": "#81A1C1", "accent-fg": "#81A1C1", "accent-bg": "rgba(46, 52, 64, 0.5)", "success-bg": "rgba(163, 190, 140, 0.15)", "warning-bg": "rgba(235, 203, 139, 0.15)", "error-bg": "rgba(191, 97, 106, 0.15)", "info": "#81A1C1", "info-bg": "rgba(46, 52, 64, 0.5)", "special": "#B48EAD", "special-bg": "rgba(180, 142, 173, 0.15)", "chat-column": "#2E3440", "chat-column-border": "#434C5E", "scrollbar": "#434C5E", "scrollbar-hover": "#4C566A", "md-code": "#B48EAD", "md-pre-bg": "#242932" };
|
|
16468
|
+
const syntax$6 = { "keyword": "#C792EA", "string": "#C3E88D", "comment": "#7B88A1", "function": "#82AAFF", "type": "#FFCB6B", "number": "#F78C6C", "operator": "#89DDFF", "property": "#F78C6C", "tag": "#F07178", "variable": "#EEFFFF", "constant": "#F78C6C", "heading": "#C792EA", "link": "#C3E88D", "list": "#F78C6C", "quote": "#7B88A1", "meta": "#B2CCD6", "mark": "#C792EA", "invalid": "#F07178", "active-line-bg": "rgba(216, 222, 233, 0.05)", "selection-bg": "rgba(94, 129, 172, 0.40)", "selection-match-bg": "rgba(216, 222, 233, 0.08)" };
|
|
16469
|
+
const nord = {
|
|
16443
16470
|
$schema: $schema$6,
|
|
16444
16471
|
name: name$8,
|
|
16445
16472
|
kind: kind$6,
|
|
16446
16473
|
seeds: seeds$6,
|
|
16447
|
-
overrides: overrides$7
|
|
16474
|
+
overrides: overrides$7,
|
|
16475
|
+
syntax: syntax$6
|
|
16448
16476
|
};
|
|
16449
16477
|
const $schema$5 = "pi-theme/v1";
|
|
16450
|
-
const name$7 = "
|
|
16451
|
-
const kind$5 = "
|
|
16452
|
-
const seeds$5 = { "app": "#
|
|
16453
|
-
const overrides$6 = { "surface-hover": "#
|
|
16454
|
-
const
|
|
16478
|
+
const name$7 = "Gruvbox";
|
|
16479
|
+
const kind$5 = "dark";
|
|
16480
|
+
const seeds$5 = { "app": "#282828", "surface": "#3C3836", "text": "#EBDBB2", "accent": "#458588", "success": "#B8BB26", "warning": "#FABD2F", "error": "#FB4934" };
|
|
16481
|
+
const overrides$6 = { "surface-hover": "#504945", "card": "#504945", "elevated": "#665C54", "highlight": "#3C3836", "highlight-strong": "#504945", "secondary": "#BDAE93", "muted": "#A89984", "dim": "#928374", "faint": "#7C6F64", "ghost": "#665C54", "inverse": "#282828", "border": "#504945", "border-strong": "#665C54", "focus": "#D79921", "accent-hover": "#689D6A", "accent-fg": "#83A598", "accent-bg": "rgba(40, 40, 40, 0.5)", "success-bg": "rgba(152, 151, 26, 0.15)", "warning-bg": "rgba(215, 153, 33, 0.15)", "error-bg": "rgba(204, 36, 29, 0.15)", "info": "#83A598", "info-bg": "rgba(40, 40, 40, 0.5)", "special": "#D3869B", "special-bg": "rgba(177, 98, 134, 0.15)", "chat-column": "#282828", "chat-column-border": "#504945", "scrollbar": "#504945", "scrollbar-hover": "#665C54", "md-code": "#D3869B", "md-pre-bg": "#1D2021" };
|
|
16482
|
+
const syntax$5 = { "keyword": "#D3869B", "string": "#B8BB26", "comment": "#A89984", "function": "#FABD2F", "type": "#FABD2F", "number": "#FE8019", "operator": "#83A598", "property": "#FE8019", "tag": "#FB4934", "variable": "#EBDBB2", "constant": "#FE8019", "heading": "#D3869B", "link": "#B8BB26", "list": "#FE8019", "quote": "#A89984", "meta": "#BDAE93", "mark": "#D3869B", "invalid": "#FB4934", "active-line-bg": "rgba(235, 219, 178, 0.04)", "selection-bg": "rgba(69, 133, 136, 0.40)", "selection-match-bg": "rgba(235, 219, 178, 0.08)" };
|
|
16483
|
+
const gruvbox = {
|
|
16455
16484
|
$schema: $schema$5,
|
|
16456
16485
|
name: name$7,
|
|
16457
16486
|
kind: kind$5,
|
|
16458
16487
|
seeds: seeds$5,
|
|
16459
|
-
overrides: overrides$6
|
|
16488
|
+
overrides: overrides$6,
|
|
16489
|
+
syntax: syntax$5
|
|
16460
16490
|
};
|
|
16461
16491
|
const $schema$4 = "pi-theme/v1";
|
|
16462
|
-
const name$6 = "
|
|
16492
|
+
const name$6 = "Breeze Dark";
|
|
16463
16493
|
const kind$4 = "dark";
|
|
16464
|
-
const seeds$4 = { "app": "#
|
|
16465
|
-
const overrides$5 = { "surface-hover": "#
|
|
16466
|
-
const syntax$4 = { "keyword": "#
|
|
16467
|
-
const
|
|
16494
|
+
const seeds$4 = { "app": "#232629", "surface": "#31363b", "text": "#cfcfc2", "accent": "#2980b9", "success": "#1c8042", "warning": "#fdbc4b", "error": "#da4453" };
|
|
16495
|
+
const overrides$5 = { "surface-hover": "#3f4347", "card": "#3f4347", "elevated": "#4d5358", "highlight": "#31363b", "highlight-strong": "#3f4347", "secondary": "#a5a6a8", "muted": "#898a8c", "dim": "#7a7c7d", "faint": "#5f6266", "ghost": "#4d5358", "inverse": "#232629", "border": "#3f4347", "border-strong": "#4d5358", "focus": "#3daee9", "accent-hover": "#3daee9", "accent-fg": "#3daee9", "accent-bg": "rgba(45, 92, 118, 0.5)", "success-bg": "rgba(28, 128, 66, 0.15)", "warning-bg": "rgba(246, 116, 0, 0.15)", "error-bg": "rgba(218, 68, 83, 0.15)", "info": "#3daee9", "info-bg": "rgba(45, 92, 118, 0.5)", "special": "#8e44ad", "special-bg": "rgba(142, 68, 173, 0.15)", "chat-column": "#232629", "chat-column-border": "#3f4347", "scrollbar": "#3f4347", "scrollbar-hover": "#4d5358", "md-code": "#60a5fa", "md-pre-bg": "#1d2024" };
|
|
16496
|
+
const syntax$4 = { "keyword": "#fdbc4b", "string": "#f44f4f", "comment": "#7a7c7d", "function": "#8e44ad", "type": "#2980b9", "number": "#f67400", "operator": "#3f8058", "property": "#27aeae", "tag": "#2980b9", "variable": "#cfcfc2", "constant": "#27aeae", "heading": "#8e44ad", "link": "#0099ff", "list": "#da4453", "quote": "#7a7c7d", "meta": "#a5a6a8", "mark": "#8e44ad", "invalid": "#da4453", "active-line-bg": "#2A2E32", "selection-bg": "rgba(45, 92, 118, 0.65)", "selection-match-bg": "rgba(65, 72, 87, 0.5)" };
|
|
16497
|
+
const breezeDark = {
|
|
16468
16498
|
$schema: $schema$4,
|
|
16469
16499
|
name: name$6,
|
|
16470
16500
|
kind: kind$4,
|
|
@@ -16473,12 +16503,12 @@ const nord = {
|
|
|
16473
16503
|
syntax: syntax$4
|
|
16474
16504
|
};
|
|
16475
16505
|
const $schema$3 = "pi-theme/v1";
|
|
16476
|
-
const name$5 = "
|
|
16477
|
-
const kind$3 = "
|
|
16478
|
-
const seeds$3 = { "app": "#
|
|
16479
|
-
const overrides$4 = { "surface-hover": "#
|
|
16480
|
-
const syntax$3 = { "keyword": "#
|
|
16481
|
-
const
|
|
16506
|
+
const name$5 = "Breeze Light";
|
|
16507
|
+
const kind$3 = "light";
|
|
16508
|
+
const seeds$3 = { "app": "#ffffff", "surface": "#f8f7f6", "text": "#1f1c1b", "accent": "#0057ae", "success": "#006e28", "warning": "#b08000", "error": "#bf0303" };
|
|
16509
|
+
const overrides$4 = { "surface-hover": "#ebebeb", "card": "#ebebeb", "elevated": "#d8d8d8", "highlight": "#f8f7f6", "highlight-strong": "#ebebeb", "secondary": "#444444", "muted": "#5d5d5d", "dim": "#7a7c7d", "faint": "#898887", "ghost": "#d8d8d8", "inverse": "#ffffff", "border": "#d8d8d8", "border-strong": "#c0c0bf", "focus": "#0057ae", "accent-hover": "#2980b9", "accent-fg": "#0057ae", "accent-bg": "rgba(0, 87, 174, 0.12)", "success-bg": "rgba(0, 110, 40, 0.12)", "warning-bg": "rgba(176, 128, 0, 0.12)", "error-bg": "rgba(191, 3, 3, 0.12)", "info": "#0057ae", "info-bg": "rgba(0, 87, 174, 0.12)", "special": "#644a9b", "special-bg": "rgba(100, 74, 155, 0.12)", "chat-column": "#ffffff", "chat-column-border": "#d8d8d8", "scrollbar": "#d8d8d8", "scrollbar-hover": "#898887", "md-code": "#644a9b", "md-pre-bg": "#f8f7f6" };
|
|
16510
|
+
const syntax$3 = { "keyword": "#b08000", "string": "#bf0303", "comment": "#898887", "function": "#644a9b", "type": "#0057ae", "number": "#b08000", "operator": "#ca60ca", "property": "#0057ae", "tag": "#0057ae", "variable": "#1f1c1b", "constant": "#aa5500", "heading": "#644a9b", "link": "#0095ff", "list": "#bf0303", "quote": "#898887", "meta": "#898887", "mark": "#644a9b", "invalid": "#bf0303", "active-line-bg": "#f8f7f6", "selection-bg": "rgba(148, 202, 239, 0.6)", "selection-match-bg": "rgba(0, 0, 0, 0.05)" };
|
|
16511
|
+
const breezeLight = {
|
|
16482
16512
|
$schema: $schema$3,
|
|
16483
16513
|
name: name$5,
|
|
16484
16514
|
kind: kind$3,
|
|
@@ -16487,12 +16517,12 @@ const gruvbox = {
|
|
|
16487
16517
|
syntax: syntax$3
|
|
16488
16518
|
};
|
|
16489
16519
|
const $schema$2 = "pi-theme/v1";
|
|
16490
|
-
const name$4 = "Breeze
|
|
16520
|
+
const name$4 = "Breeze Claudius";
|
|
16491
16521
|
const kind$2 = "dark";
|
|
16492
16522
|
const seeds$2 = { "app": "#232629", "surface": "#31363b", "text": "#cfcfc2", "accent": "#2980b9", "success": "#1c8042", "warning": "#fdbc4b", "error": "#da4453" };
|
|
16493
|
-
const overrides$3 = { "surface-hover": "#3f4347", "card": "#3f4347", "elevated": "#4d5358", "highlight": "#31363b", "highlight-strong": "#3f4347", "secondary": "#a5a6a8", "muted": "#898a8c", "dim": "#7a7c7d", "faint": "#5f6266", "ghost": "#4d5358", "inverse": "#232629", "border": "#3f4347", "border-strong": "#4d5358", "focus": "#3daee9", "accent-hover": "#3daee9", "accent-fg": "#3daee9", "accent-bg": "rgba(45, 92, 118, 0.5)", "success-bg": "rgba(28, 128, 66, 0.15)", "warning-bg": "rgba(246, 116, 0, 0.15)", "error-bg": "rgba(218, 68, 83, 0.15)", "info": "#3daee9", "info-bg": "rgba(45, 92, 118, 0.5)", "special": "#8e44ad", "special-bg": "rgba(142, 68, 173, 0.15)", "chat-column": "#
|
|
16523
|
+
const overrides$3 = { "surface-hover": "#3f4347", "card": "#3f4347", "elevated": "#4d5358", "highlight": "#31363b", "highlight-strong": "#3f4347", "secondary": "#a5a6a8", "muted": "#898a8c", "dim": "#7a7c7d", "faint": "#5f6266", "ghost": "#4d5358", "inverse": "#232629", "border": "#3f4347", "border-strong": "#4d5358", "focus": "#3daee9", "accent-hover": "#3daee9", "accent-fg": "#3daee9", "accent-bg": "rgba(45, 92, 118, 0.5)", "success-bg": "rgba(28, 128, 66, 0.15)", "warning-bg": "rgba(246, 116, 0, 0.15)", "error-bg": "rgba(218, 68, 83, 0.15)", "info": "#3daee9", "info-bg": "rgba(45, 92, 118, 0.5)", "special": "#8e44ad", "special-bg": "rgba(142, 68, 173, 0.15)", "chat-column": "#1e1e1e", "chat-column-border": "transparent", "scrollbar": "#3f4347", "scrollbar-hover": "#4d5358", "md-code": "#60a5fa", "md-pre-bg": "#1d2024" };
|
|
16494
16524
|
const syntax$2 = { "keyword": "#fdbc4b", "string": "#f44f4f", "comment": "#7a7c7d", "function": "#8e44ad", "type": "#2980b9", "number": "#f67400", "operator": "#3f8058", "property": "#27aeae", "tag": "#2980b9", "variable": "#cfcfc2", "constant": "#27aeae", "heading": "#8e44ad", "link": "#0099ff", "list": "#da4453", "quote": "#7a7c7d", "meta": "#a5a6a8", "mark": "#8e44ad", "invalid": "#da4453", "active-line-bg": "#2A2E32", "selection-bg": "rgba(45, 92, 118, 0.65)", "selection-match-bg": "rgba(65, 72, 87, 0.5)" };
|
|
16495
|
-
const
|
|
16525
|
+
const breezeClaudius = {
|
|
16496
16526
|
$schema: $schema$2,
|
|
16497
16527
|
name: name$4,
|
|
16498
16528
|
kind: kind$2,
|
|
@@ -16501,34 +16531,44 @@ const breezeDark = {
|
|
|
16501
16531
|
syntax: syntax$2
|
|
16502
16532
|
};
|
|
16503
16533
|
const $schema$1 = "pi-theme/v1";
|
|
16504
|
-
const name$3 = "
|
|
16505
|
-
const kind$1 = "
|
|
16506
|
-
const
|
|
16507
|
-
const
|
|
16508
|
-
const
|
|
16509
|
-
const
|
|
16534
|
+
const name$3 = "Sessrúmnir";
|
|
16535
|
+
const kind$1 = "dark";
|
|
16536
|
+
const author$1 = "Ymir";
|
|
16537
|
+
const description$1 = "The seat's own cloth — the carved stone, bone, bronze and blood of the landing page. The default look of the seat; a user theme chosen still wins over it.";
|
|
16538
|
+
const seeds$1 = { "app": "#0e0c09", "surface": "#151209", "text": "#cfc3a9", "accent": "#c9973f", "success": "#96a0a8", "warning": "#c9973f", "error": "#c2584a" };
|
|
16539
|
+
const overrides$2 = { "app": "#0e0c09", "surface": "#151209", "surface-hover": "#1a1610", "card": "#151209", "elevated": "#1a1610", "highlight": "#14100b", "highlight-strong": "#1a1610", "primary": "#cfc3a9", "secondary": "rgba(207, 195, 169, 0.82)", "muted": "#9a8f75", "dim": "#6b6250", "faint": "rgba(207, 195, 169, 0.38)", "ghost": "rgba(207, 195, 169, 0.26)", "inverse": "#0e0c09", "border": "#2b241a", "border-strong": "#7d5f2a", "border-strong-hover": "#c9973f", "focus": "#c9973f", "accent": "#c9973f", "accent-hover": "#7d5f2a", "accent-fg": "#cfc3a9", "accent-bg": "rgba(201, 151, 79, 0.14)", "success": "#96a0a8", "success-bg": "rgba(150, 160, 168, 0.14)", "warning": "#c9973f", "warning-bg": "rgba(201, 151, 79, 0.18)", "error": "#c2584a", "error-hover": "#7c3a30", "error-bg": "rgba(124, 58, 48, 0.24)", "info": "#9a8f75", "info-bg": "rgba(154, 143, 117, 0.14)", "special": "#7d5f2a", "special-bg": "rgba(125, 95, 42, 0.18)", "chat-column": "#0e0c09", "chat-column-border": "#2b241a", "scrollbar": "#2b241a", "scrollbar-hover": "#7d5f2a", "md-code": "#c9973f", "md-pre-bg": "#14100b", "selection-bg": "#57411a", "selection-fg": "#f0e6cd" };
|
|
16540
|
+
const syntax$1 = { "keyword": "#c9973f", "string": "#96a0a8", "comment": "#6b6250", "function": "#cfc3a9", "type": "#9a8f75", "number": "#c2584a", "operator": "#9a8f75", "property": "#96a0a8", "tag": "#c2584a", "variable": "#cfc3a9", "constant": "#c9973f", "heading": "#cfc3a9", "link": "#c9973f", "list": "#c2584a", "quote": "#9a8f75", "meta": "#6b6250", "mark": "#c9973f", "invalid": "#c2584a", "active-line-bg": "rgba(207, 195, 169, 0.04)", "selection-bg": "#57411a", "selection-match-bg": "rgba(207, 195, 169, 0.08)" };
|
|
16541
|
+
const sessrumnir = {
|
|
16510
16542
|
$schema: $schema$1,
|
|
16511
16543
|
name: name$3,
|
|
16512
16544
|
kind: kind$1,
|
|
16545
|
+
author: author$1,
|
|
16546
|
+
description: description$1,
|
|
16513
16547
|
seeds: seeds$1,
|
|
16514
16548
|
overrides: overrides$2,
|
|
16515
16549
|
syntax: syntax$1
|
|
16516
16550
|
};
|
|
16517
16551
|
const $schema = "pi-theme/v1";
|
|
16518
|
-
const name$2 = "
|
|
16552
|
+
const name$2 = "Fensalir";
|
|
16519
16553
|
const kind = "dark";
|
|
16520
|
-
const
|
|
16521
|
-
const
|
|
16522
|
-
const
|
|
16523
|
-
const
|
|
16554
|
+
const author = "Ymir";
|
|
16555
|
+
const description = "Fensalir — the weaving halls: the carved cloth of the halls, taken whole from the landing page's stone, bone, bronze and blood. The default cloth of the seat; any user theme chosen still wins over it.";
|
|
16556
|
+
const seeds = { "app": "#0e0c09", "surface": "#151209", "text": "#cfc3a9", "accent": "#c9973f", "success": "#96a0a8", "warning": "#c9973f", "error": "#c2584a" };
|
|
16557
|
+
const overrides$1 = { "app": "#0e0c09", "surface": "#151209", "surface-hover": "#1a1610", "card": "#151209", "elevated": "#1a1610", "highlight": "#14100b", "highlight-strong": "#1a1610", "primary": "#cfc3a9", "secondary": "rgba(207, 195, 169, 0.82)", "muted": "#9a8f75", "dim": "#6b6250", "faint": "rgba(207, 195, 169, 0.38)", "ghost": "rgba(207, 195, 169, 0.26)", "inverse": "#0e0c09", "border": "#2b241a", "border-strong": "#7d5f2a", "border-strong-hover": "#c9973f", "focus": "#c9973f", "accent": "#c9973f", "accent-hover": "#7d5f2a", "accent-fg": "#cfc3a9", "accent-bg": "rgba(201, 151, 79, 0.14)", "success": "#96a0a8", "success-bg": "rgba(150, 160, 168, 0.14)", "warning": "#c9973f", "warning-bg": "rgba(201, 151, 79, 0.18)", "error": "#c2584a", "error-hover": "#7c3a30", "error-bg": "rgba(124, 58, 48, 0.24)", "info": "#9a8f75", "info-bg": "rgba(154, 143, 117, 0.14)", "special": "#7d5f2a", "special-bg": "rgba(125, 95, 42, 0.18)", "chat-column": "#0e0c09", "chat-column-border": "#2b241a", "scrollbar": "#2b241a", "scrollbar-hover": "#7d5f2a", "md-code": "#c9973f", "md-pre-bg": "#14100b", "selection-bg": "#57411a", "selection-fg": "#f0e6cd" };
|
|
16558
|
+
const syntax = { "keyword": "#c9973f", "string": "#96a0a8", "comment": "#6b6250", "function": "#cfc3a9", "type": "#9a8f75", "number": "#c2584a", "operator": "#9a8f75", "property": "#96a0a8", "tag": "#c2584a", "variable": "#cfc3a9", "constant": "#c9973f", "heading": "#cfc3a9", "link": "#c9973f", "list": "#c2584a", "quote": "#9a8f75", "meta": "#6b6250", "mark": "#c9973f", "invalid": "#c2584a", "active-line-bg": "rgba(207, 195, 169, 0.04)", "selection-bg": "#57411a", "selection-match-bg": "rgba(207, 195, 169, 0.08)" };
|
|
16559
|
+
const fensalir = {
|
|
16524
16560
|
$schema,
|
|
16525
16561
|
name: name$2,
|
|
16526
16562
|
kind,
|
|
16563
|
+
author,
|
|
16564
|
+
description,
|
|
16527
16565
|
seeds,
|
|
16528
16566
|
overrides: overrides$1,
|
|
16529
16567
|
syntax
|
|
16530
16568
|
};
|
|
16531
16569
|
const BUILTIN_THEMES = [
|
|
16570
|
+
{ id: "sessrumnir", file: sessrumnir },
|
|
16571
|
+
{ id: "fensalir", file: fensalir },
|
|
16532
16572
|
{ id: "dark", file: dark },
|
|
16533
16573
|
{ id: "light", file: light },
|
|
16534
16574
|
{ id: "nord", file: nord },
|
|
@@ -16548,7 +16588,9 @@ const BUILTIN_THEME_NAME_KEYS = {
|
|
|
16548
16588
|
gruvbox: "themes.builtin.gruvbox",
|
|
16549
16589
|
"breeze-dark": "themes.builtin.breeze-dark",
|
|
16550
16590
|
"breeze-light": "themes.builtin.breeze-light",
|
|
16551
|
-
"breeze-claudius": "themes.builtin.breeze-claudius"
|
|
16591
|
+
"breeze-claudius": "themes.builtin.breeze-claudius",
|
|
16592
|
+
sessrumnir: "themes.builtin.sessrumnir",
|
|
16593
|
+
fensalir: "themes.builtin.fensalir"
|
|
16552
16594
|
};
|
|
16553
16595
|
function themeDisplayName(id2, fileName) {
|
|
16554
16596
|
return isBuiltinThemeId(id2) ? t$1(BUILTIN_THEME_NAME_KEYS[id2]) : fileName;
|
|
@@ -18056,7 +18098,7 @@ const useAppStore = create$1((set, get2) => ({
|
|
|
18056
18098
|
rememberBootTheme(settings2);
|
|
18057
18099
|
watchSystemTheme(() => {
|
|
18058
18100
|
const state = get2();
|
|
18059
|
-
return state.settingsDraft.theme ?? state.settings?.theme ?? "
|
|
18101
|
+
return state.settingsDraft.theme ?? state.settings?.theme ?? "fensalir";
|
|
18060
18102
|
});
|
|
18061
18103
|
document.documentElement.style.fontSize = `${settings2.fontSize}px`;
|
|
18062
18104
|
await applyLanguageSetting(settings2.language);
|
|
@@ -21230,7 +21272,7 @@ function StatusPopover() {
|
|
|
21230
21272
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-2 border-t border-border flex items-center justify-between text-[10px] text-faint", children: [
|
|
21231
21273
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
21232
21274
|
"v",
|
|
21233
|
-
"0.1.
|
|
21275
|
+
"0.1.16"
|
|
21234
21276
|
] }),
|
|
21235
21277
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
21236
21278
|
"button",
|
|
@@ -90323,8 +90365,8 @@ function CustomModelsEditor() {
|
|
|
90323
90365
|
function forkTheme(base2, newName) {
|
|
90324
90366
|
return { ...structuredClone(base2), name: newName };
|
|
90325
90367
|
}
|
|
90326
|
-
function withSeed(theme2,
|
|
90327
|
-
return { ...theme2, seeds: { ...theme2.seeds, [
|
|
90368
|
+
function withSeed(theme2, seed2, value) {
|
|
90369
|
+
return { ...theme2, seeds: { ...theme2.seeds, [seed2]: value } };
|
|
90328
90370
|
}
|
|
90329
90371
|
function withOverride(theme2, token, value) {
|
|
90330
90372
|
const overrides2 = { ...theme2.overrides };
|
|
@@ -90369,7 +90411,7 @@ function tokenLabel(name2) {
|
|
|
90369
90411
|
return name2.replace(/-/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
|
|
90370
90412
|
}
|
|
90371
90413
|
function resolveSettingsThemeId(state) {
|
|
90372
|
-
return state.settingsDraft.theme ?? state.settings?.theme ?? "
|
|
90414
|
+
return state.settingsDraft.theme ?? state.settings?.theme ?? "fensalir";
|
|
90373
90415
|
}
|
|
90374
90416
|
function ThemeEditor({
|
|
90375
90417
|
baseTheme: baseTheme2,
|
|
@@ -90430,9 +90472,9 @@ function ThemeEditor({
|
|
|
90430
90472
|
setSaving(true);
|
|
90431
90473
|
setSaveError(null);
|
|
90432
90474
|
try {
|
|
90433
|
-
const { author, description, ...rest } = draft;
|
|
90434
|
-
const trimmedAuthor =
|
|
90435
|
-
const trimmedDescription =
|
|
90475
|
+
const { author: author2, description: description2, ...rest } = draft;
|
|
90476
|
+
const trimmedAuthor = author2?.trim();
|
|
90477
|
+
const trimmedDescription = description2?.trim();
|
|
90436
90478
|
const payload = {
|
|
90437
90479
|
...rest,
|
|
90438
90480
|
...trimmedAuthor ? { author: trimmedAuthor } : {},
|
|
@@ -90544,16 +90586,16 @@ function ThemeEditor({
|
|
|
90544
90586
|
)
|
|
90545
90587
|
] })
|
|
90546
90588
|
] }),
|
|
90547
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: SEED_NAMES.map((
|
|
90548
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-sm text-primary", htmlFor: `theme-editor-seed-${
|
|
90589
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: SEED_NAMES.map((seed2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
90590
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-sm text-primary", htmlFor: `theme-editor-seed-${seed2}`, children: t2(SEED_LABEL_KEYS[seed2]) }),
|
|
90549
90591
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
90550
90592
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
90551
90593
|
"input",
|
|
90552
90594
|
{
|
|
90553
|
-
id: `theme-editor-seed-${
|
|
90595
|
+
id: `theme-editor-seed-${seed2}`,
|
|
90554
90596
|
type: "color",
|
|
90555
|
-
value: normalizeHexColor(draft.seeds[
|
|
90556
|
-
onChange: (event) => preview(withSeed(draft,
|
|
90597
|
+
value: normalizeHexColor(draft.seeds[seed2]),
|
|
90598
|
+
onChange: (event) => preview(withSeed(draft, seed2, event.target.value)),
|
|
90557
90599
|
className: "h-8 w-10 cursor-pointer rounded border border-border-strong bg-surface p-0.5"
|
|
90558
90600
|
}
|
|
90559
90601
|
),
|
|
@@ -90561,14 +90603,14 @@ function ThemeEditor({
|
|
|
90561
90603
|
"input",
|
|
90562
90604
|
{
|
|
90563
90605
|
type: "text",
|
|
90564
|
-
value: draft.seeds[
|
|
90565
|
-
onChange: (event) => preview(withSeed(draft,
|
|
90606
|
+
value: draft.seeds[seed2],
|
|
90607
|
+
onChange: (event) => preview(withSeed(draft, seed2, event.target.value)),
|
|
90566
90608
|
maxLength: HEX_TEXT_INPUT_MAX_LENGTH,
|
|
90567
90609
|
className: "w-28 rounded-md border border-border-strong bg-surface px-2 py-1 text-xs font-mono text-primary focus:border-focus focus:outline-none"
|
|
90568
90610
|
}
|
|
90569
90611
|
)
|
|
90570
90612
|
] })
|
|
90571
|
-
] },
|
|
90613
|
+
] }, seed2)) }),
|
|
90572
90614
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("details", { className: "rounded-md border border-border", children: [
|
|
90573
90615
|
/* @__PURE__ */ jsxRuntimeExports.jsx("summary", { className: "cursor-pointer select-none px-3 py-2 text-sm text-secondary", children: t2("themes.editor.advancedSummary") }),
|
|
90574
90616
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1 border-t border-border px-3 py-2", children: ADVANCED_TOKENS.map((token) => {
|
|
@@ -91999,7 +92041,7 @@ function SettingsSection({
|
|
|
91999
92041
|
}
|
|
92000
92042
|
function SettingsRow({
|
|
92001
92043
|
label,
|
|
92002
|
-
description,
|
|
92044
|
+
description: description2,
|
|
92003
92045
|
children,
|
|
92004
92046
|
stack = false
|
|
92005
92047
|
}) {
|
|
@@ -92007,7 +92049,7 @@ function SettingsRow({
|
|
|
92007
92049
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
92008
92050
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
92009
92051
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-primary", children: label }),
|
|
92010
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-dim", children:
|
|
92052
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-dim", children: description2 })
|
|
92011
92053
|
] }),
|
|
92012
92054
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { children })
|
|
92013
92055
|
] });
|
|
@@ -92015,7 +92057,7 @@ function SettingsRow({
|
|
|
92015
92057
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-4", children: [
|
|
92016
92058
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
92017
92059
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-primary", children: label }),
|
|
92018
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-dim", children:
|
|
92060
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-dim", children: description2 })
|
|
92019
92061
|
] }),
|
|
92020
92062
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-64", children })
|
|
92021
92063
|
] });
|
|
@@ -97025,6 +97067,155 @@ function useFolderDrop() {
|
|
|
97025
97067
|
}, []);
|
|
97026
97068
|
return { isDraggingFolder };
|
|
97027
97069
|
}
|
|
97070
|
+
const EMBERS = 30;
|
|
97071
|
+
const HAZE = 6;
|
|
97072
|
+
const EMBER_RGB = "236,166,84";
|
|
97073
|
+
const HAZE_RGB = "214,138,64";
|
|
97074
|
+
function paint(ctx, W, H, embers, haze) {
|
|
97075
|
+
ctx.clearRect(0, 0, W, H);
|
|
97076
|
+
for (const ha of haze) {
|
|
97077
|
+
const g = ctx.createRadialGradient(ha.x, ha.y, 0, ha.x, ha.y, ha.r);
|
|
97078
|
+
g.addColorStop(0, `rgba(${HAZE_RGB},0.030)`);
|
|
97079
|
+
g.addColorStop(1, "rgba(0,0,0,0)");
|
|
97080
|
+
ctx.fillStyle = g;
|
|
97081
|
+
ctx.beginPath();
|
|
97082
|
+
ctx.arc(ha.x, ha.y, ha.r, 0, 6.283);
|
|
97083
|
+
ctx.fill();
|
|
97084
|
+
}
|
|
97085
|
+
for (const e of embers) {
|
|
97086
|
+
ctx.fillStyle = `rgba(${EMBER_RGB},${e.a.toFixed(3)})`;
|
|
97087
|
+
ctx.beginPath();
|
|
97088
|
+
ctx.arc(e.x, e.y, e.r, 0, 6.283);
|
|
97089
|
+
ctx.fill();
|
|
97090
|
+
}
|
|
97091
|
+
}
|
|
97092
|
+
function seed(W, H) {
|
|
97093
|
+
const embers = [];
|
|
97094
|
+
for (let i = 0; i < EMBERS; i++) {
|
|
97095
|
+
embers.push({
|
|
97096
|
+
x: Math.random() * W,
|
|
97097
|
+
y: H + Math.random() * H * 0.3 - 6,
|
|
97098
|
+
r: 1 + Math.random() * 1.6,
|
|
97099
|
+
v: 0.14 + Math.random() * 0.34,
|
|
97100
|
+
ph: Math.random() * 6.28,
|
|
97101
|
+
sp: 0.6 + Math.random() * 1.4,
|
|
97102
|
+
a: 0.26
|
|
97103
|
+
});
|
|
97104
|
+
}
|
|
97105
|
+
const haze = [];
|
|
97106
|
+
for (let i = 0; i < HAZE; i++) {
|
|
97107
|
+
haze.push({ x: Math.random() * W, y: H * 0.3 + Math.random() * H * 0.7, r: 130 + Math.random() * 170, v: (Math.random() - 0.5) * 0.15 });
|
|
97108
|
+
}
|
|
97109
|
+
return { embers, haze };
|
|
97110
|
+
}
|
|
97111
|
+
function startEmbers(host) {
|
|
97112
|
+
if (!host) return () => {
|
|
97113
|
+
};
|
|
97114
|
+
const canvas = host.tagName === "CANVAS" ? host : document.createElement("canvas");
|
|
97115
|
+
if (canvas !== host) {
|
|
97116
|
+
canvas.style.position = "absolute";
|
|
97117
|
+
canvas.style.inset = "0";
|
|
97118
|
+
host.appendChild(canvas);
|
|
97119
|
+
}
|
|
97120
|
+
canvas.setAttribute("aria-hidden", "true");
|
|
97121
|
+
canvas.style.pointerEvents = "none";
|
|
97122
|
+
const ctx = canvas.getContext("2d");
|
|
97123
|
+
if (!ctx) return () => {
|
|
97124
|
+
};
|
|
97125
|
+
const dpr = Math.min(window.devicePixelRatio || 1, 2);
|
|
97126
|
+
let W = 0;
|
|
97127
|
+
let H = 0;
|
|
97128
|
+
let t2 = 0;
|
|
97129
|
+
let raf = 0;
|
|
97130
|
+
let { embers, haze } = seed(1, 1);
|
|
97131
|
+
const reduced = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches === true;
|
|
97132
|
+
function size() {
|
|
97133
|
+
const rect = canvas.getBoundingClientRect();
|
|
97134
|
+
W = rect.width || canvas.clientWidth || 0;
|
|
97135
|
+
H = rect.height || canvas.clientHeight || 0;
|
|
97136
|
+
canvas.width = Math.max(1, W * dpr);
|
|
97137
|
+
canvas.height = Math.max(1, H * dpr);
|
|
97138
|
+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
97139
|
+
}
|
|
97140
|
+
function reseed() {
|
|
97141
|
+
({ embers, haze } = seed(W, H));
|
|
97142
|
+
if (reduced) {
|
|
97143
|
+
for (const e of embers) e.a = 0.3 + 0.4 * Math.random();
|
|
97144
|
+
paint(ctx, W, H, embers, haze);
|
|
97145
|
+
}
|
|
97146
|
+
}
|
|
97147
|
+
function frame() {
|
|
97148
|
+
t2 += 0.016;
|
|
97149
|
+
for (const ha of haze) {
|
|
97150
|
+
ha.x += ha.v;
|
|
97151
|
+
if (ha.x < -ha.r) ha.x = W + ha.r;
|
|
97152
|
+
if (ha.x > W + ha.r) ha.x = -ha.r;
|
|
97153
|
+
}
|
|
97154
|
+
for (const e of embers) {
|
|
97155
|
+
e.y -= e.v;
|
|
97156
|
+
e.x += Math.sin(t2 * e.sp + e.ph) * 0.18;
|
|
97157
|
+
if (e.y < -6) {
|
|
97158
|
+
e.y = H + 6;
|
|
97159
|
+
e.x = Math.random() * W;
|
|
97160
|
+
}
|
|
97161
|
+
e.a = 0.26 + 0.4 * (0.5 + 0.5 * Math.sin(t2 * e.sp * 2 + e.ph));
|
|
97162
|
+
}
|
|
97163
|
+
paint(ctx, W, H, embers, haze);
|
|
97164
|
+
}
|
|
97165
|
+
function loop() {
|
|
97166
|
+
frame();
|
|
97167
|
+
raf = requestAnimationFrame(loop);
|
|
97168
|
+
}
|
|
97169
|
+
size();
|
|
97170
|
+
reseed();
|
|
97171
|
+
if (!reduced) raf = requestAnimationFrame(loop);
|
|
97172
|
+
const onResize = () => {
|
|
97173
|
+
size();
|
|
97174
|
+
reseed();
|
|
97175
|
+
};
|
|
97176
|
+
window.addEventListener("resize", onResize);
|
|
97177
|
+
let ro = null;
|
|
97178
|
+
if (typeof ResizeObserver !== "undefined" && canvas.parentElement) {
|
|
97179
|
+
const host2 = canvas.parentElement;
|
|
97180
|
+
let lastW = 0;
|
|
97181
|
+
let lastH = 0;
|
|
97182
|
+
ro = new ResizeObserver((entries) => {
|
|
97183
|
+
const e = entries[0];
|
|
97184
|
+
if (!e) return;
|
|
97185
|
+
const w = e.contentRect?.width ?? e.contentBoxSize?.[0]?.inlineSize ?? 0;
|
|
97186
|
+
const h = e.contentRect?.height ?? e.contentBoxSize?.[0]?.blockSize ?? 0;
|
|
97187
|
+
if (Math.abs(w - lastW) > 0.5 || Math.abs(h - lastH) > 0.5) {
|
|
97188
|
+
lastW = w;
|
|
97189
|
+
lastH = h;
|
|
97190
|
+
onResize();
|
|
97191
|
+
}
|
|
97192
|
+
});
|
|
97193
|
+
ro.observe(host2);
|
|
97194
|
+
}
|
|
97195
|
+
return () => {
|
|
97196
|
+
if (raf) cancelAnimationFrame(raf);
|
|
97197
|
+
window.removeEventListener("resize", onResize);
|
|
97198
|
+
if (ro) ro.disconnect();
|
|
97199
|
+
};
|
|
97200
|
+
}
|
|
97201
|
+
function startAllEmbers(root2 = document) {
|
|
97202
|
+
return Array.from(root2.querySelectorAll("[data-ember]")).map(startEmbers);
|
|
97203
|
+
}
|
|
97204
|
+
if (typeof document !== "undefined") {
|
|
97205
|
+
const boot = () => startAllEmbers();
|
|
97206
|
+
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", boot, { once: true });
|
|
97207
|
+
else boot();
|
|
97208
|
+
}
|
|
97209
|
+
function EmberBackground() {
|
|
97210
|
+
const ref = reactExports.useRef(null);
|
|
97211
|
+
reactExports.useEffect(() => {
|
|
97212
|
+
const el = ref.current;
|
|
97213
|
+
if (!el) return;
|
|
97214
|
+
const stop = startEmbers(el);
|
|
97215
|
+
return () => stop?.();
|
|
97216
|
+
}, []);
|
|
97217
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("canvas", { ref, className: "ember-bg", "data-ember": true, "aria-hidden": "true" });
|
|
97218
|
+
}
|
|
97028
97219
|
function App() {
|
|
97029
97220
|
const { t: t2 } = useTranslation();
|
|
97030
97221
|
usePiEvents();
|
|
@@ -97071,6 +97262,7 @@ function App() {
|
|
|
97071
97262
|
const showUpdateBanner = !!updateInfo?.updateAvailable && !updateDismissed;
|
|
97072
97263
|
const globalWorkflowOpen = showChrome && workflowPanelOpen && !workflowPanelFilter && workflowPanelWorkspaceId === null;
|
|
97073
97264
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex h-screen flex-col bg-app text-primary", children: [
|
|
97265
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(EmberBackground, {}),
|
|
97074
97266
|
isDraggingFolder && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
97075
97267
|
"div",
|
|
97076
97268
|
{
|
package/out/renderer/index.html
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
<link rel="icon" type="image/svg+xml" href="./assets/pi-logo-B48rElrT.svg" />
|
|
11
11
|
<title>Sessrúmnir</title>
|
|
12
12
|
<script src="./theme-boot.js"></script>
|
|
13
|
-
<script type="module" crossorigin src="./assets/index-
|
|
14
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
13
|
+
<script type="module" crossorigin src="./assets/index-DbCaU2eq.js"></script>
|
|
14
|
+
<link rel="stylesheet" crossorigin href="./assets/index-DL2o01yM.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body class="bg-app text-primary antialiased">
|
|
17
17
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zerwiz/sessrumnir",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "Desktop GUI frontend for the Pi coding agent",
|
|
5
5
|
"main": "out/main/index.js",
|
|
6
6
|
"desktopName": "pi-desktop.desktop",
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
"package:win": "electron-vite build && electron-builder --win",
|
|
40
40
|
"package:win:nsis": "electron-vite build && electron-builder --win nsis",
|
|
41
41
|
"package:win:portable": "electron-vite build && electron-builder --win portable",
|
|
42
|
-
"package:all": "electron-vite build && electron-builder --linux --mac --win"
|
|
42
|
+
"package:all": "electron-vite build && electron-builder --linux --mac --win",
|
|
43
|
+
"prepublishOnly": "npm run build"
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
45
46
|
"@codemirror/lang-cpp": "^6.0.3",
|
|
@@ -163,5 +164,6 @@
|
|
|
163
164
|
"artifactName": "Pi-Desktop-${version}-${os}-${arch}-setup.${ext}"
|
|
164
165
|
}
|
|
165
166
|
},
|
|
166
|
-
"productName": "Sessr\u00famnir"
|
|
167
|
+
"productName": "Sessr\u00famnir",
|
|
168
|
+
"private": false
|
|
167
169
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/renderer/src/app.tsx
CHANGED
|
@@ -26,6 +26,8 @@ import { useAppStore } from './store'
|
|
|
26
26
|
import { useEffect } from 'react'
|
|
27
27
|
import { ArrowUpCircle, FolderOpen, PanelLeft, X } from 'lucide-react'
|
|
28
28
|
|
|
29
|
+
import EmberBackground from './components/EmberBackground'
|
|
30
|
+
|
|
29
31
|
export function App(): React.JSX.Element {
|
|
30
32
|
const { t } = useTranslation()
|
|
31
33
|
usePiEvents()
|
|
@@ -95,6 +97,7 @@ export function App(): React.JSX.Element {
|
|
|
95
97
|
|
|
96
98
|
return (
|
|
97
99
|
<div className="relative flex h-screen flex-col bg-app text-primary">
|
|
100
|
+
<EmberBackground />
|
|
98
101
|
{isDraggingFolder && (
|
|
99
102
|
<div
|
|
100
103
|
className="pointer-events-none absolute inset-0 z-[100] flex items-center justify-center bg-app/80 backdrop-blur-sm"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type declarations for the shared hearth (ember.js).
|
|
3
|
+
*
|
|
4
|
+
* The implementation is plain JS so any surface — React, Vue, Astro, or a bare
|
|
5
|
+
* page — can import the same fire. These types keep TypeScript consumers honest
|
|
6
|
+
* without forcing the module itself into a build step.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** Start the hearth on <host> (a canvas, or an element to receive one). Returns a stop function. */
|
|
10
|
+
export function startEmbers(host: Element | null): () => void;
|
|
11
|
+
|
|
12
|
+
/** Light every element marked `data-ember`. Returns one stop function per hearth. */
|
|
13
|
+
export function startAllEmbers(root?: ParentNode): Array<() => void>;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ember.js — the hearth, in one place.
|
|
3
|
+
*
|
|
4
|
+
* The fire that warms Sessrúmnir's chat came from the landing page's hero
|
|
5
|
+
* (Ginnungagap): embers rising slowly with a gentle sway, over a few drifting
|
|
6
|
+
* haze pools. Sessrúmnir carries a React port; this is the framework-neutral
|
|
7
|
+
* original, so every surface can share one fire instead of four copies.
|
|
8
|
+
*
|
|
9
|
+
* import { startEmbers } from '.../midgard/design-system/ember.js'
|
|
10
|
+
* const stop = startEmbers(document.querySelector('[data-ember]'))
|
|
11
|
+
*
|
|
12
|
+
* Or simply mark an element and let it find its own:
|
|
13
|
+
*
|
|
14
|
+
* <canvas data-ember></canvas>
|
|
15
|
+
* <script type="module" src="/ember.js"></script>
|
|
16
|
+
*
|
|
17
|
+
* It is decorative: the canvas is given `pointer-events: none` and
|
|
18
|
+
* `aria-hidden`, and a reader who has asked their machine for less motion gets a
|
|
19
|
+
* still, single-frame hearth instead of an animation.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const EMBERS = 30;
|
|
23
|
+
const HAZE = 6;
|
|
24
|
+
const EMBER_RGB = '236,166,84';
|
|
25
|
+
const HAZE_RGB = '214,138,64';
|
|
26
|
+
|
|
27
|
+
/** Draw one still frame — also the whole effect under reduced motion. */
|
|
28
|
+
function paint(ctx, W, H, embers, haze) {
|
|
29
|
+
ctx.clearRect(0, 0, W, H);
|
|
30
|
+
for (const ha of haze) {
|
|
31
|
+
const g = ctx.createRadialGradient(ha.x, ha.y, 0, ha.x, ha.y, ha.r);
|
|
32
|
+
g.addColorStop(0, `rgba(${HAZE_RGB},0.030)`);
|
|
33
|
+
g.addColorStop(1, 'rgba(0,0,0,0)');
|
|
34
|
+
ctx.fillStyle = g;
|
|
35
|
+
ctx.beginPath();
|
|
36
|
+
ctx.arc(ha.x, ha.y, ha.r, 0, 6.283);
|
|
37
|
+
ctx.fill();
|
|
38
|
+
}
|
|
39
|
+
for (const e of embers) {
|
|
40
|
+
ctx.fillStyle = `rgba(${EMBER_RGB},${e.a.toFixed(3)})`;
|
|
41
|
+
ctx.beginPath();
|
|
42
|
+
ctx.arc(e.x, e.y, e.r, 0, 6.283);
|
|
43
|
+
ctx.fill();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function seed(W, H) {
|
|
48
|
+
const embers = [];
|
|
49
|
+
for (let i = 0; i < EMBERS; i++) {
|
|
50
|
+
embers.push({
|
|
51
|
+
x: Math.random() * W,
|
|
52
|
+
y: H + Math.random() * H * 0.3 - 6,
|
|
53
|
+
r: 1.0 + Math.random() * 1.6,
|
|
54
|
+
v: 0.14 + Math.random() * 0.34,
|
|
55
|
+
ph: Math.random() * 6.28,
|
|
56
|
+
sp: 0.6 + Math.random() * 1.4,
|
|
57
|
+
a: 0.26,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const haze = [];
|
|
61
|
+
for (let i = 0; i < HAZE; i++) {
|
|
62
|
+
haze.push({ x: Math.random() * W, y: H * 0.3 + Math.random() * H * 0.7, r: 130 + Math.random() * 170, v: (Math.random() - 0.5) * 0.15 });
|
|
63
|
+
}
|
|
64
|
+
return { embers, haze };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Start the hearth on <host>. Returns a stop function. Safe to call on a host
|
|
69
|
+
* that has no box yet (it simply draws nothing until it has one).
|
|
70
|
+
*/
|
|
71
|
+
export function startEmbers(host) {
|
|
72
|
+
if (!host) return () => {};
|
|
73
|
+
const canvas = host.tagName === 'CANVAS' ? host : document.createElement('canvas');
|
|
74
|
+
if (canvas !== host) {
|
|
75
|
+
canvas.style.position = 'absolute';
|
|
76
|
+
canvas.style.inset = '0';
|
|
77
|
+
host.appendChild(canvas);
|
|
78
|
+
}
|
|
79
|
+
canvas.setAttribute('aria-hidden', 'true');
|
|
80
|
+
canvas.style.pointerEvents = 'none';
|
|
81
|
+
|
|
82
|
+
const ctx = canvas.getContext('2d');
|
|
83
|
+
if (!ctx) return () => {};
|
|
84
|
+
|
|
85
|
+
const dpr = Math.min(window.devicePixelRatio || 1, 2);
|
|
86
|
+
let W = 0;
|
|
87
|
+
let H = 0;
|
|
88
|
+
let t = 0;
|
|
89
|
+
let raf = 0;
|
|
90
|
+
let { embers, haze } = seed(1, 1);
|
|
91
|
+
|
|
92
|
+
const reduced = window.matchMedia?.('(prefers-reduced-motion: reduce)').matches === true;
|
|
93
|
+
|
|
94
|
+
function size() {
|
|
95
|
+
const rect = canvas.getBoundingClientRect();
|
|
96
|
+
W = rect.width || canvas.clientWidth || 0;
|
|
97
|
+
H = rect.height || canvas.clientHeight || 0;
|
|
98
|
+
canvas.width = Math.max(1, W * dpr);
|
|
99
|
+
canvas.height = Math.max(1, H * dpr);
|
|
100
|
+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function reseed() {
|
|
104
|
+
({ embers, haze } = seed(W, H));
|
|
105
|
+
if (reduced) {
|
|
106
|
+
for (const e of embers) e.a = 0.3 + 0.4 * Math.random();
|
|
107
|
+
paint(ctx, W, H, embers, haze);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function frame() {
|
|
112
|
+
t += 0.016;
|
|
113
|
+
for (const ha of haze) {
|
|
114
|
+
ha.x += ha.v;
|
|
115
|
+
if (ha.x < -ha.r) ha.x = W + ha.r;
|
|
116
|
+
if (ha.x > W + ha.r) ha.x = -ha.r;
|
|
117
|
+
}
|
|
118
|
+
for (const e of embers) {
|
|
119
|
+
e.y -= e.v;
|
|
120
|
+
e.x += Math.sin(t * e.sp + e.ph) * 0.18;
|
|
121
|
+
if (e.y < -6) {
|
|
122
|
+
e.y = H + 6;
|
|
123
|
+
e.x = Math.random() * W;
|
|
124
|
+
}
|
|
125
|
+
e.a = 0.26 + 0.4 * (0.5 + 0.5 * Math.sin(t * e.sp * 2 + e.ph));
|
|
126
|
+
}
|
|
127
|
+
paint(ctx, W, H, embers, haze);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function loop() {
|
|
131
|
+
frame();
|
|
132
|
+
raf = requestAnimationFrame(loop);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
size();
|
|
136
|
+
reseed();
|
|
137
|
+
if (!reduced) raf = requestAnimationFrame(loop);
|
|
138
|
+
|
|
139
|
+
const onResize = () => {
|
|
140
|
+
size();
|
|
141
|
+
reseed();
|
|
142
|
+
};
|
|
143
|
+
window.addEventListener('resize', onResize);
|
|
144
|
+
|
|
145
|
+
// The hearth warms a *container*, and containers change without a window
|
|
146
|
+
// resize (a split pane, a toggled sidebar). Watch the host: re-size and
|
|
147
|
+
// re-seed only when its dimensions actually changed, never per-frame.
|
|
148
|
+
let ro = null;
|
|
149
|
+
if (typeof ResizeObserver !== 'undefined' && canvas.parentElement) {
|
|
150
|
+
const host = canvas.parentElement;
|
|
151
|
+
let lastW = 0;
|
|
152
|
+
let lastH = 0;
|
|
153
|
+
ro = new ResizeObserver((entries) => {
|
|
154
|
+
const e = entries[0];
|
|
155
|
+
if (!e) return;
|
|
156
|
+
const w = e.contentRect?.width ?? e.contentBoxSize?.[0]?.inlineSize ?? 0;
|
|
157
|
+
const h = e.contentRect?.height ?? e.contentBoxSize?.[0]?.blockSize ?? 0;
|
|
158
|
+
if (Math.abs(w - lastW) > 0.5 || Math.abs(h - lastH) > 0.5) {
|
|
159
|
+
lastW = w;
|
|
160
|
+
lastH = h;
|
|
161
|
+
onResize();
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
ro.observe(host);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return () => {
|
|
168
|
+
if (raf) cancelAnimationFrame(raf);
|
|
169
|
+
window.removeEventListener('resize', onResize);
|
|
170
|
+
if (ro) ro.disconnect();
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Every element marked `data-ember` lights its own hearth. */
|
|
175
|
+
export function startAllEmbers(root = document) {
|
|
176
|
+
return Array.from(root.querySelectorAll('[data-ember]')).map(startEmbers);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (typeof document !== 'undefined') {
|
|
180
|
+
const boot = () => startAllEmbers();
|
|
181
|
+
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot, { once: true });
|
|
182
|
+
else boot();
|
|
183
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import { startEmbers } from '../assets/ember.js';
|
|
3
|
+
|
|
4
|
+
/** The hearth — the hall's glow, carried in this repo (not shared or borrowed). */
|
|
5
|
+
export default function EmberBackground() {
|
|
6
|
+
const ref = useRef<HTMLCanvasElement>(null);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
const el = ref.current;
|
|
9
|
+
if (!el) return;
|
|
10
|
+
const stop = startEmbers(el);
|
|
11
|
+
return () => stop?.();
|
|
12
|
+
}, []);
|
|
13
|
+
return <canvas ref={ref} className="ember-bg" data-ember aria-hidden="true" />;
|
|
14
|
+
}
|
|
@@ -81,7 +81,7 @@ function tokenLabel(name: string): string {
|
|
|
81
81
|
// reads it via `useAppStore.getState()` at cleanup time rather than through
|
|
82
82
|
// the hook, so the two call sites can't share a `useAppStore(...)` call.
|
|
83
83
|
function resolveSettingsThemeId(state: ReturnType<typeof useAppStore.getState>): string {
|
|
84
|
-
return state.settingsDraft.theme ?? state.settings?.theme ?? '
|
|
84
|
+
return state.settingsDraft.theme ?? state.settings?.theme ?? 'fensalir'
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
export function ThemeEditor({
|
|
@@ -376,3 +376,6 @@
|
|
|
376
376
|
Highlight API) are injected at runtime from chat-search.tsx — Tailwind's
|
|
377
377
|
Lightning CSS transformer drops the unrecognized ::highlight() pseudo-element
|
|
378
378
|
at build time, so they can't live here. */
|
|
379
|
+
|
|
380
|
+
/* The hearth — embers rising over the cloth. */
|
|
381
|
+
.ember-bg { position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: 0.5; mix-blend-mode: screen; }
|
|
@@ -1908,7 +1908,7 @@ export const useAppStore = create<AppState & AppActions>((set, get) => ({
|
|
|
1908
1908
|
// when the effective (draft or saved) theme is 'system'.
|
|
1909
1909
|
watchSystemTheme(() => {
|
|
1910
1910
|
const state = get()
|
|
1911
|
-
return state.settingsDraft.theme ?? state.settings?.theme ?? '
|
|
1911
|
+
return state.settingsDraft.theme ?? state.settings?.theme ?? 'fensalir'
|
|
1912
1912
|
})
|
|
1913
1913
|
|
|
1914
1914
|
// Apply font size
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "pi-theme/v1",
|
|
3
|
+
"name": "Fensalir",
|
|
4
|
+
"kind": "dark",
|
|
5
|
+
"author": "Ymir",
|
|
6
|
+
"description": "Fensalir — the weaving halls: the carved cloth of the halls, taken whole from the landing page's stone, bone, bronze and blood. The default cloth of the seat; any user theme chosen still wins over it.",
|
|
7
|
+
"seeds": {
|
|
8
|
+
"app": "#0e0c09",
|
|
9
|
+
"surface": "#151209",
|
|
10
|
+
"text": "#cfc3a9",
|
|
11
|
+
"accent": "#c9973f",
|
|
12
|
+
"success": "#96a0a8",
|
|
13
|
+
"warning": "#c9973f",
|
|
14
|
+
"error": "#c2584a"
|
|
15
|
+
},
|
|
16
|
+
"overrides": {
|
|
17
|
+
"app": "#0e0c09",
|
|
18
|
+
"surface": "#151209",
|
|
19
|
+
"surface-hover": "#1a1610",
|
|
20
|
+
"card": "#151209",
|
|
21
|
+
"elevated": "#1a1610",
|
|
22
|
+
"highlight": "#14100b",
|
|
23
|
+
"highlight-strong": "#1a1610",
|
|
24
|
+
"primary": "#cfc3a9",
|
|
25
|
+
"secondary": "rgba(207, 195, 169, 0.82)",
|
|
26
|
+
"muted": "#9a8f75",
|
|
27
|
+
"dim": "#6b6250",
|
|
28
|
+
"faint": "rgba(207, 195, 169, 0.38)",
|
|
29
|
+
"ghost": "rgba(207, 195, 169, 0.26)",
|
|
30
|
+
"inverse": "#0e0c09",
|
|
31
|
+
"border": "#2b241a",
|
|
32
|
+
"border-strong": "#7d5f2a",
|
|
33
|
+
"border-strong-hover": "#c9973f",
|
|
34
|
+
"focus": "#c9973f",
|
|
35
|
+
"accent": "#c9973f",
|
|
36
|
+
"accent-hover": "#7d5f2a",
|
|
37
|
+
"accent-fg": "#cfc3a9",
|
|
38
|
+
"accent-bg": "rgba(201, 151, 79, 0.14)",
|
|
39
|
+
"success": "#96a0a8",
|
|
40
|
+
"success-bg": "rgba(150, 160, 168, 0.14)",
|
|
41
|
+
"warning": "#c9973f",
|
|
42
|
+
"warning-bg": "rgba(201, 151, 79, 0.18)",
|
|
43
|
+
"error": "#c2584a",
|
|
44
|
+
"error-hover": "#7c3a30",
|
|
45
|
+
"error-bg": "rgba(124, 58, 48, 0.24)",
|
|
46
|
+
"info": "#9a8f75",
|
|
47
|
+
"info-bg": "rgba(154, 143, 117, 0.14)",
|
|
48
|
+
"special": "#7d5f2a",
|
|
49
|
+
"special-bg": "rgba(125, 95, 42, 0.18)",
|
|
50
|
+
"chat-column": "#0e0c09",
|
|
51
|
+
"chat-column-border": "#2b241a",
|
|
52
|
+
"scrollbar": "#2b241a",
|
|
53
|
+
"scrollbar-hover": "#7d5f2a",
|
|
54
|
+
"md-code": "#c9973f",
|
|
55
|
+
"md-pre-bg": "#14100b",
|
|
56
|
+
"selection-bg": "#57411a",
|
|
57
|
+
"selection-fg": "#f0e6cd"
|
|
58
|
+
},
|
|
59
|
+
"syntax": {
|
|
60
|
+
"keyword": "#c9973f",
|
|
61
|
+
"string": "#96a0a8",
|
|
62
|
+
"comment": "#6b6250",
|
|
63
|
+
"function": "#cfc3a9",
|
|
64
|
+
"type": "#9a8f75",
|
|
65
|
+
"number": "#c2584a",
|
|
66
|
+
"operator": "#9a8f75",
|
|
67
|
+
"property": "#96a0a8",
|
|
68
|
+
"tag": "#c2584a",
|
|
69
|
+
"variable": "#cfc3a9",
|
|
70
|
+
"constant": "#c9973f",
|
|
71
|
+
"heading": "#cfc3a9",
|
|
72
|
+
"link": "#c9973f",
|
|
73
|
+
"list": "#c2584a",
|
|
74
|
+
"quote": "#9a8f75",
|
|
75
|
+
"meta": "#6b6250",
|
|
76
|
+
"mark": "#c9973f",
|
|
77
|
+
"invalid": "#c2584a",
|
|
78
|
+
"active-line-bg": "rgba(207, 195, 169, 0.04)",
|
|
79
|
+
"selection-bg": "#57411a",
|
|
80
|
+
"selection-match-bg": "rgba(207, 195, 169, 0.08)"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -8,8 +8,12 @@ import gruvbox from './gruvbox.json'
|
|
|
8
8
|
import breezeDark from './breeze-dark.json'
|
|
9
9
|
import breezeLight from './breeze-light.json'
|
|
10
10
|
import breezeClaudius from './breeze-claudius.json'
|
|
11
|
+
import sessrumnir from './sessrumnir.json'
|
|
12
|
+
import fensalir from './fensalir.json'
|
|
11
13
|
|
|
12
14
|
export const BUILTIN_THEMES: ReadonlyArray<{ id: string; file: ThemeFile }> = [
|
|
15
|
+
{ id: 'sessrumnir', file: sessrumnir as ThemeFile },
|
|
16
|
+
{ id: 'fensalir', file: fensalir as ThemeFile },
|
|
13
17
|
{ id: 'dark', file: dark as ThemeFile },
|
|
14
18
|
{ id: 'light', file: light as ThemeFile },
|
|
15
19
|
{ id: 'nord', file: nord as ThemeFile },
|
|
@@ -42,6 +46,8 @@ const BUILTIN_THEME_NAME_KEYS = {
|
|
|
42
46
|
'breeze-dark': 'themes.builtin.breeze-dark',
|
|
43
47
|
'breeze-light': 'themes.builtin.breeze-light',
|
|
44
48
|
'breeze-claudius': 'themes.builtin.breeze-claudius',
|
|
49
|
+
sessrumnir: 'themes.builtin.sessrumnir',
|
|
50
|
+
fensalir: 'themes.builtin.fensalir',
|
|
45
51
|
} as const satisfies Record<BuiltinThemeId, string>
|
|
46
52
|
|
|
47
53
|
/** Built-in themes show a translated name; user and gallery themes keep their own. */
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "pi-theme/v1",
|
|
3
|
+
"name": "Sessrúmnir",
|
|
4
|
+
"kind": "dark",
|
|
5
|
+
"author": "Ymir",
|
|
6
|
+
"description": "The seat's own cloth — the carved stone, bone, bronze and blood of the landing page. The default look of the seat; a user theme chosen still wins over it.",
|
|
7
|
+
"seeds": {
|
|
8
|
+
"app": "#0e0c09",
|
|
9
|
+
"surface": "#151209",
|
|
10
|
+
"text": "#cfc3a9",
|
|
11
|
+
"accent": "#c9973f",
|
|
12
|
+
"success": "#96a0a8",
|
|
13
|
+
"warning": "#c9973f",
|
|
14
|
+
"error": "#c2584a"
|
|
15
|
+
},
|
|
16
|
+
"overrides": {
|
|
17
|
+
"app": "#0e0c09",
|
|
18
|
+
"surface": "#151209",
|
|
19
|
+
"surface-hover": "#1a1610",
|
|
20
|
+
"card": "#151209",
|
|
21
|
+
"elevated": "#1a1610",
|
|
22
|
+
"highlight": "#14100b",
|
|
23
|
+
"highlight-strong": "#1a1610",
|
|
24
|
+
"primary": "#cfc3a9",
|
|
25
|
+
"secondary": "rgba(207, 195, 169, 0.82)",
|
|
26
|
+
"muted": "#9a8f75",
|
|
27
|
+
"dim": "#6b6250",
|
|
28
|
+
"faint": "rgba(207, 195, 169, 0.38)",
|
|
29
|
+
"ghost": "rgba(207, 195, 169, 0.26)",
|
|
30
|
+
"inverse": "#0e0c09",
|
|
31
|
+
"border": "#2b241a",
|
|
32
|
+
"border-strong": "#7d5f2a",
|
|
33
|
+
"border-strong-hover": "#c9973f",
|
|
34
|
+
"focus": "#c9973f",
|
|
35
|
+
"accent": "#c9973f",
|
|
36
|
+
"accent-hover": "#7d5f2a",
|
|
37
|
+
"accent-fg": "#cfc3a9",
|
|
38
|
+
"accent-bg": "rgba(201, 151, 79, 0.14)",
|
|
39
|
+
"success": "#96a0a8",
|
|
40
|
+
"success-bg": "rgba(150, 160, 168, 0.14)",
|
|
41
|
+
"warning": "#c9973f",
|
|
42
|
+
"warning-bg": "rgba(201, 151, 79, 0.18)",
|
|
43
|
+
"error": "#c2584a",
|
|
44
|
+
"error-hover": "#7c3a30",
|
|
45
|
+
"error-bg": "rgba(124, 58, 48, 0.24)",
|
|
46
|
+
"info": "#9a8f75",
|
|
47
|
+
"info-bg": "rgba(154, 143, 117, 0.14)",
|
|
48
|
+
"special": "#7d5f2a",
|
|
49
|
+
"special-bg": "rgba(125, 95, 42, 0.18)",
|
|
50
|
+
"chat-column": "#0e0c09",
|
|
51
|
+
"chat-column-border": "#2b241a",
|
|
52
|
+
"scrollbar": "#2b241a",
|
|
53
|
+
"scrollbar-hover": "#7d5f2a",
|
|
54
|
+
"md-code": "#c9973f",
|
|
55
|
+
"md-pre-bg": "#14100b",
|
|
56
|
+
"selection-bg": "#57411a",
|
|
57
|
+
"selection-fg": "#f0e6cd"
|
|
58
|
+
},
|
|
59
|
+
"syntax": {
|
|
60
|
+
"keyword": "#c9973f",
|
|
61
|
+
"string": "#96a0a8",
|
|
62
|
+
"comment": "#6b6250",
|
|
63
|
+
"function": "#cfc3a9",
|
|
64
|
+
"type": "#9a8f75",
|
|
65
|
+
"number": "#c2584a",
|
|
66
|
+
"operator": "#9a8f75",
|
|
67
|
+
"property": "#96a0a8",
|
|
68
|
+
"tag": "#c2584a",
|
|
69
|
+
"variable": "#cfc3a9",
|
|
70
|
+
"constant": "#c9973f",
|
|
71
|
+
"heading": "#cfc3a9",
|
|
72
|
+
"link": "#c9973f",
|
|
73
|
+
"list": "#c2584a",
|
|
74
|
+
"quote": "#9a8f75",
|
|
75
|
+
"meta": "#6b6250",
|
|
76
|
+
"mark": "#c9973f",
|
|
77
|
+
"invalid": "#c2584a",
|
|
78
|
+
"active-line-bg": "rgba(207, 195, 169, 0.04)",
|
|
79
|
+
"selection-bg": "#57411a",
|
|
80
|
+
"selection-match-bg": "rgba(207, 195, 169, 0.08)"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -13,9 +13,9 @@ export const DEFAULT_SETTINGS: AppSettings = {
|
|
|
13
13
|
piExecutablePath: 'pi',
|
|
14
14
|
piEngine: 'auto',
|
|
15
15
|
defaultArgs: [],
|
|
16
|
-
theme: '
|
|
17
|
-
systemLightTheme: '
|
|
18
|
-
systemDarkTheme: '
|
|
16
|
+
theme: 'fensalir',
|
|
17
|
+
systemLightTheme: 'fensalir',
|
|
18
|
+
systemDarkTheme: 'fensalir',
|
|
19
19
|
defaultModel: null,
|
|
20
20
|
defaultProvider: null,
|
|
21
21
|
defaultCwd: null,
|
|
@@ -7,5 +7,5 @@
|
|
|
7
7
|
// those (separate process/bundle), so this module is the single shared
|
|
8
8
|
// source of truth for just the id strings.
|
|
9
9
|
export const BUILTIN_THEME_IDS = [
|
|
10
|
-
'dark', 'light', 'nord', 'gruvbox', 'breeze-dark', 'breeze-light', 'breeze-claudius',
|
|
10
|
+
'dark', 'light', 'nord', 'gruvbox', 'breeze-dark', 'breeze-light', 'breeze-claudius', 'sessrumnir', 'fensalir',
|
|
11
11
|
] as const
|