Остання активність 1786915903

What features should we make to deliver a productivity tool for multipc multimonitor work. Copy and paste works, this is a time saving application. Let's save time for anyone who uses this app. List features and other tasks to complete this project and save it all in SUMMARY.md

Версія 55f3cffcce36644c092d8d7c4b5a7dab54e2f5b1

Qwen-SUMMARY.md Неформатований

EnvoyOS — Multi-PC, Multi-Monitor Productivity Suite

A productivity-focused desktop application built with Godot 4.6. Designed for engineers and knowledge workers who work across multiple PCs and monitors. The core value proposition: every keystroke, file, and timer is one hop away regardless of which machine you're sitting at.


Project Highlights

  • All-in-One Toolkit: AI tools, clipboard sync, file transfer, timers, inventory tracking, video/audio settings, and built-in support documentation in a single interface.
  • Modular Architecture: Clean separation between logic (*_engine.gd) and UI (*_ui.gd) ensures scalability and easy maintenance.
  • Cross-PC Sync: ENet-based multiplayer with AES-256 encrypted clipboard, planned file transfer, and shared state.
  • Multi-Monitor Aware: DPI scaling, per-monitor layout memory, window tiling, and floating overlays.
  • AI Integration: Local Ollama-powered code assistant, suggestions, and (planned) transcription.

Why Support?

Developing and maintaining open-source tools takes time, effort, and resources. Your support directly funds:

  • New feature development & bug fixes
  • Performance optimizations & engine updates
  • Documentation & community resources

Every contribution, no matter the size, helps keep this project growing and accessible to everyone. Thank you for your support! ☕✨


Current State

Completed / Working

Module Status
Clipboard sync (ENet + AES-256) ✅ Working
AI Chat (Ollama streaming) ✅ Working
Markdown Editor (autosave) ✅ Working
VoIP (UDP, VAD, jitter buffer) 🚧 In Progress
Audio settings (volume, mute, mic level) 🚧 In Progress
Timer panel (12 slots, fuel-bar UI) ✅ Working
Inventory panel (12 slots, fuel-bar UI) 🚧 In Progress
Tab management (custom tab bar, session persistence) ✅ Working
OS Grid layout (configurable rows × cols) 🚧 In Progress
Theme builder (bg/font/accent/shade/transparency) ✅ Working
Video settings (FPS, DPI, window mode, position, size) ✅ Working
Web tab browser (paginated Chrome export) 🚧 In Progress
Ship game (2D physics, object pooling) ✅ Working
TOP / Power state tracker 🚧 In Progress
User AFK detection (cross-platform) ✅ Working
Window drag/resize (borderless) ✅ Working
System tray minimization ✅ Working

Missing / Stub (Blocking)

File Status Action Required
system_engine.gd Empty Implement CPU/RAM/disk/GPU stats
system_ui.gd Empty Build system dashboard (CPU graph, RAM bar, disk, AFK)
ai_code_engine.gd Empty Build code-gen/review/explain engine
ai_code_ui.gd Empty Side-by-side code editor + AI panel
music_engine.gd extends Node only Implement playback queue, seeking, shuffle

Known Bugs / Technical Debt

