neoagent 2.4.1-beta.22 → 2.4.1-beta.24

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.
Files changed (86) hide show
  1. package/extensions/chrome-browser/icons/icon128.png +0 -0
  2. package/extensions/chrome-browser/icons/icon16.png +0 -0
  3. package/extensions/chrome-browser/icons/icon48.png +0 -0
  4. package/extensions/chrome-browser/icons/logo.svg +40 -10
  5. package/flutter_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  6. package/flutter_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  7. package/flutter_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  8. package/flutter_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  9. package/flutter_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  10. package/flutter_app/assets/branding/app_icon_1024.png +0 -0
  11. package/flutter_app/assets/branding/app_icon_128.png +0 -0
  12. package/flutter_app/assets/branding/app_icon_192.png +0 -0
  13. package/flutter_app/assets/branding/app_icon_256.png +0 -0
  14. package/flutter_app/assets/branding/app_icon_32.png +0 -0
  15. package/flutter_app/assets/branding/app_icon_512.png +0 -0
  16. package/flutter_app/assets/branding/app_icon_64.png +0 -0
  17. package/flutter_app/assets/branding/app_icon_light_1024.png +0 -0
  18. package/flutter_app/assets/branding/app_icon_light_128.png +0 -0
  19. package/flutter_app/assets/branding/app_icon_light_192.png +0 -0
  20. package/flutter_app/assets/branding/app_icon_light_256.png +0 -0
  21. package/flutter_app/assets/branding/app_icon_light_32.png +0 -0
  22. package/flutter_app/assets/branding/app_icon_light_512.png +0 -0
  23. package/flutter_app/assets/branding/app_icon_light_64.png +0 -0
  24. package/flutter_app/assets/branding/tray_icon_light_template.png +0 -0
  25. package/flutter_app/assets/branding/tray_icon_template.png +0 -0
  26. package/flutter_app/lib/features/onboarding/onboarding_chrome.dart +1 -1
  27. package/flutter_app/lib/features/onboarding/onboarding_companion_step.dart +1 -1
  28. package/flutter_app/lib/features/onboarding/onboarding_model_step.dart +1 -1
  29. package/flutter_app/lib/features/onboarding/onboarding_welcome_step.dart +2 -2
  30. package/flutter_app/lib/main_app_shell.dart +7 -7
  31. package/flutter_app/lib/main_shared.dart +1 -1
  32. package/flutter_app/linux/runner/resources/app_icon.png +0 -0
  33. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png +0 -0
  34. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png +0 -0
  35. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png +0 -0
  36. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png +0 -0
  37. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png +0 -0
  38. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png +0 -0
  39. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png +0 -0
  40. package/flutter_app/tool/branding_source/neoagent-icon-1024.png +0 -0
  41. package/flutter_app/tool/branding_source/neoagent-icon-128.png +0 -0
  42. package/flutter_app/tool/branding_source/neoagent-icon-16.png +0 -0
  43. package/flutter_app/tool/branding_source/neoagent-icon-180.png +0 -0
  44. package/flutter_app/tool/branding_source/neoagent-icon-192.png +0 -0
  45. package/flutter_app/tool/branding_source/neoagent-icon-256.png +0 -0
  46. package/flutter_app/tool/branding_source/neoagent-icon-32.png +0 -0
  47. package/flutter_app/tool/branding_source/neoagent-icon-48.png +0 -0
  48. package/flutter_app/tool/branding_source/neoagent-icon-512.png +0 -0
  49. package/flutter_app/tool/branding_source/neoagent-icon-64.png +0 -0
  50. package/flutter_app/tool/branding_source/neoagent-icon.svg +43 -0
  51. package/flutter_app/tool/generate_desktop_branding.py +147 -198
  52. package/flutter_app/web/favicon.png +0 -0
  53. package/flutter_app/web/favicon.svg +40 -10
  54. package/flutter_app/web/favicon_light.svg +40 -10
  55. package/flutter_app/web/icons/Icon-192-light.png +0 -0
  56. package/flutter_app/web/icons/Icon-192.png +0 -0
  57. package/flutter_app/web/icons/Icon-512-light.png +0 -0
  58. package/flutter_app/web/icons/Icon-512.png +0 -0
  59. package/flutter_app/web/icons/Icon-maskable-192-light.png +0 -0
  60. package/flutter_app/web/icons/Icon-maskable-192.png +0 -0
  61. package/flutter_app/web/icons/Icon-maskable-512-light.png +0 -0
  62. package/flutter_app/web/icons/Icon-maskable-512.png +0 -0
  63. package/flutter_app/windows/runner/main.cpp +7 -1
  64. package/flutter_app/windows/runner/resources/app_icon.ico +0 -0
  65. package/package.json +1 -1
  66. package/server/public/.last_build_id +1 -1
  67. package/server/public/assets/assets/branding/app_icon_256.png +0 -0
  68. package/server/public/assets/assets/branding/app_icon_512.png +0 -0
  69. package/server/public/assets/assets/branding/app_icon_light_256.png +0 -0
  70. package/server/public/assets/assets/branding/app_icon_light_512.png +0 -0
  71. package/server/public/assets/assets/branding/tray_icon_light_template.png +0 -0
  72. package/server/public/assets/assets/branding/tray_icon_template.png +0 -0
  73. package/server/public/assets/web/icons/Icon-192.png +0 -0
  74. package/server/public/favicon.png +0 -0
  75. package/server/public/favicon.svg +40 -10
  76. package/server/public/favicon_light.svg +40 -10
  77. package/server/public/flutter_bootstrap.js +2 -2
  78. package/server/public/icons/Icon-192-light.png +0 -0
  79. package/server/public/icons/Icon-192.png +0 -0
  80. package/server/public/icons/Icon-512-light.png +0 -0
  81. package/server/public/icons/Icon-512.png +0 -0
  82. package/server/public/icons/Icon-maskable-192-light.png +0 -0
  83. package/server/public/icons/Icon-maskable-192.png +0 -0
  84. package/server/public/icons/Icon-maskable-512-light.png +0 -0
  85. package/server/public/icons/Icon-maskable-512.png +0 -0
  86. package/server/public/main.dart.js +111 -111
