4.4 KiB
4.4 KiB
Project-Specific Agent Guidelines: jai-sing-box
This project implements a lightweight Windows system tray controller for sing-box (a universal proxy platform) written in the Jai programming language.
Key Project Notes:
- The built executable is
sing-box-tray.exe. - sing-box core is downloaded on-demand and installed to
%LOCALAPPDATA%\sing-box-tray\. - CRITICAL: Never terminate sing-box or sing-box-tray processes (see section 5).
- Uses only native Win32 APIs (WinINet, no libcurl dependency).
- Build via
build.jaimetaprogram (sets windows subsystem, custom entry).
Jai Developer Agent Guidelines
These guidelines apply to any agent working with the Jai programming language.
1. Syntax & Core Idioms
- Declarations: Use
:=for type inference,: Type =for explicit types, and::for compile-time constants (functions, structs, constants). - Procedures: Declare procedures as
name :: (params) -> return_type { ... }. Use#expandfor macros that compile into the caller's scope and access caller variables using backticks (e.g.,`x). - Memory Management: Jai does not have RAII or garbage collection. Memory is managed manually, typically using
deferto clean up resources right after allocation:data := alloc(size); defer free(data); - Context Allocators: Jai uses an implicit
contextparameter containing the current allocator (context.allocator).- Use
context.allocator = temp_allocator;for temporary/arena allocations that don't need manual freeing (cleared at the end of the frame/loop iteration viareset_temporary_storage()). - When writing reusable libraries or procedures, accept an optional allocator parameter or use
context.allocatorby default.
- Use
2. Standard Libraries & Imports
- Anonymous Imports: Use
#import "Basic";anonymously to bring standard utilities likeprint,alloc,free,tprintdirectly into the scope. - Named Imports: Use named imports
String :: #import "String";to namespace helper libraries, which keeps the scope clean. Note that operator overloads do not automatically propagate through namespaces. - No Package Manager: Since Jai does not have a package manager, vendor any external libraries directly into the project's
modules/folder or implement them yourself.
3. Platform Bindings & Win32 API
- Windows Bindings: The standard
Windowsmodule (#import "Windows";) provides native bindings to Win32 APIs. - Wide Strings: Many Windows APIs require wide UTF-16 strings (e.g.,
LPCWSTR). Use helper utilities to convert Jai UTF-8 strings (string) to UTF-16 wide strings when calling Windows APIs (e.g. usingutf8_to_wideor similar functions in the runtime or writing a custom converter usingMultiByteToWideChar). - Callback Conventions: When defining callbacks for Win32 API (such as Window Procedures or Thread Procedures), you must mark the procedure with
#c_callcalling convention and usually#no_contextto prevent context mismatches when called from OS threads:window_proc :: (hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #c_call { // If context is needed inside the callback, re-push it: ctx: Context; // or get from global/user data push_context ctx { // Jai code here } }
4. Code Quality & Compilation
- No Compiler Warnings: Always ensure the code compiles without warnings or errors.
- Compile-Time Execution: Utilize
#runblocks to execute code at compile-time for code generation, building lookups, or validating configurations. - Linting & Safety: Avoid using uninitialized variables unless performance-critical (explicitly mark as
---if needed).
5. Process Management Warning (VPN Connectivity)
- CRITICAL WARNING: Do NOT kill, terminate, or stop the
sing-boxorsing-box-trayprocesses during runtime unless explicitly instructed by the user. The agent's own network connection and container/sandbox internet access might be routed through this active VPN. Killing it will sever the agent's connection. - Rebuilding & Locked Executables: Always try to compile the project first. Do not preemptively ask the user to close the executable unless compilation actually fails with a file lock error (e.g.
LNK1104or similar) and you have verified that the locked file is indeed the output binary in the build directory. Only ask the user to close/free the executable in that specific failure case.