Issue Location Fix
grid_engine.gd references clipboard_engine.is_connected_to_network (doesn't exist) grid_engine.gd line ~230 Change to clipboard_engine.can_broadcast / clipboard_engine.is_connecting
tab_engine.gd and top_engine.gd are 95% duplicates Both files Merge into one class or have TopEngine extend TabEngine
No input validation on VoIP port field voip_ui.gd Add is_valid_int() check before int() cast
Timer/Inventory hh:mm:ss parse has no overflow guard time_ui.gd, inventory_ui.gd Validate h≤23, m≤59, s≤59 before arithmetic
Music/Media tab is a dead tab main_engine.gd ALL_TABS Either implement or remove from list
No CI / automated testing Repo root Add GitHub Actions with godot --headless --check-only

Feature Roadmap

Phase 1 — Fix & Stabilise (Weeks 1–2)

# Task Details
1.1 Implement system_engine.gd CPU %, RAM used/total, disk usage, GPU load (platform-specific), network throughput. Emit signals for UI.
1.2 Implement system_ui.gd Dashboard with live-updating gauges, AFK timer (reuse user_active_engine.gd), process list (optional).
1.3 Fix grid_engine.gd broken refs Replace is_connected_to_networkcan_broadcast, is_reconnectingis_connecting.
1.4 Merge tab_engine / top_engine One base class, reduce duplication.
1.5 Add input validation VoIP port, Timer/Inventory time parsing, all user-facing number fields.
1.6 Implement or remove Music tab Either build music_engine.gd + wire music_ui.gd, or remove "Media" from ALL_TABS.
1.7 Add unit tests (GUT) ThemeSerializer round-trip, TabEngine CRUD, TimeEngine tick, InventoryEngine expiry, ClipboardEngine encrypt/decrypt.
1.8 CI pipeline GitHub Actions: godot --headless --check-only + GUT test run on push.

Phase 2 — Multi-PC Power Features (Weeks 3–6)

# Task Details
2.1 Clipboard History Ring Buffer Store last 100 items (text + images) with timestamp, source PC, app name. Global hotkey Ctrl+Shift+V opens searchable picker across all peers.
2.2 Snippet Library Save frequently-used text blocks (code snippets, email templates, API keys). Sync to all PCs. One-click paste.
2.3 Cross-PC Text Search Type a keyword → search all peers' clipboard history simultaneously via RPC.
2.4 P2P File Transfer Drag file onto Network tab → AES-256 encrypt → chunked ENet stream → progress bar → destination PC. Reuse existing crypto.
2.5 Shared Workspace Folder Synced directory (chunked transfer). Edit on PC-A, open on PC-B.
2.6 Shared Kanban Board To-Do / In-Progress / Done. RPC-synced in real-time. Cards: title, tags, due date, assigned PC. Reuse clipboard_engine RPC pattern.
2.7 Notification Mirroring System/app notifications broadcast to all peers. "PC-A idle > 10 min" → toast on PC-B. Timer expiry → alert all.
2.8 Command Palette (Ctrl+K) Fuzzy-search all actions: "open tab", "change theme", "start timer 3", "connect to PC-B", "mute audio". One keystroke to do anything.
2.9 Global Hotkeys (OS-level) Register via native helper: clipboard history, screenshot, quick paste. Works even when app is unfocused.
2.10 Offline Queue When disconnected, queue clipboard/file/task changes. Auto-sync on reconnect (extend existing reconnection logic).

Phase 3 — Multi-Monitor & AI (Weeks 7–10)

# Task Details
3.1 Monitor Layout Memory Detect monitors, save per-monitor window positions/sizes per panel. Restore on reconnect. user://monitor_layout.json.
3.2 Floating Overlays Always-on-top widgets: timer countdown, clipboard dock (last 5 items), AFK indicator glow. Assignable to specific monitor.
3.3 Window Tiling / Snapping Ctrl+1..4 → quadrant. Ctrl+Shift+Left/Right → half. Save/load named layouts. Ctrl+L to cycle.
3.4 Per-Monitor Contrast Each monitor can have different shade/brightness. Auto-adjust based on ambient light or time-of-day.
3.5 AI Code Engine ai_code_engine.gd: Explain selected code, Refactor + diff view, Generate from prompt, Review PR diff. Reuse Ollama streaming client.
3.6 AI Code UI ai_code_ui.gd: Side-by-side editor + AI response panel. Syntax highlighting, diff view, copy-to-clipboard.
3.7 AI Meeting Notes Stream mic audio → local Whisper (Ollama-compatible) → bullet-point summary → sync to all peers.
3.8 Cross-PC Input Mirroring (KVM) Type on PC-A → keystrokes stream to PC-B. Mouse delta streaming (relative, not absolute). Per-peer toggle.
3.9 AI Suggestion Engine Wire existing "Suggestion" prompt field to a "Smart Suggestions" button on clipboard tab. 3 context-aware actions.

Phase 4 — Polish & Release (Weeks 11–12)

# Task Details
4.1 Auto-start with OS Registry key (Win), .desktop file (Linux), LaunchAgent (macOS).
4.2 System Tray Menu "Show", "Mute", "Disconnect", "Open Timer", "Open Kanban", "Exit".
4.3 Backup / Restore One-click export all user:// settings to .zip. Import on new PC.
4.4 Accessibility Pass High-contrast mode, UI font scaling, screen-reader labels on all controls.
4.5 Session Replay Record 10s UI interaction replay as JSON for bug reports.
4.6 User Documentation Expand SUMMARY.md → full user manual. Keyboard shortcut reference. Setup guide per OS.
4.7 Export / Packaging godot --export-release for Windows / Linux / macOS. In-app updater (optional).

Phase 5 — Differentiators (Ongoing)

# Feature Description
5.1 Screen recording per monitor GPU capture, "record this monitor" toggle, export to file.
5.2 Screenshot + AI annotate Capture region → send to Ollama → written description.
5.3 Pomodoro focus mode 25/5 preset. Auto-pauses AI streaming and network sync during focus.
5.4 Dark-light auto-switch Theme tied to system clock (dark after 18:00).
5.5 Peer presence bar Avatar strip showing online PCs (reuse multiplayer.get_peers()).
5.6 Voice commands "Hey, paste the last email" → VAD → match snippet → paste.
5.7 Shared timer countdown Timer on PC-A shows live on PC-B. Sync end_timestamp over network.
5.8 Calendar view Timers/inventory deadlines on a mini monthly calendar.
5.9 CSV export Timer/inventory state as CSV for spreadsheet tracking.
5.10 Low-stock alerts Inventory item below threshold → red flag on all PCs.

Architecture Notes

┌─────────────────────────────────────────────────────────────────────┐
│                        MainUI / GridUI (Root)                        │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  TabBar / Grid Toolbar                                         │  │
│  └───────────────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  TabContainer / Content Area                                   │  │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐            │  │
│  │  │ AI Chat │ │ Editor  │ │ Network │ │  Timer  │  ...        │  │
│  │  └─────────┘ └─────────┘ └─────────┘ └─────────┘            │  │
│  └───────────────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────────────┐  │
│  │  Engines (Nodes)                                               │  │
│  │  clipboard_engine │ ai_engine │ video_engine │ audio_engine    │  │
│  │  mic_engine │ web_engine │ time_engine │ inventory_engine     │  │
│  │  ui_engine │ top_engine │ tab_engine │ voip_engine            │  │
│  └───────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────┘

Network Layer: ENet (MultiplayerPeer) + AES-256 (AESContext)
Persistence:   ConfigFile (*.cfg) + JSON (*.json) + CSV (timers/inventory)
Theme:         ThemeSerializer (compressed JSON, hex colors, FastLZ)

Supported Platforms

OS Clipboard Audio Idle Detection Network
Windows WASAPI GetLastInputInfo (P/Invoke) ENet
macOS CoreAudio IOHIDSystem (ioreg) ENet
Linux PipeWire/PulseAudio D-Bus (Mutter/KWin) / xprintidle ENet

Keyboard Shortcuts (Planned)

Shortcut Action
Ctrl+K Command Palette
Ctrl+Shift+V Clipboard History (cross-PC)
Ctrl+1..4 Snap to quadrant
Ctrl+Shift+Left/Right Snap to half
Ctrl+L Cycle saved layouts
Ctrl+W / close_tab Close current tab
Ctrl+T / new_tab New tab
Ctrl+Tab / Ctrl+Shift+Tab Next / Previous tab

Why This Saves Time

Pain Point Solution Time Saved
Copy on PC-A, walk to PC-B, paste Cross-PC clipboard sync 30s–2min per transfer
Re-type same email/snippet on each machine Snippet library + one-click paste 1–5min per repetition
"Where did I save that file?" Shared workspace + cross-PC search 5–15min per search
Set up different configs per monitor Monitor layout memory + auto-restore 5–10min per session
Explain code to colleague on another screen AI explain + share to all PCs 5–10min per explanation
Track physical inventory across desk drawers Shared inventory with expiry alerts Ongoing
"Did I finish that task?" Shared Kanban visible on all PCs 2–5min per check
Context-switch between 4 monitors on 2 PCs Window tiling + input mirroring 1–3min per switch

Contribution Guidelines

  1. Read AIFIX.md for Godot 4.6 API corrections before editing.
  2. Follow the *_engine.gd / *_ui.gd naming convention.
  3. All new UI must handle tab-switch cleanup (check for existing wrapper before adding).
  4. Network changes must go through clipboard_engine.gd RPC pattern (or the new MultiplayerChannel helper).
  5. Theme changes must flow through ui_engine.gdMainUI.apply_full_theme().
  6. Run tests: godot --headless -s res://addons/gut/gut_cmdln.gd -gdir=res://tests

License & Attribution

See repository for license file. Built with ❤️ and too much coffee. ☕

z-Godot-Convention.md Неформатований

Godot 4.7 — Project Conventions & API Reference

A reference document for the EnvoyOS project targeting Godot 4.7. Derived from the official Godot 4.7 documentation structure and the project's AIFIX.md corrections.


Table of Contents

  1. GDScript Syntax & Type Hints
  2. Node Lifecycle
  3. Signals
  4. Input Handling
  5. Controls & UI
  6. Window Management
  7. Audio
  8. Networking (Multiplayer)
  9. File I/O
  10. Resources & Loading
  11. Performance
  12. Style Conventions
  13. Common Pitfalls & Corrections

1. GDScript Syntax & Type Hints

Typed Arrays

# WRONG (Godot 3 style, inferred empty array)
var rocks := []

# CORRECT (Godot 4.7 explicit type)
var rocks: Array[Label] = []
var items: Array[Dictionary] = []
var names: Array[String] = []
var scales: Array[float] = []

Variable Declarations

# Prefer explicit types over := inference when the type is unambiguous
var file: FileAccess = FileAccess.open(path, FileAccess.READ)
var parsed: Variant = JSON.parse_string(json_str)

# Use := only when the right-hand side type is clear
var btn := Button.new()
var style := StyleBoxFlat.new()

Color Construction

# WRONG
col.color = Color.rand()

# CORRECT
col.color = Color(randf(), randf(), randf())

Global Functions (Not Methods)

# WRONG (clampf is a global function, not a method on float)
_transparency_multiplier = value.clampf(0.0, 1.0)

# CORRECT
_transparency_multiplier = clampf(value, 0.0, 1.0)
# OR
_transparency_multiplier = clamp(value, 0.0, 1.0)

Vector Operations

# WRONG (ceiled() does not exist on Vector2)
var target := vec.ceiled()

# CORRECT
var target := Vector2i(vec.ceil())

Async/Await

# WRONG (yield was removed in Godot 4)
yield(get_tree().process_frame, "process_frame")

# CORRECT
await get_tree().process_frame

Process Delta Time

# WRONG (throws error)
var speed = Node.get_process_delta_time()

# CORRECT
var speed = get_process_delta_time()

Constants & Enums

const MAX_ITEMS := 12
const CONFIG_PATH := "user://inventory_config.cfg"

enum PowerState {
    OFF = 0,
    LOW = 1,
    NETWORK = 2,
    HIGH = 3,
}

2. Node Lifecycle

Key Notifications (Godot 4.7)

func _notification(what: int) -> void:
    match what:
        NOTIFICATION_WM_CLOSE_REQUEST:
            # Window close (replaces NOTIFICATION_WM_QUIT_REQUEST)
            pass
        NOTIFICATION_APPLICATION_PAUSED, NOTIFICATION_APPLICATION_FOCUS_OUT:
            # App backgrounded / lost focus
            pass
        NOTIFICATION_APPLICATION_RESUMED, NOTIFICATION_APPLICATION_FOCUS_IN:
            # App foregrounded / regained focus
            pass

Process Mode (Replaces Old Pause Mode)

# WRONG
timer.pause_mode = Timer.PAUSE_MODE_PROCESS

# CORRECT
timer.process_mode = Node.PROCESS_MODE_ALWAYS

Dialogs and Timers

# When a ConfirmationDialog is shown via popup_centered(),
# the SceneTree pauses. Timers inside will stop unless:
dialog.process_mode = Node.PROCESS_MODE_ALWAYS

Node Creation and Freeing

# To clear a container's children (VBoxContainer has no .clear() in Godot 4)
# WRONG
kitchen_sink_box.clear()

# CORRECT
for child in container.get_children():
    child.queue_free()

Safe Instance Checks

# After any await or deferred call, verify the object still exists
if is_instance_valid(node) and node.is_inside_tree():
    node.do_something()

3. Signals

Declaration

signal item_updated(index: int)
signal stats_updated(latency_ms: float, jitter: float, packet_loss: float)

Connecting (with type-safe lambdas)

btn.pressed.connect(_on_button_pressed.bind(index))
slider.value_changed.connect(func(val: float): _on_slider(val))

Disconnecting

if signal_name in node.get_signal_connection_list(sig):
    node.disconnect(sig, callable)

RPC (Multiplayer)

@rpc("any_peer", "unreliable_ordered")
func receive_secure_clipboard(encrypted_data: PackedByteArray) -> void:
    pass

# Call from any peer:
rpc("receive_secure_clipboard", data)

4. Input Handling

Key Codes (Godot 4.7)

if event is InputEventKey and event.keycode == KEY_TAB and Input.is_key_pressed(KEY_CTRL):
    pass

Touchscreen

# WRONG
Input.is_touchscreen_available()

# CORRECT
DisplayServer.is_touchscreen_available()

WebRTC Feature Check

# WRONG
Engine.has_feature("web_view")

# CORRECT
OS.has_feature("web") or ClassDB.class_exists("WebRTCPeerConnection")

Mouse Position (Global vs Local)

# For window-level calculations (resize, drag), use GLOBAL screen coords:
var global_mouse: Vector2 = DisplayServer.mouse_get_position()

# For UI-local calculations:
var local_mouse: Vector2 = get_viewport().get_mouse_position()

5. Controls & UI

StyleBoxFlat (Per-Corner, Per-Side)

# WRONG (Godot 3 properties do not exist in 4.7)
style.border_width_all = 2
style.corner_radius_all = 16

# CORRECT (individual properties)
style.border_width_left = 2
style.border_width_right = 2
style.border_width_top = 2
style.border_width_bottom = 2
style.corner_radius_top_left = 16
style.corner_radius_top_right = 16
style.corner_radius_bottom_left = 16
style.corner_radius_bottom_right = 16

StyleBox Copying

# WRONG
var hover_style = StyleBoxFlat.new(style)

# CORRECT
var hover_style = style.duplicate()

TextEdit Wrapping

# WRONG
system_input.fit_content_width = true

# CORRECT
system_input.wrap_mode = TextEdit.LINE_WRAPPING_BOUNDARY

Tree Items

# WRONG (type inference fails)
var child := control.create_item(root)

# CORRECT
var child: TreeItem = control.create_item(root)

Abstract Classes

# WRONG (Slider is abstract, cannot be constructed)
Slider.new()

# CORRECT
VSlider.new()
HSlider.new()

TabBar Close Buttons

# WRONG (property does not exist)
tab_bar.tabs_closeable = true

# CORRECT
tab_bar.tab_close_display_policy = TabBar.CLOSE_BUTTON_SHOW_ALWAYS
tab_bar.tab_close_pressed.connect(_on_tab_close_pressed)

Hiding TabContainer's Built-in Tab Bar

tab_container.tabs_visible = false

ConfirmationDialog

# Godot 4.7: use get_cancel_button() (not get_cancel())
dialog.get_cancel_button().text = "Cancel"

6. Window Management

V-Sync

# WRONG
DisplayServer.vsync = DisplayServer.VSYNC_ENABLED

# CORRECT
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_ENABLED)