@@ -2,13 +2,13 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- import math
6
5
  from pathlib import Path
7
6
 
8
- from PIL import Image, ImageDraw, ImageFilter
7
+ from PIL import Image, ImageDraw
9
8
 
10
9
 
11
10
  ROOT = Path(__file__).resolve().parents[1]
11
+ SOURCE_DIR = ROOT / "tool" / "branding_source"
12
12
  BRANDING_DIR = ROOT / "assets" / "branding"
13
13
  WEB_DIR = ROOT / "web"
14
14
  WEB_ICONS_DIR = WEB_DIR / "icons"
@@ -20,114 +20,14 @@ SERVER_PUBLIC_DIR = ROOT.parent / "server" / "public"
20
20
  SERVER_PUBLIC_ICONS_DIR = SERVER_PUBLIC_DIR / "icons"
21
21
  STATIC_IMG_DIR = ROOT.parent / "static" / "img"
22
22
  LANDING_LOGO_PATH = ROOT.parent / "landing" / "assets" / "logo.svg"
23
- EXTENSION_LOGO_PATH = ROOT.parent / "extensions" / "chrome-browser" / "icons" / "logo.svg"
23
+ EXTENSION_ICON_DIR = ROOT.parent / "extensions" / "chrome-browser" / "icons"
24
+ EXTENSION_LOGO_PATH = EXTENSION_ICON_DIR / "logo.svg"
24
25
 
25
- ACCENT = (118, 89, 50)
26
- ACCENT_ALT = (40, 105, 92)
27
- ACCENT_DARK = (149, 118, 74)
28
- ACCENT_ALT_DARK = (58, 134, 121)
29
- SYMBOL_LIGHT = (255, 249, 237, 255)
30
- WHITE = (255, 255, 255, 255)
26
+ SOURCE_SVG = SOURCE_DIR / "neoagent-icon.svg"
27
+ SOURCE_PNG_SIZES = (16, 32, 48, 64, 128, 180, 192, 256, 512, 1024)
31
28
  TRANSPARENT = (0, 0, 0, 0)
