neoagent 2.4.1-beta.9 → 2.4.1
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/.env.example +33 -3
- package/LICENSE +111 -56
- package/README.md +8 -3
- package/docs/configuration.md +8 -0
- package/docs/getting-started.md +9 -3
- package/docs/index.md +4 -0
- package/extensions/chrome-browser/background.mjs +36 -4
- package/extensions/chrome-browser/icons/icon128.png +0 -0
- package/extensions/chrome-browser/icons/icon16.png +0 -0
- package/extensions/chrome-browser/icons/icon48.png +0 -0
- package/extensions/chrome-browser/icons/logo.svg +39 -8
- package/extensions/chrome-browser/manifest.json +3 -3
- package/extensions/chrome-browser/popup.html +5 -1
- package/extensions/chrome-browser/popup.js +13 -0
- package/flutter_app/android/app/src/main/AndroidManifest.xml +2 -1
- package/flutter_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/flutter_app/assets/branding/app_icon_1024.png +0 -0
- package/flutter_app/assets/branding/app_icon_128.png +0 -0
- package/flutter_app/assets/branding/app_icon_192.png +0 -0
- package/flutter_app/assets/branding/app_icon_256.png +0 -0
- package/flutter_app/assets/branding/app_icon_32.png +0 -0
- package/flutter_app/assets/branding/app_icon_512.png +0 -0
- package/flutter_app/assets/branding/app_icon_64.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_1024.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_128.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_192.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_256.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_32.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_512.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_64.png +0 -0
- package/flutter_app/assets/branding/onboarding_intro.mp4 +0 -0
- package/flutter_app/assets/branding/tray_icon_light_template.png +0 -0
- package/flutter_app/assets/branding/tray_icon_template.png +0 -0
- package/flutter_app/lib/features/location/location_service.dart +3 -0
- package/flutter_app/lib/features/onboarding/onboarding_chrome.dart +391 -382
- package/flutter_app/lib/features/onboarding/onboarding_companion_step.dart +743 -0
- package/flutter_app/lib/features/onboarding/onboarding_messaging_step.dart +18 -16
- package/flutter_app/lib/features/onboarding/onboarding_model_step.dart +19 -18
- package/flutter_app/lib/features/onboarding/onboarding_shell.dart +8 -1
- package/flutter_app/lib/features/onboarding/onboarding_video_step.dart +16 -13
- package/flutter_app/lib/features/onboarding/onboarding_welcome_step.dart +17 -13
- package/flutter_app/lib/main.dart +2 -0
- package/flutter_app/lib/main_account_settings.dart +10 -34
- package/flutter_app/lib/main_admin.dart +14 -1
- package/flutter_app/lib/main_app_shell.dart +377 -340
- package/flutter_app/lib/main_chat.dart +707 -227
- package/flutter_app/lib/main_controller.dart +197 -42
- package/flutter_app/lib/main_devices.dart +436 -4
- package/flutter_app/lib/main_integrations.dart +255 -6
- package/flutter_app/lib/main_launcher.dart +1 -1
- package/flutter_app/lib/main_model_picker.dart +685 -0
- package/flutter_app/lib/main_models.dart +212 -0
- package/flutter_app/lib/main_navigation.dart +1 -9
- package/flutter_app/lib/main_operations.dart +1417 -614
- package/flutter_app/lib/main_settings.dart +673 -871
- package/flutter_app/lib/main_shared.dart +971 -443
- package/flutter_app/lib/main_spacing.dart +4 -4
- package/flutter_app/lib/main_theme.dart +22 -14
- package/flutter_app/lib/main_unified.dart +5 -72
- package/flutter_app/lib/src/android_apk_drop_zone.dart +24 -0
- package/flutter_app/lib/src/android_apk_drop_zone_stub.dart +13 -0
- package/flutter_app/lib/src/android_apk_drop_zone_web.dart +219 -0
- package/flutter_app/lib/src/backend_client.dart +46 -0
- package/flutter_app/lib/src/desktop_companion_actions.dart +30 -7
- package/flutter_app/lib/src/desktop_companion_io.dart +71 -1
- package/flutter_app/lib/src/security/password_strength.dart +84 -0
- package/flutter_app/lib/src/stream_renderer.dart +42 -3
- package/flutter_app/lib/src/theme/palette.dart +76 -34
- package/flutter_app/linux/runner/resources/app_icon.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png +0 -0
- package/flutter_app/pubspec.lock +2 -2
- package/flutter_app/pubspec.yaml +7 -1
- package/flutter_app/tool/branding_source/neoagent-icon-1024.png +0 -0
- package/flutter_app/tool/branding_source/neoagent-icon-128.png +0 -0
- package/flutter_app/tool/branding_source/neoagent-icon-16.png +0 -0
- package/flutter_app/tool/branding_source/neoagent-icon-180.png +0 -0
- package/flutter_app/tool/branding_source/neoagent-icon-192.png +0 -0
- package/flutter_app/tool/branding_source/neoagent-icon-256.png +0 -0
- package/flutter_app/tool/branding_source/neoagent-icon-32.png +0 -0
- package/flutter_app/tool/branding_source/neoagent-icon-48.png +0 -0
- package/flutter_app/tool/branding_source/neoagent-icon-512.png +0 -0
- package/flutter_app/tool/branding_source/neoagent-icon-64.png +0 -0
- package/flutter_app/tool/branding_source/neoagent-icon.svg +43 -0
- package/flutter_app/tool/generate_desktop_branding.py +154 -152
- package/flutter_app/web/favicon.png +0 -0
- package/flutter_app/web/favicon.svg +40 -9
- package/flutter_app/web/favicon_light.svg +43 -0
- package/flutter_app/web/icons/Icon-192-light.png +0 -0
- package/flutter_app/web/icons/Icon-192.png +0 -0
- package/flutter_app/web/icons/Icon-512-light.png +0 -0
- package/flutter_app/web/icons/Icon-512.png +0 -0
- package/flutter_app/web/icons/Icon-maskable-192-light.png +0 -0
- package/flutter_app/web/icons/Icon-maskable-192.png +0 -0
- package/flutter_app/web/icons/Icon-maskable-512-light.png +0 -0
- package/flutter_app/web/icons/Icon-maskable-512.png +0 -0
- package/flutter_app/windows/runner/main.cpp +7 -1
- package/flutter_app/windows/runner/resources/app_icon.ico +0 -0
- package/lib/manager.js +445 -83
- package/package.json +17 -3
- package/runtime/paths.js +3 -1
- package/server/admin/access.js +198 -0
- package/server/admin/admin.css +268 -0
- package/server/admin/admin.js +348 -0
- package/server/admin/analytics.js +128 -0
- package/server/admin/index.html +1015 -0
- package/server/admin/login.html +290 -0
- package/server/admin/logo.svg +43 -0
- package/server/admin/sql.js +134 -0
- package/server/admin/users.js +147 -0
- package/server/config/origins.js +3 -1
- package/server/db/database.js +92 -0
- package/server/db/ftsQuery.js +27 -0
- package/server/http/routes.js +1 -0
- package/server/http/static.js +23 -6
- package/server/index.js +1 -1
- package/server/middleware/adminAuth.js +48 -0
- package/server/middleware/auth.js +1 -40
- package/server/public/.last_build_id +1 -1
- package/server/public/app_icon.png +0 -0
- package/server/public/assets/AssetManifest.bin +1 -1
- package/server/public/assets/AssetManifest.bin.json +1 -1
- package/server/public/assets/assets/branding/app_icon_1024.png +0 -0
- package/server/public/assets/assets/branding/app_icon_256.png +0 -0
- package/server/public/assets/assets/branding/app_icon_512.png +0 -0
- package/server/public/assets/assets/branding/app_icon_light_1024.png +0 -0
- package/server/public/assets/assets/branding/app_icon_light_256.png +0 -0
- package/server/public/assets/assets/branding/app_icon_light_512.png +0 -0
- package/server/public/assets/assets/branding/onboarding_intro.mp4 +0 -0
- package/server/public/assets/assets/branding/tray_icon_light_template.png +0 -0
- package/server/public/assets/assets/branding/tray_icon_template.png +0 -0
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/assets/web/icons/Icon-192.png +0 -0
- package/server/public/favicon.png +0 -0
- package/server/public/favicon.svg +40 -9
- package/server/public/favicon_light.svg +43 -0
- package/server/public/flutter_bootstrap.js +2 -2
- package/server/public/icons/Icon-192-light.png +0 -0
- package/server/public/icons/Icon-192.png +0 -0
- package/server/public/icons/Icon-512-light.png +0 -0
- package/server/public/icons/Icon-512.png +0 -0
- package/server/public/icons/Icon-maskable-192-light.png +0 -0
- package/server/public/icons/Icon-maskable-192.png +0 -0
- package/server/public/icons/Icon-maskable-512-light.png +0 -0
- package/server/public/icons/Icon-maskable-512.png +0 -0
- package/server/public/main.dart.js +88537 -85936
- package/server/routes/admin.js +632 -0
- package/server/routes/agent_profiles.js +3 -0
- package/server/routes/agents.js +1 -1
- package/server/routes/auth.js +3 -1
- package/server/routes/mcp.js +29 -13
- package/server/routes/memory.js +23 -1
- package/server/routes/messaging.js +2 -0
- package/server/routes/screenHistory.js +14 -8
- package/server/routes/settings.js +10 -2
- package/server/routes/stream.js +1 -1
- package/server/routes/triggers.js +4 -4
- package/server/routes/voice_assistant.js +36 -1
- package/server/routes/workspace.js +86 -0
- package/server/services/account/admin_two_factor.js +132 -0
- package/server/services/account/password_policy.js +6 -1
- package/server/services/ai/completion.js +44 -0
- package/server/services/ai/engine.js +321 -500
- package/server/services/ai/imageAnalysis.js +9 -5
- package/server/services/ai/logFormat.js +46 -0
- package/server/services/ai/loopPolicy.js +11 -0
- package/server/services/ai/messagingFallback.js +228 -0
- package/server/services/ai/models.js +194 -55
- package/server/services/ai/providerRetry.js +169 -0
- package/server/services/ai/providers/anthropic.js +15 -4
- package/server/services/ai/providers/google.js +38 -11
- package/server/services/ai/providers/grok.js +19 -68
- package/server/services/ai/providers/grokOauth.js +141 -0
- package/server/services/ai/providers/nvidia.js +154 -0
- package/server/services/ai/providers/ollama.js +76 -39
- package/server/services/ai/providers/openai.js +20 -31
- package/server/services/ai/providers/openaiCodex.js +6 -2
- package/server/services/ai/providers/openaiCompatible.js +70 -0
- package/server/services/ai/providers/openrouter.js +162 -0
- package/server/services/ai/settings.js +30 -0
- package/server/services/ai/systemPrompt.js +51 -29
- package/server/services/ai/taskAnalysis.js +60 -1
- package/server/services/ai/toolEvidence.js +207 -0
- package/server/services/ai/toolSelector.js +8 -1
- package/server/services/ai/tools.js +78 -13
- package/server/services/browser/extension/registry.js +94 -9
- package/server/services/desktop/registry.js +104 -1
- package/server/services/desktop/screenRecorder.js +208 -98
- package/server/services/desktop/screen_recorder_support.js +46 -0
- package/server/services/integrations/google/provider.js +13 -0
- package/server/services/integrations/home_assistant/constants.js +88 -0
- package/server/services/integrations/home_assistant/network.js +207 -0
- package/server/services/integrations/home_assistant/provider.js +249 -0
- package/server/services/integrations/home_assistant/snapshot.js +98 -0
- package/server/services/integrations/home_assistant/tools.js +101 -0
- package/server/services/integrations/manager.js +5 -0
- package/server/services/integrations/registry.js +2 -0
- package/server/services/integrations/trello/provider.js +8 -2
- package/server/services/manager.js +51 -53
- package/server/services/mcp/client.js +208 -268
- package/server/services/mcp/client_support.js +172 -0
- package/server/services/mcp/recovery.js +116 -0
- package/server/services/mcp/tool_operations.js +123 -0
- package/server/services/memory/ingestion.js +185 -370
- package/server/services/memory/ingestion_coverage.js +129 -0
- package/server/services/memory/ingestion_documents.js +123 -0
- package/server/services/memory/ingestion_support.js +171 -0
- package/server/services/memory/intelligence.js +181 -0
- package/server/services/memory/manager.js +476 -32
- package/server/services/messaging/automation.js +71 -134
- package/server/services/messaging/formatting_guides.js +26 -1
- package/server/services/messaging/inbound_queue.js +111 -0
- package/server/services/messaging/manager.js +25 -8
- package/server/services/messaging/typing_keepalive.js +110 -0
- package/server/services/streaming/android-stream.js +293 -40
- package/server/services/tasks/integration_runtime.js +4 -1
- package/server/services/tasks/runtime.js +415 -56
- package/server/services/tasks/task_repository.js +48 -6
- package/server/services/websocket.js +8 -2
- package/server/services/widgets/service.js +17 -1
- package/server/services/workspace/manager.js +116 -0
- package/server/utils/logger.js +44 -6
- package/server/utils/security.js +3 -0
- package/server/utils/version.js +29 -19
- package/server/services/memory/openhuman_uplift.test.js +0 -98
|
@@ -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
|
|
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"
|
|
@@ -18,172 +18,156 @@ LINUX_ICON_DIR = ROOT / "linux" / "runner" / "resources"
|
|
|
18
18
|
ANDROID_RES_DIR = ROOT / "android" / "app" / "src" / "main" / "res"
|
|
19
19
|
SERVER_PUBLIC_DIR = ROOT.parent / "server" / "public"
|
|
20
20
|
SERVER_PUBLIC_ICONS_DIR = SERVER_PUBLIC_DIR / "icons"
|
|
21
|
+
STATIC_IMG_DIR = ROOT.parent / "static" / "img"
|
|
22
|
+
LANDING_LOGO_PATH = ROOT.parent / "landing" / "assets" / "logo.svg"
|
|
23
|
+
EXTENSION_ICON_DIR = ROOT.parent / "extensions" / "chrome-browser" / "icons"
|
|
24
|
+
EXTENSION_LOGO_PATH = EXTENSION_ICON_DIR / "logo.svg"
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
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)
|
|
25
28
|
TRANSPARENT = (0, 0, 0, 0)
|
|
29
|
+
WHITE = (255, 255, 255, 255)
|
|
30
|
+
BLACK = (0, 0, 0, 255)
|
|
31
|
+
TRAY_TEMPLATE_SIZE = 256
|
|
26
32
|
|
|
27
33
|
|
|
28
|
-
def
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
tx = x / max(size - 1, 1)
|
|
38
|
-
ty = y / max(size - 1, 1)
|
|
39
|
-
t = (tx + ty) / 2
|
|
40
|
-
px[x, y] = (
|
|
41
|
-
int(lerp(ACCENT[0], ACCENT_ALT[0], t)),
|
|
42
|
-
int(lerp(ACCENT[1], ACCENT_ALT[1], t)),
|
|
43
|
-
int(lerp(ACCENT[2], ACCENT_ALT[2], t)),
|
|
44
|
-
255,
|
|
45
|
-
)
|
|
46
|
-
return img
|
|
34
|
+
def ensure_dirs() -> None:
|
|
35
|
+
BRANDING_DIR.mkdir(parents=True, exist_ok=True)
|
|
36
|
+
WEB_ICONS_DIR.mkdir(parents=True, exist_ok=True)
|
|
37
|
+
MAC_ICON_DIR.mkdir(parents=True, exist_ok=True)
|
|
38
|
+
LINUX_ICON_DIR.mkdir(parents=True, exist_ok=True)
|
|
39
|
+
SERVER_PUBLIC_ICONS_DIR.mkdir(parents=True, exist_ok=True)
|
|
40
|
+
STATIC_IMG_DIR.mkdir(parents=True, exist_ok=True)
|
|
41
|
+
LANDING_LOGO_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
42
|
+
EXTENSION_ICON_DIR.mkdir(parents=True, exist_ok=True)
|
|
47
43
|
|
|
48
44
|
|
|
49
|
-
def
|
|
50
|
-
|
|
51
|
-
inner = size - pad * 2
|
|
52
|
-
def point(x: float, y: float) -> tuple[float, float]:
|
|
53
|
-
return (pad + inner * x, pad + inner * y)
|
|
45
|
+
def source_png_path(size: int) -> Path:
|
|
46
|
+
return SOURCE_DIR / f"neoagent-icon-{size}.png"
|
|
54
47
|
|
|
55
|
-
top = [point(0.5, 0.08), point(0.1, 0.3), point(0.5, 0.52), point(0.9, 0.3)]
|
|
56
|
-
middle = [point(0.1, 0.52), point(0.5, 0.74), point(0.9, 0.52)]
|
|
57
|
-
bottom = [point(0.1, 0.72), point(0.5, 0.94), point(0.9, 0.72)]
|
|
58
|
-
return top, middle, bottom, inner
|
|
59
48
|
|
|
49
|
+
def load_source_icon(size: int) -> Image.Image:
|
|
50
|
+
if size in SOURCE_PNG_SIZES and source_png_path(size).exists():
|
|
51
|
+
return Image.open(source_png_path(size)).convert("RGBA")
|
|
52
|
+
source = Image.open(source_png_path(1024)).convert("RGBA")
|
|
53
|
+
return source.resize((size, size), Image.Resampling.LANCZOS)
|
|
60
54
|
|
|
61
|
-
def draw_logo(draw: ImageDraw.ImageDraw, size: int, color: tuple[int, int, int, int]) -> None:
|
|
62
|
-
top, middle, bottom, inner = logo_paths(size)
|
|
63
|
-
stroke = max(2, round(inner * 0.08))
|
|
64
|
-
draw.polygon(top, fill=color)
|
|
65
|
-
draw.line(middle, fill=color, width=stroke, joint="curve")
|
|
66
|
-
draw.line(bottom, fill=color, width=stroke, joint="curve")
|
|
67
55
|
|
|
56
|
+
def save_icon(path: Path, size: int) -> None:
|
|
57
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
58
|
+
image = load_source_icon(size)
|
|
59
|
+
if image.size != (size, size):
|
|
60
|
+
image = image.resize((size, size), Image.Resampling.LANCZOS)
|
|
61
|
+
image.save(path, format="PNG")
|
|
68
62
|
|
|
69
|
-
def make_app_icon(size: int) -> Image.Image:
|
|
70
|
-
canvas = Image.new("RGBA", (size, size), TRANSPARENT)
|
|
71
63
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
radius=corner,
|
|
79
|
-
fill=(0, 0, 0, 72),
|
|
64
|
+
def write_source_svg(path: Path) -> None:
|
|
65
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
66
|
+
svg = SOURCE_SVG.read_text(encoding="utf-8")
|
|
67
|
+
svg = svg.replace(
|
|
68
|
+
'stroke="rgba(255,255,255,0.16)"',
|
|
69
|
+
'stroke="#ffffff" stroke-opacity="0.16"',
|
|
80
70
|
)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
71
|
+
path.write_text(svg, encoding="utf-8")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def draw_scaled_circle(
|
|
75
|
+
draw: ImageDraw.ImageDraw,
|
|
76
|
+
size: int,
|
|
77
|
+
center_x: float,
|
|
78
|
+
center_y: float,
|
|
79
|
+
radius: float,
|
|
80
|
+
color: tuple[int, int, int, int],
|
|
81
|
+
) -> None:
|
|
82
|
+
scale = size / 100
|
|
83
|
+
draw.ellipse(
|
|
84
|
+
(
|
|
85
|
+
(center_x - radius) * scale,
|
|
86
|
+
(center_y - radius) * scale,
|
|
87
|
+
(center_x + radius) * scale,
|
|
88
|
+
(center_y + radius) * scale,
|
|
89
|
+
),
|
|
90
|
+
fill=color,
|
|
101
91
|
)
|
|
102
|
-
canvas.alpha_composite(ring)
|
|
103
|
-
|
|
104
|
-
glyph = Image.new("RGBA", (size, size), TRANSPARENT)
|
|
105
|
-
draw = ImageDraw.Draw(glyph)
|
|
106
|
-
draw_logo(draw, size, WHITE)
|
|
107
|
-
canvas.alpha_composite(glyph)
|
|
108
|
-
return canvas
|
|
109
92
|
|
|
110
93
|
|
|
111
|
-
def make_tray_template(
|
|
94
|
+
def make_tray_template(
|
|
95
|
+
size: int = 64,
|
|
96
|
+
color: tuple[int, int, int, int] = BLACK,
|
|
97
|
+
) -> Image.Image:
|
|
112
98
|
img = Image.new("RGBA", (size, size), TRANSPARENT)
|
|
113
99
|
draw = ImageDraw.Draw(img)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
100
|
+
scale = size / 100
|
|
101
|
+
width = max(2, round(size * 0.078))
|
|
102
|
+
center = 50 * scale
|
|
103
|
+
|
|
104
|
+
draw.arc(
|
|
105
|
+
(
|
|
106
|
+
(50 - 30) * scale,
|
|
107
|
+
(50 - 30) * scale,
|
|
108
|
+
(50 + 30) * scale,
|
|
109
|
+
(50 + 30) * scale,
|
|
110
|
+
),
|
|
111
|
+
start=158,
|
|
112
|
+
end=444,
|
|
113
|
+
fill=color,
|
|
114
|
+
width=width,
|
|
115
|
+
)
|
|
116
|
+
draw.arc(
|
|
117
|
+
(
|
|
118
|
+
(50 - 17) * scale,
|
|
119
|
+
(50 - 17) * scale,
|
|
120
|
+
(50 + 17) * scale,
|
|
121
|
+
(50 + 17) * scale,
|
|
122
|
+
),
|
|
123
|
+
start=68,
|
|
124
|
+
end=330,
|
|
125
|
+
fill=color,
|
|
126
|
+
width=width,
|
|
127
|
+
)
|
|
128
|
+
draw_scaled_circle(draw, size, 50, 50, 7, color)
|
|
129
|
+
draw_scaled_circle(draw, size, 50, 20, 5.6, color)
|
|
130
|
+
|
|
131
|
+
# Slightly round arc ends so the template keeps the supplied logo's soft tube feel.
|
|
132
|
+
end_radius = width / 2
|
|
133
|
+
for x, y in ((77.2, 74.8), (80.0, 41.2), (32.0, 29.7), (68.8, 39.2)):
|
|
134
|
+
draw.ellipse(
|
|
135
|
+
(
|
|
136
|
+
x * scale - end_radius,
|
|
137
|
+
y * scale - end_radius,
|
|
138
|
+
x * scale + end_radius,
|
|
139
|
+
y * scale + end_radius,
|
|
140
|
+
),
|
|
141
|
+
fill=color,
|
|
142
|
+
)
|
|
133
143
|
|
|
144
|
+
# Keep the symbol optically centered inside the menu-bar bounds.
|
|
145
|
+
vertical_offset = round(size * 0.03125)
|
|
146
|
+
return img.crop((0, vertical_offset, size, size + vertical_offset))
|
|
134
147
|
|
|
135
|
-
def write_favicon_svg(path: Path) -> None:
|
|
136
|
-
svg = f"""<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
|
137
|
-
<defs>
|
|
138
|
-
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
139
|
-
<stop offset="0%" stop-color="#{ACCENT[0]:02x}{ACCENT[1]:02x}{ACCENT[2]:02x}"/>
|
|
140
|
-
<stop offset="100%" stop-color="#{ACCENT_ALT[0]:02x}{ACCENT_ALT[1]:02x}{ACCENT_ALT[2]:02x}"/>
|
|
141
|
-
</linearGradient>
|
|
142
|
-
</defs>
|
|
143
|
-
<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"/>
|
|
144
|
-
<polygon points="16,5.7 5.2,11.6 16,17.6 26.8,11.6" fill="white"/>
|
|
145
|
-
<polyline points="5.2,17.6 16,23.5 26.8,17.6" fill="none" stroke="white" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
146
|
-
<polyline points="5.2,22.7 16,28.1 26.8,22.7" fill="none" stroke="white" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
147
|
-
</svg>
|
|
148
|
-
"""
|
|
149
|
-
write_text(path, svg)
|
|
150
148
|
|
|
149
|
+
def main() -> None:
|
|
150
|
+
ensure_dirs()
|
|
151
151
|
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
for size in (1024, 512, 256, 192, 128, 64, 32):
|
|
153
|
+
save_icon(BRANDING_DIR / f"app_icon_{size}.png", size)
|
|
154
|
+
save_icon(BRANDING_DIR / f"app_icon_light_{size}.png", size)
|
|
154
155
|
|
|
156
|
+
make_tray_template(TRAY_TEMPLATE_SIZE).save(
|
|
157
|
+
BRANDING_DIR / "tray_icon_template.png",
|
|
158
|
+
format="PNG",
|
|
159
|
+
)
|
|
160
|
+
make_tray_template(TRAY_TEMPLATE_SIZE, WHITE).save(
|
|
161
|
+
BRANDING_DIR / "tray_icon_light_template.png",
|
|
162
|
+
format="PNG",
|
|
163
|
+
)
|
|
155
164
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
master = make_app_icon(1024)
|
|
159
|
-
|
|
160
|
-
save_png(master, BRANDING_DIR / "app_icon_1024.png", 1024)
|
|
161
|
-
save_png(master, BRANDING_DIR / "app_icon_512.png", 512)
|
|
162
|
-
save_png(master, BRANDING_DIR / "app_icon_256.png", 256)
|
|
163
|
-
save_png(master, BRANDING_DIR / "app_icon_192.png", 192)
|
|
164
|
-
save_png(master, BRANDING_DIR / "app_icon_128.png", 128)
|
|
165
|
-
save_png(master, BRANDING_DIR / "app_icon_64.png", 64)
|
|
166
|
-
save_png(master, BRANDING_DIR / "app_icon_32.png", 32)
|
|
167
|
-
|
|
168
|
-
tray = make_tray_template(64)
|
|
169
|
-
save_png(tray, BRANDING_DIR / "tray_icon_template.png", 64)
|
|
170
|
-
|
|
171
|
-
icon_sizes = {
|
|
172
|
-
16: "app_icon_16.png",
|
|
173
|
-
32: "app_icon_32.png",
|
|
174
|
-
64: "app_icon_64.png",
|
|
175
|
-
128: "app_icon_128.png",
|
|
176
|
-
256: "app_icon_256.png",
|
|
177
|
-
512: "app_icon_512.png",
|
|
178
|
-
1024: "app_icon_1024.png",
|
|
179
|
-
}
|
|
180
|
-
for size, filename in icon_sizes.items():
|
|
181
|
-
save_png(master, MAC_ICON_DIR / filename, size)
|
|
165
|
+
for size in (16, 32, 64, 128, 256, 512, 1024):
|
|
166
|
+
save_icon(MAC_ICON_DIR / f"app_icon_{size}.png", size)
|
|
182
167
|
|
|
183
|
-
|
|
168
|
+
save_icon(LINUX_ICON_DIR / "app_icon.png", 256)
|
|
184
169
|
|
|
185
|
-
|
|
186
|
-
master_for_ico.save(
|
|
170
|
+
load_source_icon(256).save(
|
|
187
171
|
WINDOWS_ICON_PATH,
|
|
188
172
|
format="ICO",
|
|
189
173
|
sizes=[(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)],
|
|
@@ -194,15 +178,33 @@ def main() -> None:
|
|
|
194
178
|
512: "Icon-512.png",
|
|
195
179
|
}
|
|
196
180
|
for size, filename in web_icon_sizes.items():
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
181
|
+
save_icon(WEB_ICONS_DIR / filename, size)
|
|
182
|
+
save_icon(WEB_ICONS_DIR / filename.replace("Icon-", "Icon-maskable-"), size)
|
|
183
|
+
save_icon(WEB_ICONS_DIR / filename.replace(".png", "-light.png"), size)
|
|
184
|
+
save_icon(WEB_ICONS_DIR / filename.replace("Icon-", "Icon-maskable-").replace(".png", "-light.png"), size)
|
|
185
|
+
save_icon(SERVER_PUBLIC_ICONS_DIR / filename, size)
|
|
186
|
+
save_icon(SERVER_PUBLIC_ICONS_DIR / filename.replace("Icon-", "Icon-maskable-"), size)
|
|
187
|
+
|
|
188
|
+
save_icon(WEB_DIR / "favicon.png", 32)
|
|
189
|
+
save_icon(SERVER_PUBLIC_DIR / "favicon.png", 32)
|
|
190
|
+
write_source_svg(WEB_DIR / "favicon.svg")
|
|
191
|
+
write_source_svg(WEB_DIR / "favicon_light.svg")
|
|
192
|
+
write_source_svg(SERVER_PUBLIC_DIR / "favicon.svg")
|
|
193
|
+
write_source_svg(SERVER_PUBLIC_DIR / "favicon_light.svg")
|
|
194
|
+
write_source_svg(LANDING_LOGO_PATH)
|
|
195
|
+
write_source_svg(EXTENSION_LOGO_PATH)
|
|
196
|
+
|
|
197
|
+
for size in (16, 48, 128):
|
|
198
|
+
save_icon(EXTENSION_ICON_DIR / f"icon{size}.png", size)
|
|
199
|
+
|
|
200
|
+
save_icon(STATIC_IMG_DIR / "app_icon.png", 512)
|
|
201
|
+
save_icon(STATIC_IMG_DIR / "app_icon_light.png", 512)
|
|
202
|
+
save_icon(SERVER_PUBLIC_DIR / "assets" / "assets" / "branding" / "app_icon_256.png", 256)
|
|
203
|
+
make_tray_template(TRAY_TEMPLATE_SIZE).save(
|
|
204
|
+
SERVER_PUBLIC_DIR / "assets" / "assets" / "branding" / "tray_icon_template.png",
|
|
205
|
+
format="PNG",
|
|
206
|
+
)
|
|
207
|
+
save_icon(SERVER_PUBLIC_DIR / "assets" / "web" / "icons" / "Icon-192.png", 192)
|
|
206
208
|
|
|
207
209
|
android_icon_sizes = {
|
|
208
210
|
"mipmap-mdpi": 48,
|
|
@@ -212,7 +214,7 @@ def main() -> None:
|
|
|
212
214
|
"mipmap-xxxhdpi": 192,
|
|
213
215
|
}
|
|
214
216
|
for folder, size in android_icon_sizes.items():
|
|
215
|
-
|
|
217
|
+
save_icon(ANDROID_RES_DIR / folder / "ic_launcher.png", size)
|
|
216
218
|
|
|
217
219
|
|
|
218
220
|
if __name__ == "__main__":
|
|
Binary file
|
|
@@ -1,12 +1,43 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 100 100">
|
|
2
2
|
<defs>
|
|
3
|
-
<linearGradient id="
|
|
4
|
-
<stop offset="0%" stop-color="#
|
|
5
|
-
<stop offset="100%" stop-color="#
|
|
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
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 100 100">
|
|
2
|
+
<defs>
|
|
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
|
+
</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>
|
|
30
|
+
</defs>
|
|
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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
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(
|
|
40
|
+
window.SetQuitOnClose(true);
|
|
35
41
|
|
|
36
42
|
::MSG msg;
|
|
37
43
|
while (true) {
|
|
Binary file
|