DPI / Content Scaling

# WRONG (size_scale does not exist)
get_window().size_scale = 2.0

# CORRECT
get_window().content_scale_factor = 2.0
# OR for base resolution:
get_window().content_scale_size = Vector2i(1920, 1080)

Window Size (Integer Required)

# Adjust physical window size inversely proportional to scale
var target_size := Vector2i((LOGICAL_BASE_SIZE / scale).ceil())
window.size = target_size

Deferred Window Size (Avoid Startup Race)

window.content_scale_factor = scale
var target_size := Vector2i((LOGICAL_BASE_SIZE / scale).ceil())
window.set_deferred("size", target_size)

Borderless Window

get_window().borderless = true
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, true)

Resize Flag (Windows DWM)

# WRONG (RESIZE flag does not exist as a set-to-true operation)
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_RESIZE, true)

# CORRECT (pass false to RESIZE_DISABLED to ENABLE resizing)
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_RESIZE_DISABLED, false)

Borderless Resize (Global Mouse)

# Must use global screen coordinates for borderless resize
var global_mouse := DisplayServer.mouse_get_position()
var window_top_left := get_window().position
var target_width: int = int(max(global_mouse.x - window_top_left.x, 800))
var target_height: int = int(max(global_mouse.y - window_top_left.y, 500))
get_window().size = Vector2i(target_width, target_height)