32
-
33
-
34
- def lerp(a: float, b: float, t: float) -> float:
35
- return a + (b - a) * t
36
-
37
-
38
- def gradient_background(
39
- size: int,
40
- start: tuple[int, int, int],
41
- end: tuple[int, int, int],
42
- ) -> Image.Image:
43
- img = Image.new("RGBA", (size, size), TRANSPARENT)
44
- px = img.load()
45
- for y in range(size):
46
- for x in range(size):
47
- tx = x / max(size - 1, 1)
48
- ty = y / max(size - 1, 1)
49
- t = (tx + ty) / 2
50
- px[x, y] = (
51
- int(lerp(start[0], end[0], t)),
52
- int(lerp(start[1], end[1], t)),
53
- int(lerp(start[2], end[2], t)),
54
- 255,
55
- )
56
- return img
57
-
58
-
59
- def logo_paths(size: int, padding_ratio: float = 0.16):
60
- pad = size * padding_ratio
61
- inner = size - pad * 2
62
- def point(x: float, y: float) -> tuple[float, float]:
63
- return (pad + inner * x, pad + inner * y)
64
-
65
- top = [point(0.5, 0.08), point(0.92, 0.35), point(0.5, 0.53), point(0.08, 0.35)]
66
- middle = [point(0.5, 0.43), point(0.9, 0.64), point(0.5, 0.76), point(0.1, 0.64)]
67
- bottom = [point(0.5, 0.67), point(0.86, 0.86), point(0.5, 0.96), point(0.14, 0.86)]
68
- return top, middle, bottom
69
-
70
-
71
- def draw_logo(draw: ImageDraw.ImageDraw, size: int, color: tuple[int, int, int, int]) -> None:
72
- top, middle, bottom = logo_paths(size)
73
- draw.polygon(top, fill=color)
74
- draw.polygon(middle, fill=color)
75
- draw.polygon(bottom, fill=color)
76
-
77
-
78
- def make_app_icon(size: int, *, light: bool = False) -> Image.Image:
79
- canvas = Image.new("RGBA", (size, size), TRANSPARENT)
80
- start = ACCENT if light else ACCENT_DARK
81
- end = ACCENT_ALT if light else ACCENT_ALT_DARK
82
- symbol = SYMBOL_LIGHT if light else WHITE
83
-
84
- shadow = Image.new("RGBA", (size, size), TRANSPARENT)
85
- shadow_draw = ImageDraw.Draw(shadow)
86
- offset_y = size * 0.02
87
- corner = round(size * 0.34)
88
- shadow_draw.rounded_rectangle(
89
- (size * 0.07, size * 0.07 + offset_y, size * 0.93, size * 0.93 + offset_y),
90
- radius=corner,
91
- fill=(0, 0, 0, 72),
92
- )
93
- shadow = shadow.filter(ImageFilter.GaussianBlur(radius=max(2, size * 0.04)))
94
- canvas.alpha_composite(shadow)
95
-
96
- base_mask = Image.new("L", (size, size), 0)
97
- mask_draw = ImageDraw.Draw(base_mask)
98
- base_rect = (size * 0.08, size * 0.08, size * 0.92, size * 0.92)
99
- mask_draw.rounded_rectangle(base_rect, radius=corner, fill=255)
100
-
101
- base = gradient_background(size, start, end)
102
- clipped = Image.new("RGBA", (size, size), TRANSPARENT)
103
- clipped.paste(base, mask=base_mask)
104
- canvas.alpha_composite(clipped)
105
-
106
- ring = Image.new("RGBA", (size, size), TRANSPARENT)
107
- ring_draw = ImageDraw.Draw(ring)
108
- ring_draw.rounded_rectangle(
109
- base_rect,
110
- radius=corner,
111
- outline=(255, 255, 255, 36),
112
- width=max(1, round(size * 0.012)),
113
- )
114
- canvas.alpha_composite(ring)
115
-
116
- glyph = Image.new("RGBA", (size, size), TRANSPARENT)
117
- draw = ImageDraw.Draw(glyph)
118
- draw_logo(draw, size, symbol)
119
- canvas.alpha_composite(glyph)
120
- return canvas
121
-
122
-
123
- def make_tray_template(
124
- size: int = 64,
125
- color: tuple[int, int, int, int] = (0, 0, 0, 255),
126
- ) -> Image.Image:
127
- img = Image.new("RGBA", (size, size), TRANSPARENT)
128
- draw = ImageDraw.Draw(img)
129
- draw_logo(draw, size, color)
130
- return img
29
+ WHITE = (255, 255, 255, 255)
30
+ BLACK = (0, 0, 0, 255)
131
31
 
132
32
 
133
33
  def ensure_dirs() -> None:
@@ -138,86 +38,128 @@ def ensure_dirs() -> None:
138
38
  SERVER_PUBLIC_ICONS_DIR.mkdir(parents=True, exist_ok=True)
139
39
  STATIC_IMG_DIR.mkdir(parents=True, exist_ok=True)
140
40
  LANDING_LOGO_PATH.parent.mkdir(parents=True, exist_ok=True)
141
- EXTENSION_LOGO_PATH.parent.mkdir(parents=True, exist_ok=True)
41
+ EXTENSION_ICON_DIR.mkdir(parents=True, exist_ok=True)
42
+
43
+
44
+ def source_png_path(size: int) -> Path:
45
+ return SOURCE_DIR / f"neoagent-icon-{size}.png"
46
+
142
47
 
48
+ def load_source_icon(size: int) -> Image.Image:
49
+ if size in SOURCE_PNG_SIZES and source_png_path(size).exists():
50
+ return Image.open(source_png_path(size)).convert("RGBA")
51
+ source = Image.open(source_png_path(1024)).convert("RGBA")
52
+ return source.resize((size, size), Image.Resampling.LANCZOS)
143
53
 