Cursor Shapes

DisplayServer.cursor_set_shape(DisplayServer.CURSOR_DRAG)
DisplayServer.cursor_set_shape(DisplayServer.CURSOR_HSIZE)
DisplayServer.cursor_set_shape(DisplayServer.CURSOR_ARROW)

Always on Top

get_window().always_on_top = true

Window Position

DisplayServer.window_set_position(Vector2i(x, y))
# OR
get_window().position = Vector2i(x, y)

7. Audio

Bus Management

AudioServer.add_bus()
AudioServer.set_bus_volume_db(index, db)
AudioServer.set_bus_mute(index, true)
AudioServer.get_bus_count()
AudioServer.get_bus_name(index)

Audio Effects

var capture := AudioEffectCapture.new()
AudioServer.add_bus_effect(bus_index, capture)
AudioServer.set_bus_effect_enabled(bus_index, effect_index, true)

Microphone Input

var mic_stream := AudioStreamMicrophone.new()
player.stream = mic_stream
player.bus = AudioServer.get_bus_name(bus_index)
player.autoplay = true

PCM Playback

var wav := AudioStreamWAV.new()
wav.format = AudioStreamWAV.FORMAT_16_BITS
wav.mix_rate = 48000
wav.stereo = true
wav.set_data(PackedFloat32Array)
player.stream = wav
player.play()

Input Device List

if AudioServer.has_method("get_input_device_list"):
    var devices: Array[String] = AudioServer.call("get_input_device_list")

8. Networking (Multiplayer)

ENet Multiplayer

var peer := ENetMultiplayerPeer.new()
var err: int = peer.create_server(port)
# OR
var err: int = peer.create_client("192.168.1.10", 8443)

multiplayer.multiplayer_peer = peer

Signals

multiplayer.connected_to_server.connect(_on_connected)
multiplayer.connection_failed.connect(_on_failed)
multiplayer.server_disconnected.connect(_on_disconnected)
multiplayer.peer_connected.connect(_on_peer_joined)
multiplayer.peer_disconnected.connect(_on_peer_left)
multiplayer.get_peers()  # Array[int]
multiplayer.get_unique_id()  # int

UDP (VoIP)

var pkt_peer := PacketPeerUDP.new()
pkt_peer.connect_to_host(ip, port)
pkt_peer.put_data(PackedByteArray)
pkt_peer.get_available_packet_count()
pkt_peer.get_packet()  # PackedByteArray
pkt_peer.close()

Local Addresses

# WRONG
IP.get_network_interfaces()  # as static call

# CORRECT (on the singleton instance)
var addresses: Array = IP.get_local_addresses()
var interfaces: Array = IP.get_network_interfaces()

Crypto (AES-256)

var aes := AESContext.new()
var hash_ctx := HashingContext.new()
hash_ctx.start(HashingContext.HASH_SHA256)
hash_ctx.update(key_bytes)
var key: PackedByteArray = hash_ctx.finish()

aes.start(AESContext.MODE_ECB_ENCRYPT, key)
var encrypted: PackedByteArray = aes.update(data)
aes.finish()

9. File I/O

ConfigFile

var config := ConfigFile.new()
config.load("user://settings.cfg")
var val = config.get_value("section", "key", default)
config.set_value("section", "key", value)
config.save("user://settings.cfg")

FileAccess

# Plain
var file := FileAccess.open(path, FileAccess.READ)
var text := file.get_as_text()
file.close()

# Compressed (FastLZ)
var file := FileAccess.open_compressed(path, FileAccess.WRITE, FileAccess.COMPRESSION_FASTLZ)
file.store_string(json_str)
file.close()

# Check existence
FileAccess.file_exists("user://data.json")

CSV

file.store_csv_line(["col1", "col2", "col3"])
var row: PackedStringArray = file.get_csv_line()

JSON

var parsed: Variant = JSON.parse_string(json_text)
var json_str: String = JSON.stringify(data, "\t")

10. Resources & Loading

Loading Scripts

# Static (compile-time)
const MyScript = preload("res://scripts/my_script.gd")

# Dynamic (runtime)
var script: GDScript = load("res://scripts/dynamic.gd")
var instance: Node = script.new()

Loading Fonts

var custom_font: Font = load("res://font/text_with_emojis.tres")

Class Registration

class_name MyEngine
extends Node

Note: If two scripts reference each other (circular dependency), relax the type hint to the base class to break the loop:

# Instead of:
var tab_bar: MainTabBar
# Use:
var tab_bar: TabBar

11. Performance

FPS

Engine.get_frames_per_second()
Engine.max_fps = 60

Draw Calls

Performance.get_monitor(Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME)

Low Processor Usage

OS.low_processor_usage_mode = true

Object Pooling

# Pre-allocate nodes, toggle visibility instead of create/free
var pool: Array[Label] = []
for i in POOL_SIZE:
    var node := Label.new()
    node.visible = false
    add_child(node)
    pool.append(node)

Avoid Per-Frame Allocations

# Reuse cache arrays
var _cache: Array[Node] = []

func update():
    _cache.clear()
    for item in items:
        if item.valid:
            _cache.append(item)
    # Swap with working array
    var temp = items
    items = _cache
    _cache = temp