144
- def write_text(path: Path, content: str) -> None:
145
- path.write_text(content, encoding="utf-8")
54
+
55
+ def save_icon(path: Path, size: int) -> None:
56
+ path.parent.mkdir(parents=True, exist_ok=True)
57
+ image = load_source_icon(size)
58
+ if image.size != (size, size):
59
+ image = image.resize((size, size), Image.Resampling.LANCZOS)
60
+ image.save(path, format="PNG")
146
61
 
147
62
 
148
- def copy_png(image: Image.Image, path: Path, size: int) -> None:
63
+ def write_source_svg(path: Path) -> None:
149
64
  path.parent.mkdir(parents=True, exist_ok=True)
150
- save_png(image, path, size)
151
-
152
-
153
- def write_favicon_svg(path: Path, *, light: bool = False) -> None:
154
- start = ACCENT if light else ACCENT_DARK
155
- end = ACCENT_ALT if light else ACCENT_ALT_DARK
156
- symbol = "#fff9ed" if light else "#ffffff"
157
- stroke = "#000000" if light else "#ffffff"
158
- stroke_opacity = "0.24" if light else "0.16"
159
- svg = f"""<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
160
- <defs>
161
- <linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
162
- <stop offset="0%" stop-color="#{start[0]:02x}{start[1]:02x}{start[2]:02x}"/>
163
- <stop offset="100%" stop-color="#{end[0]:02x}{end[1]:02x}{end[2]:02x}"/>
164
- </linearGradient>
165
- </defs>
166
- <rect x="2.5" y="2.5" width="27" height="27" rx="9" ry="9" fill="url(#bg)" stroke="{stroke}" stroke-opacity="{stroke_opacity}" stroke-width="1"/>
167
- <rect x="3" y="3" width="26" height="26" rx="8.5" ry="8.5" fill="none" stroke="#ffffff" stroke-opacity="0.18" stroke-width="1"/>
168
- <path d="M16 5.7 26.8 12.1 16 16.5 5.2 12.1Z" fill="{symbol}"/>
169
- <path d="M16 14.2 26.5 19.3 16 22.4 5.5 19.3Z" fill="{symbol}"/>
170
- <path d="M16 20 25.4 24.6 16 27 6.6 24.6Z" fill="{symbol}"/>
171
- </svg>
172
- """
173
- write_text(path, svg)
174
-
175
-
176
- def save_png(image: Image.Image, path: Path, size: int) -> None:
177
- image.resize((size, size), Image.Resampling.LANCZOS).save(path, format="PNG")
65
+ svg = SOURCE_SVG.read_text(encoding="utf-8")
66
+ svg = svg.replace(
67
+ 'stroke="rgba(255,255,255,0.16)"',
68
+ 'stroke="#ffffff" stroke-opacity="0.16"',
69
+ )
70
+ path.write_text(svg, encoding="utf-8")
71
+
72
+
73
+ def draw_scaled_circle(
74
+ draw: ImageDraw.ImageDraw,
75
+ size: int,
76
+ center_x: float,
77
+ center_y: float,
78
+ radius: float,
79
+ color: tuple[int, int, int, int],
80
+ ) -> None:
81
+ scale = size / 100
82
+ draw.ellipse(
83
+ (
84
+ (center_x - radius) * scale,
85
+ (center_y - radius) * scale,
86
+ (center_x + radius) * scale,
87
+ (center_y + radius) * scale,
88
+ ),
89
+ fill=color,
90
+ )
91
+
92
+
93
+ def make_tray_template(
94
+ size: int = 64,
95
+ color: tuple[int, int, int, int] = BLACK,
96
+ ) -> Image.Image:
97
+ img = Image.new("RGBA", (size, size), TRANSPARENT)
98
+ draw = ImageDraw.Draw(img)
99
+ scale = size / 100
100
+ width = max(2, round(size * 0.078))
101
+ center = 50 * scale
102
+
103
+ draw.arc(
104
+ (
105
+ (50 - 30) * scale,
106
+ (50 - 30) * scale,
107
+ (50 + 30) * scale,
108
+ (50 + 30) * scale,
109
+ ),
110
+ start=158,
111
+ end=444,
112
+ fill=color,
113
+ width=width,
114
+ )
115
+ draw.arc(
116
+ (
117
+ (50 - 17) * scale,
118
+ (50 - 17) * scale,
119
+ (50 + 17) * scale,
120
+ (50 + 17) * scale,
121
+ ),
122
+ start=68,
123
+ end=330,
124
+ fill=color,
125
+ width=width,
126
+ )
127
+ draw_scaled_circle(draw, size, 50, 50, 7, color)
128
+ draw_scaled_circle(draw, size, 50, 20, 5.6, color)
129
+
130
+ # Slightly round arc ends so the template keeps the supplied logo's soft tube feel.
131
+ end_radius = width / 2
132
+ for x, y in ((77.2, 74.8), (80.0, 41.2), (32.0, 29.7), (68.8, 39.2)):
133
+ draw.ellipse(
134
+ (
135
+ x * scale - end_radius,
136
+ y * scale - end_radius,
137
+ x * scale + end_radius,
138
+ y * scale + end_radius,
139
+ ),
140
+ fill=color,
141
+ )
142
+
143
+ # Keep the symbol optically centered inside the menu-bar bounds.
144
+ return img.crop((0, 2, size, size + 2))
178
145
 