Debounce Timers

var _save_timer := Timer.new()
_save_timer.wait_time = 1.0
_save_timer.one_shot = true
add_child(_save_timer)

# In event handler:
_save_timer.stop()
_save_timer.start()

12. Style Conventions

File Naming

Pattern Purpose
*_engine.gd Logic / data / network layer
*_ui.gd Presentation / node construction
*_helper.gd Static utility functions

Engine Pattern

extends Node
class_name MyEngine

signal data_changed(value: Variant)

const CONFIG_PATH := "user://my_settings.cfg"

var _state: Dictionary = {}

func _ready() -> void:
    _load()

func _exit_tree() -> void:
    _save()

func _process(delta: float) -> void:
    # Per-frame logic

# Public API
func get_value(key: String) -> Variant: ...
func set_value(key: String, val: Variant) -> void: ...

# Private helpers
func _load() -> void: ...
func _save() -> void: ...

UI Pattern

extends RefCounted
class_name MyUI

static func setup_ui(page_container: Node, engine: Node) -> void:
    # Guard against double-setup
    if page_container.has_node("MyWrapper"):
        return

    # Locate content area
    var layout_vbox = page_container.get_child(0)
    var main_content = layout_vbox.get_child(0)

    # Clear previous
    for child in main_content.get_children():
        child.queue_free()

    # Build UI...

Print Statements

print("[EngineName] Message: ", detail)
push_warning("[EngineName] Non-fatal issue")
push_error("[EngineName] Fatal issue: ", err)

13. Common Pitfalls & Corrections

# Wrong Correct Reason
1 var items := [] var items: Array[Label] = [] Typed arrays required
2 DisplayServer.vsync = true DisplayServer.window_set_vsync_mode(...) API changed in 4.x
3 Input.is_touchscreen_available() DisplayServer.is_touchscreen_available() Moved to DisplayServer
4 Color.rand() Color(randf(), randf(), randf()) No static rand()
5 yield(...) await ... yield removed in Godot 4
6 container.clear() for c in container.get_children(): c.queue_free() No clear() on Container
7 style.border_width_all = 2 Per-side border_width_left/right/top/bottom No _all shortcut
8 style.corner_radius_all = 16 Per-corner corner_radius_top_left/... No _all shortcut
9 StyleBoxFlat.new(style) style.duplicate() No copy constructor
10 fit_content_width = true wrap_mode = TextEdit.LINE_WRAPPING_BOUNDARY Property renamed
11 Slider.new() VSlider.new() / HSlider.new() Slider is abstract
12 tab_bar.tabs_closeable = true tab_bar.tab_close_display_policy = ... Property renamed
13 get_window().size_scale = 2.0 get_window().content_scale_factor = 2.0 Property renamed
14 DisplayServer.window_set_flag(RESIZE, true) DisplayServer.window_set_flag(RESIZE_DISABLED, false) Flag semantics inverted
15 dialog.get_cancel() dialog.get_cancel_button() Method renamed in 4.6+
16 Node.get_process_delta_time() get_process_delta_time() Instance method, not static
17 vec.ceiled() Vector2i(vec.ceil()) Wrong method name
18 IP.get_network_interfaces() (static) IP.get_network_interfaces() (on singleton) Must be instance call
19 NOTIFICATION_WM_QUIT_REQUEST NOTIFICATION_WM_CLOSE_REQUEST Renamed in Godot 4
20 timer.pause_mode = PAUSE_MODE_PROCESS timer.process_mode = PROCESS_MODE_ALWAYS Renamed in Godot 4
21 Engine.has_feature("web_view") OS.has_feature("web") Correct singleton + feature
22 var child := control.create_item(root) var child: TreeItem = control.create_item(root) Type inference fails
23 Engine.get_process_time() Does not exist Use Time.get_ticks_msec()
24 NOTIFICATION_FOCUS_OUT NOTIFICATION_APPLICATION_FOCUS_OUT Correct constant name

Quick Reference: Godot 4.7 Class Hierarchy (UI)

CanvasItem
├── Control
│   ├── Container
│   │   ├── VBoxContainer
│   │   ├── HBoxContainer
│   │   ├── GridContainer
│   │   ├── MarginContainer
│   │   ├── PanelContainer
│   │   ├── ScrollContainer
│   │   ├── TabContainer
│   │   ├── HSplitContainer / VSplitContainer
│   │   └── CenterContainer
│   ├── Label
│   ├── Button
│   ├── CheckBox
│   ├── OptionButton
│   ├── LineEdit
│   ├── TextEdit
│   ├── RichTextLabel
│   ├── HSlider / VSlider
│   ├── ProgressBar
│   ├── SpinBox
│   ├── ColorPickerButton
│   ├── Tree
│   ├── TabBar
│   ├── PopupMenu
│   └── ConfirmationDialog (extends Window)
├── Node2D
├── AudioStreamPlayer
└── Node (base)

References


Last updated for Godot 4.7. Cross-reference with AIFIX.md for project-specific corrections.

z1-Features.md Неформатований

EnvoyOS — Feature Roadmap

EnvoyOS is a multi-PC, multi-monitor productivity dashboard built in Godot 4.6. It combines clipboard sync, AI assistance, timers, inventory, web tab sessions, media controls, theme building, and a modular tab/engine architecture into a single desktop app.