179
146
 
180
147
  def main() -> None:
181
148
  ensure_dirs()
182
- master = make_app_icon(1024)
183
- light_master = make_app_icon(1024, light=True)
184
-
185
- save_png(master, BRANDING_DIR / "app_icon_1024.png", 1024)
186
- save_png(master, BRANDING_DIR / "app_icon_512.png", 512)
187
- save_png(master, BRANDING_DIR / "app_icon_256.png", 256)
188
- save_png(master, BRANDING_DIR / "app_icon_192.png", 192)
189
- save_png(master, BRANDING_DIR / "app_icon_128.png", 128)
190
- save_png(master, BRANDING_DIR / "app_icon_64.png", 64)
191
- save_png(master, BRANDING_DIR / "app_icon_32.png", 32)
192
- save_png(light_master, BRANDING_DIR / "app_icon_light_1024.png", 1024)
193
- save_png(light_master, BRANDING_DIR / "app_icon_light_512.png", 512)
194
- save_png(light_master, BRANDING_DIR / "app_icon_light_256.png", 256)
195
- save_png(light_master, BRANDING_DIR / "app_icon_light_192.png", 192)
196
- save_png(light_master, BRANDING_DIR / "app_icon_light_128.png", 128)
197
- save_png(light_master, BRANDING_DIR / "app_icon_light_64.png", 64)
198
- save_png(light_master, BRANDING_DIR / "app_icon_light_32.png", 32)
199
-
200
- tray = make_tray_template(64)
201
- save_png(tray, BRANDING_DIR / "tray_icon_template.png", 64)
202
- light_tray = make_tray_template(64, WHITE)
203
- save_png(light_tray, BRANDING_DIR / "tray_icon_light_template.png", 64)
204
-
205
- icon_sizes = {
206
- 16: "app_icon_16.png",
207
- 32: "app_icon_32.png",
208
- 64: "app_icon_64.png",
209
- 128: "app_icon_128.png",
210
- 256: "app_icon_256.png",
211
- 512: "app_icon_512.png",
212
- 1024: "app_icon_1024.png",
213
- }
214
- for size, filename in icon_sizes.items():
215
- save_png(master, MAC_ICON_DIR / filename, size)
216
149
 
217
- save_png(master, LINUX_ICON_DIR / "app_icon.png", 256)
150
+ for size in (1024, 512, 256, 192, 128, 64, 32):
151
+ save_icon(BRANDING_DIR / f"app_icon_{size}.png", size)
152
+ save_icon(BRANDING_DIR / f"app_icon_light_{size}.png", size)
153
+
154
+ make_tray_template(64).save(BRANDING_DIR / "tray_icon_template.png", format="PNG")
155
+ make_tray_template(64, WHITE).save(BRANDING_DIR / "tray_icon_light_template.png", format="PNG")
156
+
157
+ for size in (16, 32, 64, 128, 256, 512, 1024):
158
+ save_icon(MAC_ICON_DIR / f"app_icon_{size}.png", size)
218
159
 