The roadmap below prioritizes:

  1. Stabilizing the existing core product.
  2. Completing the highest-value multi-PC productivity features.
  3. Expanding AI and developer workflows.
  4. Building a polished, cross-platform desktop suite.

1. Feature Inventory

1.1 Implemented / Stable

Feature Module(s) Notes
Cross-PC clipboard sync clipboard_engine.gd ENet + AES-256, client/server, auto-reconnect
AI chat ai_engine.gd, ai_ui.gd Ollama HTTP streaming, multi-turn context
Markdown editor editor_engine.gd, editor_ui.gd Autosave, debounce, theme-aware typography
Timer panel time_engine.gd, time_ui.gd Up to 12 timers, background tick, config persistence
Inventory tracking inventory_engine.gd, inventory_ui.gd Slot-based UI, expiration tracking
Tab management tab_engine.gd, tab_ui.gd Custom tab bar, session persistence
Theme builder ui_engine.gd, ui_ui.gd bg/font/accent/shade/transparency, light/dark adaptivity
Video / display settings video_engine.gd, video_ui.gd FPS, DPI, window mode, position, size
OS grid layout grid_engine.gd, grid_ui.gd Configurable rows × columns dashboard
User AFK detection user_active_engine.gd Cross-platform idle time
System tray systemtray.gd Minimize-to-tray, app-level tray integration
Ship game ship_engine.gd, ship_ui.gd 2D physics mini-game, object pooling
Web tab session viewer web_engine.gd, web_ui.gd Loads Tab Session Manager JSON, tree view
VoIP scaffolding voip_engine.gd, voip_ui.gd UDP, VAD, jitter buffer; still in progress
Audio settings audio_engine.gd, audio_ui.gd Master volume, mute, mic level

1.2 Partial / In Progress

Feature Module(s) Missing
System monitor system_engine.gd, system_ui.gd Empty; needs CPU/RAM/disk/GPU stats and dashboard UI
AI code assistant ai_code_engine.gd, ai_code_ui.gd Empty; needs code-gen, review, explain, diff view
Music / media player music_engine.gd, music_ui.gd extends Node only; needs playback queue, seeking, shuffle
VoIP voip_engine.gd, voip_ui.gd Needs input validation, UI polish, reliability tests
OS grid layout grid_engine.gd, grid_ui.gd Broken references to clipboard engine state

1.3 Stubs / Missing

Feature Notes
Command palette No Ctrl+K action search
Global hotkeys No OS-level hotkey registration
Monitor layout memory No per-monitor window position/size persistence
Floating overlays No always-on-top widgets
P2P file transfer No chunked ENet file streaming UI
Shared workspace / Kanban No cross-PC synced task board
Notification mirroring No cross-PC toasts
Clipboard history ring buffer No searchable past clipboard picker
Snippet library No saved snippets with sync
Screen recording / capture No per-monitor GPU capture
Voice commands No local voice-to-action pipeline
In-app updater No auto-update mechanism
Unit tests / CI No GUT test suite or automated checks

2. Roadmap

Phase 1 — Stabilize & Finish Core Gaps (Weeks 1–3)

Goal: make every existing tab useful and remove obvious technical debt.

# Feature / Task Description
1.1 System monitor Implement system_engine.gd (CPU %, RAM, disk, GPU, network) and system_ui.gd dashboard with live gauges.
1.2 Music player Build music_engine.gd playback queue, seeking, shuffle/repeat; wire music_ui.gd.
1.3 AI code tab Implement ai_code_engine.gd for explain/refactor/generate and ai_code_ui.gd with side-by-side editor + diff view.
1.4 Fix grid engine refs Replace is_connected_to_network / is_reconnecting with valid clipboard engine properties.
1.5 Input validation Validate VoIP port, timer/inventory hh:mm:ss fields, and all numeric inputs.
1.6 Merge duplicate engines Consolidate tab_engine.gd and top_engine.gd into one base class.
1.7 Testing foundation Add GUT unit tests for theme serializer, tab engine, timer, inventory, clipboard crypto.
1.8 CI pipeline GitHub Actions: godot --headless --check-only + GUT on push.
1.9 Bug bash Systematic pass over known technical debt list.

Exit criteria: No empty tabs, no broken references, CI green, basic test coverage.

Phase 2 — Multi-PC Power Features (Weeks 4–7)

Goal: make EnvoyOS the primary productivity bridge between the user’s PCs.

# Feature Description
2.1 Clipboard history ring buffer Last 100 text/image items with timestamp, source PC, app name. Searchable picker.
2.2 Snippet library Save frequently used snippets/templates, sync to all peers, one-click paste.
2.3 Cross-PC clipboard search Type keyword → RPC search across all peers’ history.
2.4 P2P file transfer Drag-and-drop file onto network tab → AES-256 → chunked ENet stream → progress bar.
2.5 Shared workspace folder Synced directory with chunked transfer; edit on one PC, open on another.
2.6 Shared Kanban board To-Do / In-Progress / Done, RPC-synced in real time; cards with title, tags, due date, assigned PC.
2.7 Notification mirroring Broadcast system/app notifications to all peers; timer expiry → alert all PCs.
2.8 Command palette Ctrl+K fuzzy-search actions: tabs, theme, timers, connections, mute, etc.
2.9 Global OS-level hotkeys Clipboard history, screenshot, quick paste, show/hide app.
2.10 Offline queue Queue clipboard/file/task changes while disconnected; auto-sync on reconnect.