219
- master_for_ico = master.resize((256, 256), Image.Resampling.LANCZOS)
220
- master_for_ico.save(
160
+ save_icon(LINUX_ICON_DIR / "app_icon.png", 256)
161
+
162
+ load_source_icon(256).save(
221
163
  WINDOWS_ICON_PATH,
222
164
  format="ICO",
223
165
  sizes=[(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)],
@@ -228,26 +170,33 @@ def main() -> None:
228
170
  512: "Icon-512.png",
229
171
  }
230
172
  for size, filename in web_icon_sizes.items():
231
- copy_png(master, WEB_ICONS_DIR / filename, size)
232
- copy_png(master, WEB_ICONS_DIR / filename.replace("Icon-", "Icon-maskable-"), size)
233
- copy_png(light_master, WEB_ICONS_DIR / filename.replace(".png", "-light.png"), size)
234
- copy_png(light_master, WEB_ICONS_DIR / filename.replace("Icon-", "Icon-maskable-").replace(".png", "-light.png"), size)
235
- copy_png(master, SERVER_PUBLIC_ICONS_DIR / filename, size)
236
- copy_png(master, SERVER_PUBLIC_ICONS_DIR / filename.replace("Icon-", "Icon-maskable-"), size)
237
-
238
- copy_png(master, WEB_DIR / "favicon.png", 32)
239
- copy_png(master, SERVER_PUBLIC_DIR / "favicon.png", 32)
240
- write_favicon_svg(WEB_DIR / "favicon.svg")
241
- write_favicon_svg(WEB_DIR / "favicon_light.svg", light=True)
242
- write_favicon_svg(SERVER_PUBLIC_DIR / "favicon.svg")
243
- write_favicon_svg(SERVER_PUBLIC_DIR / "favicon_light.svg", light=True)
244
- write_favicon_svg(LANDING_LOGO_PATH, light=True)
245
- write_favicon_svg(EXTENSION_LOGO_PATH)
246
- copy_png(master, STATIC_IMG_DIR / "app_icon.png", 512)
247
- copy_png(light_master, STATIC_IMG_DIR / "app_icon_light.png", 512)
248
- copy_png(master, SERVER_PUBLIC_DIR / "assets" / "assets" / "branding" / "app_icon_256.png", 256)
249
- copy_png(tray, SERVER_PUBLIC_DIR / "assets" / "assets" / "branding" / "tray_icon_template.png", 64)
250
- copy_png(master, SERVER_PUBLIC_DIR / "assets" / "web" / "icons" / "Icon-192.png", 192)
173
+ save_icon(WEB_ICONS_DIR / filename, size)
174
+ save_icon(WEB_ICONS_DIR / filename.replace("Icon-", "Icon-maskable-"), size)
175
+ save_icon(WEB_ICONS_DIR / filename.replace(".png", "-light.png"), size)
176
+ save_icon(WEB_ICONS_DIR / filename.replace("Icon-", "Icon-maskable-").replace(".png", "-light.png"), size)
177
+ save_icon(SERVER_PUBLIC_ICONS_DIR / filename, size)
178
+ save_icon(SERVER_PUBLIC_ICONS_DIR / filename.replace("Icon-", "Icon-maskable-"), size)
179
+
180
+ save_icon(WEB_DIR / "favicon.png", 32)
181
+ save_icon(SERVER_PUBLIC_DIR / "favicon.png", 32)
182
+ write_source_svg(WEB_DIR / "favicon.svg")
183
+ write_source_svg(WEB_DIR / "favicon_light.svg")
184
+ write_source_svg(SERVER_PUBLIC_DIR / "favicon.svg")
185
+ write_source_svg(SERVER_PUBLIC_DIR / "favicon_light.svg")
186
+ write_source_svg(LANDING_LOGO_PATH)
187
+ write_source_svg(EXTENSION_LOGO_PATH)
188
+
189
+ for size in (16, 48, 128):
190
+ save_icon(EXTENSION_ICON_DIR / f"icon{size}.png", size)
191
+
192
+ save_icon(STATIC_IMG_DIR / "app_icon.png", 512)
193
+ save_icon(STATIC_IMG_DIR / "app_icon_light.png", 512)
194
+ save_icon(SERVER_PUBLIC_DIR / "assets" / "assets" / "branding" / "app_icon_256.png", 256)
195
+ make_tray_template(64).save(
196
+ SERVER_PUBLIC_DIR / "assets" / "assets" / "branding" / "tray_icon_template.png",
197
+ format="PNG",
198
+ )
199
+ save_icon(SERVER_PUBLIC_DIR / "assets" / "web" / "icons" / "Icon-192.png", 192)
251
200
 
252
201
  android_icon_sizes = {
253
202
  "mipmap-mdpi": 48,
@@ -257,7 +206,7 @@ def main() -> None:
257
206
  "mipmap-xxxhdpi": 192,
258
207
  }
259
208
  for folder, size in android_icon_sizes.items():
260
- copy_png(master, ANDROID_RES_DIR / folder / "ic_launcher.png", size)
209
+ save_icon(ANDROID_RES_DIR / folder / "ic_launcher.png", size)
261
210
 
262
211
 
263
212
  if __name__ == "__main__":
Binary file
@@ -1,13 +1,43 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 100 100">
2
2
  <defs>
3
- <linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
4
- <stop offset="0%" stop-color="#95764a"/>
5
- <stop offset="100%" stop-color="#3a8679"/>
3
+ <linearGradient id="tile" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" stop-color="#705331"></stop>
5
+ <stop offset="100%" stop-color="#22564c"></stop>
6
6
  </linearGradient>
7
+ <radialGradient id="shine" cx="26%" cy="14%" r="72%">
8
+ <stop offset="0%" stop-color="#ffffff" stop-opacity="0.22"></stop>
9
+ <stop offset="100%" stop-color="#ffffff" stop-opacity="0"></stop>
10
+ </radialGradient>
11
+ <radialGradient id="core" cx="38%" cy="32%" r="75%">
12
+ <stop offset="0%" stop-color="#fffdf6"></stop>
13
+ <stop offset="48%" stop-color="#eee3cc"></stop>
14
+ <stop offset="100%" stop-color="#b5a888"></stop>
15
+ </radialGradient>
16
+ <radialGradient id="node" cx="36%" cy="30%" r="80%">
17
+ <stop offset="0%" stop-color="#f8dca8"></stop>
18
+ <stop offset="52%" stop-color="#d3a85f"></stop>
19
+ <stop offset="100%" stop-color="#9b6f2f"></stop>
20
+ </radialGradient>
21
+ <linearGradient id="tube" x1="0%" y1="0%" x2="0%" y2="100%">
22
+ <stop offset="0%" stop-color="#fffaf0"></stop>
23
+ <stop offset="52%" stop-color="#efe7d6"></stop>
24
+ <stop offset="100%" stop-color="#cabf9f"></stop>
25
+ </linearGradient>
26
+ <filter id="sh" x="-30%" y="-30%" width="160%" height="160%">
27
+ <feDropShadow dx="0" dy="1.1" stdDeviation="1.1" flood-color="#000000" flood-opacity="0.45"></feDropShadow>
28
+ </filter>
29
+ <clipPath id="tc"><rect x="0" y="0" width="100" height="100" rx="22.5"></rect></clipPath>
7
30
  </defs>
8
- <rect x="2.5" y="2.5" width="27" height="27" rx="9" ry="9" fill="url(#bg)" stroke="#ffffff" stroke-opacity="0.16" stroke-width="1"/>
9
- <rect x="3" y="3" width="26" height="26" rx="8.5" ry="8.5" fill="none" stroke="#ffffff" stroke-opacity="0.18" stroke-width="1"/>
10
- <path d="M16 5.7 26.8 12.1 16 16.5 5.2 12.1Z" fill="#ffffff"/>
11
- <path d="M16 14.2 26.5 19.3 16 22.4 5.5 19.3Z" fill="#ffffff"/>
12
- <path d="M16 20 25.4 24.6 16 27 6.6 24.6Z" fill="#ffffff"/>
13
- </svg>
31
+ <g clip-path="url(#tc)">
32
+ <rect x="0" y="0" width="100" height="100" fill="url(#tile)"></rect>
33
+ <rect x="0" y="0" width="100" height="100" fill="url(#shine)"></rect>
34
+ <g fill="none" stroke="url(#tube)" stroke-linecap="round" filter="url(#sh)">
35
+ <circle cx="50" cy="50" r="17" stroke-width="5" stroke-dasharray="78 29" transform="rotate(-35 50 50)" stroke-opacity="0.92"></circle>
36
+ <circle cx="50" cy="50" r="30" stroke-width="5" stroke-dasharray="150 39" transform="rotate(70 50 50)" stroke-opacity="0.8"></circle>
37
+ </g>
38
+ <circle cx="50" cy="50" r="7" fill="url(#core)"></circle>
39
+ <circle cx="50" cy="20" r="5.6" fill="url(#node)"></circle>
40
+ <circle cx="48" cy="18.4" r="1.7" fill="#fff7e6" fill-opacity="0.8"></circle>
41
+ </g>
42
+ <rect x="0.6" y="0.6" width="98.8" height="98.8" rx="22" fill="none" stroke="#ffffff" stroke-opacity="0.16" stroke-width="1.2"></rect>
43
+ </svg>
@@ -1,13 +1,43 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 100 100">
2
2
  <defs>
3
- <linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
4
- <stop offset="0%" stop-color="#765932"/>
5
- <stop offset="100%" stop-color="#28695c"/>
3
+ <linearGradient id="tile" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" stop-color="#705331"></stop>
5
+ <stop offset="100%" stop-color="#22564c"></stop>
6
6
  </linearGradient>
7
+ <radialGradient id="shine" cx="26%" cy="14%" r="72%">
8
+ <stop offset="0%" stop-color="#ffffff" stop-opacity="0.22"></stop>
9
+ <stop offset="100%" stop-color="#ffffff" stop-opacity="0"></stop>
10
+ </radialGradient>
11
+ <radialGradient id="core" cx="38%" cy="32%" r="75%">
12
+ <stop offset="0%" stop-color="#fffdf6"></stop>
13
+ <stop offset="48%" stop-color="#eee3cc"></stop>
14
+ <stop offset="100%" stop-color="#b5a888"></stop>
15
+ </radialGradient>
16
+ <radialGradient id="node" cx="36%" cy="30%" r="80%">
17
+ <stop offset="0%" stop-color="#f8dca8"></stop>
18
+ <stop offset="52%" stop-color="#d3a85f"></stop>
19
+ <stop offset="100%" stop-color="#9b6f2f"></stop>
20
+ </radialGradient>
21
+ <linearGradient id="tube" x1="0%" y1="0%" x2="0%" y2="100%">
22
+ <stop offset="0%" stop-color="#fffaf0"></stop>
23
+ <stop offset="52%" stop-color="#efe7d6"></stop>
24
+ <stop offset="100%" stop-color="#cabf9f"></stop>
25
+ </linearGradient>
26
+ <filter id="sh" x="-30%" y="-30%" width="160%" height="160%">
27
+ <feDropShadow dx="0" dy="1.1" stdDeviation="1.1" flood-color="#000000" flood-opacity="0.45"></feDropShadow>
28
+ </filter>
29
+ <clipPath id="tc"><rect x="0" y="0" width="100" height="100" rx="22.5"></rect></clipPath>
7
30
  </defs>
8
- <rect x="2.5" y="2.5" width="27" height="27" rx="9" ry="9" fill="url(#bg)" stroke="#000000" stroke-opacity="0.24" stroke-width="1"/>
9
- <rect x="3" y="3" width="26" height="26" rx="8.5" ry="8.5" fill="none" stroke="#ffffff" stroke-opacity="0.18" stroke-width="1"/>
10
- <path d="M16 5.7 26.8 12.1 16 16.5 5.2 12.1Z" fill="#fff9ed"/>
11
- <path d="M16 14.2 26.5 19.3 16 22.4 5.5 19.3Z" fill="#fff9ed"/>
12
- <path d="M16 20 25.4 24.6 16 27 6.6 24.6Z" fill="#fff9ed"/>
13
- </svg>
31
+ <g clip-path="url(#tc)">
32
+ <rect x="0" y="0" width="100" height="100" fill="url(#tile)"></rect>
33
+ <rect x="0" y="0" width="100" height="100" fill="url(#shine)"></rect>
34
+ <g fill="none" stroke="url(#tube)" stroke-linecap="round" filter="url(#sh)">
35
+ <circle cx="50" cy="50" r="17" stroke-width="5" stroke-dasharray="78 29" transform="rotate(-35 50 50)" stroke-opacity="0.92"></circle>
36
+ <circle cx="50" cy="50" r="30" stroke-width="5" stroke-dasharray="150 39" transform="rotate(70 50 50)" stroke-opacity="0.8"></circle>
37
+ </g>
38
+ <circle cx="50" cy="50" r="7" fill="url(#core)"></circle>
39
+ <circle cx="50" cy="20" r="5.6" fill="url(#node)"></circle>
40
+ <circle cx="48" cy="18.4" r="1.7" fill="#fff7e6" fill-opacity="0.8"></circle>
41
+ </g>
42
+ <rect x="0.6" y="0.6" width="98.8" height="98.8" rx="22" fill="none" stroke="#ffffff" stroke-opacity="0.16" stroke-width="1.2"></rect>
43
+ </svg>
Binary file
Binary file
@@ -28,10 +28,16 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
28
28
  Win32Window::Point origin(10, 10);
29
29
  Win32Window::Size size(1280, 720);
30
30
  if (!window.Create(L"NeoAgent", origin, size)) {
31
+ ::MessageBoxW(nullptr,
32
+ L"NeoAgent failed to start. The Flutter engine could not be "
33
+ L"initialized. Ensure the application was installed correctly "
34
+ L"and all required files are present.",
35
+ L"NeoAgent — Startup Error",
36
+ MB_OK | MB_ICONERROR);
31
37
  ::CoUninitialize();
32
38
  return EXIT_FAILURE;
33
39
  }
34
- window.SetQuitOnClose(false);
40
+ window.SetQuitOnClose(true);
35
41
 
36
42
  ::MSG msg;
37
43
  while (true) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neoagent",
3
- "version": "2.4.1-beta.22",
3
+ "version": "2.4.1-beta.24",
4
4
  "description": "Proactive personal AI agent with no limits",
5
5
  "license": "AGPL-3.0-only",
6
6
  "main": "server/index.js",
@@ -1 +1 @@
1
- fba7f11f026fd312d6f63282ecee7a80
1
+ e796a3361ee4c1400233d7b77f85fb77
Binary file