Exit criteria: User can copy/paste, transfer files, and track tasks across PCs without leaving EnvoyOS.

Phase 3 — Multi-Monitor & AI (Weeks 8–11)

Goal: exploit multi-monitor setups and deepen AI assistance.

# Feature Description
3.1 Monitor layout memory Detect monitors, save per-monitor window positions/sizes, restore on launch.
3.2 Floating overlays Always-on-top widgets: timer countdown, clipboard dock, AFK glow, assigned to monitors.
3.3 Window tiling / snapping Ctrl+1..4 quadrant, Ctrl+Shift+Left/Right half, named layouts.
3.4 Per-monitor contrast Different shade/brightness per monitor; auto time-of-day adjustment.
3.5 AI code review Explain selected code, refactor with diff, generate from prompt, review PR diff.
3.6 AI meeting notes Stream mic audio → local Whisper/Ollama → bullet summary → sync to peers.
3.7 Cross-PC input mirroring Type on PC-A → keystrokes stream to PC-B; relative mouse deltas; per-peer toggle.
3.8 AI suggestion engine Context-aware “Smart Suggestions” on clipboard/tab/editor.
3.9 Screenshot + AI annotate Capture region → send to local model → written description.

Exit criteria: Multi-monitor setup feels native; AI handles coding and documentation tasks with low friction.

Phase 4 — Polish, Packaging & Release (Weeks 12–14)

Goal: ship a polished, discoverable, cross-platform product.

# Feature Description
4.1 Auto-start with OS Windows registry, Linux .desktop, macOS LaunchAgent.
4.2 System tray menu Show, Mute, Disconnect, Open Timer, Open Kanban, Exit.
4.3 Backup / restore Export/import all user:// settings as .zip.
4.4 Accessibility pass High-contrast mode, font scaling, screen-reader labels.
4.5 Session replay Record short UI interaction replay for bug reports.
4.6 User documentation Full user manual, keyboard shortcut reference, per-OS setup guide.
4.7 Export / packaging Release builds for Windows / Linux / macOS; in-app updater (optional).
4.8 Localization scaffold String externalization for future i18n.
4.9 Error reporting Opt-in crash/telemetry with minimal PII.

Exit criteria: Stable release builds, onboarding experience, accessible UI.

Phase 5 — Differentiators & Platform Expansion (Ongoing)

Goal: make EnvoyOS a complete second OS layer for power users.

# Feature Description
5.1 Screen recording per monitor GPU capture, “record this monitor” toggle, export to file.
5.2 Voice commands “Hey, paste the last email” → VAD → snippet match → paste.
5.3 Pomodoro focus mode 25/5 preset; auto-pauses AI streaming and sync during focus.
5.4 Dark-light auto-switch Theme tied to system clock or ambient light.
5.5 Peer presence bar Avatar strip showing online PCs via multiplayer.get_peers().
5.6 Shared timer countdown Timer on PC-A visible live on PC-B; sync end_timestamp.
5.7 Calendar view Timers/inventory deadlines on mini monthly calendar.
5.8 CSV export Timer/inventory state to CSV.
5.9 Low-stock alerts Inventory item below threshold → red flag on all PCs.
5.10 Browser extension Sync tabs/bookmarks/clipboard from browser to EnvoyOS.
5.11 Mobile companion System-tray / applet / browser-extension views; remote status.
5.12 Plugin / extension system Load custom GDScript panels into the tab grid.
5.13 App manifest / RBAC JSON manifest for per-panel permissions, resource limits, data classification.
5.14 Power management UI Per-tab/applet status, bandwidth throttle, CPU/GPU allocation.

3. Non-Functional Requirements

Area Requirement
Performance Inactive engines must not consume CPU; active tabs < 10 ms frame budget on mid-range hardware.
Reliability Network sync must survive peer disconnects and auto-reconnect without data loss.
Security All network payloads encrypted (AES-256); no secrets in logs; configurable trust model.
Accessibility WCAG-conscious contrast, full keyboard navigation, font scaling, screen-reader labels.
Portability Windows, Linux, macOS desktop; optional WebAssembly build for applet view.
Testability Unit tests for engines, integration tests for network sync, smoke tests for UI tabs.
Observability Structured logs, error reporting, session replay for debugging.
Packaging Signed release binaries per platform; in-app updater (optional).

4. Success Metrics

Metric Target
Core stability Zero empty tabs; no broken references; CI green
Cross-PC utility User can copy, transfer, and track work across ≥ 2 PCs without external tools
AI value ≥ 3 AI-powered workflows (chat, code review, meeting notes) usable daily
Multi-monitor ≥ 3 per-monitor layout features working out of the box
Release readiness Signed builds for 3 platforms; documented onboarding; < 5 min setup time
Extensibility Third-party panels can be loaded via manifest / plugin API

5. Immediate Next Steps

  1. Complete Phase 1 items (system monitor, music player, AI code tab, grid refs, tests, CI).
  2. Pick one Phase 2 multi-PC feature to prototype (clipboard history or P2P file transfer).
  3. Define the JSON manifest schema for panels / RBAC (informs Phase 5 but can be designed now).
  4. Establish a release cadence and changelog process.